001/* 002 * IzPack - Copyright 2001-2005 Julien Ponge, All Rights Reserved. 003 * 004 * http://www.izforge.com/izpack/ 005 * http://developer.berlios.de/projects/izpack/ 006 * 007 * Copyright 2003 Jonathan Halliday 008 * 009 * Licensed under the Apache License, Version 2.0 (the "License"); 010 * you may not use this file except in compliance with the License. 011 * You may obtain a copy of the License at 012 * 013 * http://www.apache.org/licenses/LICENSE-2.0 014 * 015 * Unless required by applicable law or agreed to in writing, software 016 * distributed under the License is distributed on an "AS IS" BASIS, 017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 018 * See the License for the specific language governing permissions and 019 * limitations under the License. 020 */ 021 022package com.izforge.izpack.installer; 023 024import java.io.File; 025import java.io.InputStream; 026import java.io.ObjectInputStream; 027import java.util.ArrayList; 028import java.util.Enumeration; 029import java.util.Iterator; 030import java.util.List; 031import java.util.Locale; 032import java.util.Properties; 033 034import com.izforge.izpack.CustomData; 035import com.izforge.izpack.Info; 036import com.izforge.izpack.Pack; 037import com.izforge.izpack.util.Debug; 038import com.izforge.izpack.util.IoHelper; 039import com.izforge.izpack.util.OsConstraint; 040import com.izforge.izpack.util.OsVersion; 041import com.izforge.izpack.util.VariableSubstitutor; 042 043/** 044 * Common utility functions for the GUI and text installers. (Do not import swing/awt classes to 045 * this class.) 046 * 047 * @author Jonathan Halliday 048 * @author Julien Ponge 049 */ 050public class InstallerBase 051{ 052 053 /** 054 * The base name of the XML file that specifies the custom langpack. Searched is for the file 055 * with the name expanded by _ISO3. 056 */ 057 protected static final String LANG_FILE_NAME = "CustomLangpack.xml"; 058 059 /** 060 * Loads the installation data. Also sets environment variables to <code>installdata</code>. 061 * All system properties are available as $SYSTEM_<variable> where <variable> is the actual 062 * name _BUT_ with all separators replaced by '_'. Properties with null values are never stored. 063 * Example: $SYSTEM_java_version or $SYSTEM_os_name 064 * 065 * @param installdata Where to store the installation data. 066 * 067 * @exception Exception Description of the Exception 068 */ 069 public void loadInstallData(AutomatedInstallData installdata) throws Exception 070 { 071 // Usefull variables 072 InputStream in; 073 ObjectInputStream objIn; 074 int size; 075 int i; 076 077 // We load the variables 078 Properties variables = null; 079 in = InstallerBase.class.getResourceAsStream("/vars"); 080 if (null != in) 081 { 082 objIn = new ObjectInputStream(in); 083 variables = (Properties) objIn.readObject(); 084 objIn.close(); 085 } 086 087 // We load the Info data 088 in = InstallerBase.class.getResourceAsStream("/info"); 089 objIn = new ObjectInputStream(in); 090 Info inf = (Info) objIn.readObject(); 091 objIn.close(); 092 093 // We put the Info data as variables 094 installdata.setVariable(ScriptParser.APP_NAME, inf.getAppName()); 095 installdata.setVariable(ScriptParser.APP_URL, inf.getAppURL()); 096 installdata.setVariable(ScriptParser.APP_VER, inf.getAppVersion()); 097 098 // We read the panels order data 099 in = InstallerBase.class.getResourceAsStream("/panelsOrder"); 100 objIn = new ObjectInputStream(in); 101 List panelsOrder = (List) objIn.readObject(); 102 objIn.close(); 103 104 // We read the packs data 105 in = InstallerBase.class.getResourceAsStream("/packs.info"); 106 objIn = new ObjectInputStream(in); 107 size = objIn.readInt(); 108 ArrayList availablePacks = new ArrayList(); 109 ArrayList allPacks = new ArrayList(); 110 for (i = 0; i < size; i++) 111 { 112 Pack pk = (Pack) objIn.readObject(); 113 allPacks.add(pk); 114 if (OsConstraint.oneMatchesCurrentSystem(pk.osConstraints)) availablePacks.add(pk); 115 } 116 objIn.close(); 117 118 // We determine the operating system and the initial installation path 119 String dir; 120 String installPath; 121 if (OsVersion.IS_WINDOWS) 122 { 123 dir = buildWindowsDefaultPath(); 124 } 125 else if (OsVersion.IS_OSX) 126 { 127 dir = "/Applications"; 128 } 129 else 130 { 131 if (new File("/usr/local/").canWrite()) 132 { 133 dir = "/usr/local"; 134 } 135 else 136 { 137 dir = System.getProperty("user.home"); 138 } 139 } 140 installdata.setVariable("APPLICATIONS_DEFAULT_ROOT", dir); 141 dir = dir + File.separator; 142 installdata.setVariable(ScriptParser.JAVA_HOME, System.getProperty("java.home")); 143 installdata.setVariable(ScriptParser.USER_HOME, System.getProperty("user.home")); 144 installdata.setVariable(ScriptParser.USER_NAME, System.getProperty("user.name")); 145 installdata.setVariable(ScriptParser.FILE_SEPARATOR, File.separator); 146 147 Enumeration e = System.getProperties().keys(); 148 while (e.hasMoreElements()) 149 { 150 String varName = (String) e.nextElement(); 151 String varValue = System.getProperty(varName); 152 if (varValue != null) 153 { 154 varName = varName.replace('.', '_'); 155 installdata.setVariable("SYSTEM_" + varName, varValue); 156 } 157 } 158 159 if (null != variables) 160 { 161 Enumeration enumeration = variables.keys(); 162 String varName; 163 String varValue; 164 while (enumeration.hasMoreElements()) 165 { 166 varName = (String) enumeration.nextElement(); 167 varValue = variables.getProperty(varName); 168 installdata.setVariable(varName, varValue); 169 } 170 } 171 172 installdata.info = inf; 173 installdata.panelsOrder = panelsOrder; 174 installdata.availablePacks = availablePacks; 175 installdata.allPacks = allPacks; 176 177 // get list of preselected packs 178 Iterator pack_it = availablePacks.iterator(); 179 while (pack_it.hasNext()) 180 { 181 Pack pack = (Pack) pack_it.next(); 182 if (pack.preselected) installdata.selectedPacks.add(pack); 183 } 184 // Set the installation path in a default manner 185 installPath = dir + inf.getAppName(); 186 if (inf.getInstallationSubPath() != null) 187 { // A subpath was defined, use it. 188 installPath = IoHelper.translatePath(dir + inf.getInstallationSubPath(), 189 new VariableSubstitutor(installdata.getVariables())); 190 } 191 installdata.setInstallPath(installPath); 192 // Load custom action data. 193 loadCustomData(installdata); 194 195 } 196 197 /** 198 * Add the contents of a custom langpack (if exist) to the previos loaded comman langpack. If 199 * not exist, trace an info and do nothing more. 200 * 201 * @param idata install data to be used 202 */ 203 protected void addCustomLangpack(AutomatedInstallData idata) 204 { 205 // We try to load and add a custom langpack. 206 try 207 { 208 idata.langpack.add(ResourceManager.getInstance().getInputStream(LANG_FILE_NAME)); 209 } 210 catch (Throwable exception) 211 { 212 Debug.trace("No custom langpack available."); 213 return; 214 } 215 Debug.trace("Custom langpack for " + idata.localeISO3 + " available."); 216 } 217 218 /** 219 * Builds the default path for Windows (i.e Program Files/...). 220 * 221 * @return The Windows default installation path. 222 */ 223 private String buildWindowsDefaultPath() 224 { 225 StringBuffer dpath = new StringBuffer(""); 226 try 227 { 228 // We load the properties 229 Properties props = new Properties(); 230 props 231 .load(InstallerBase.class 232 .getResourceAsStream("/com/izforge/izpack/installer/win32-defaultpaths.properties")); 233 234 // We look for the drive mapping 235 String drive = System.getProperty("user.home"); 236 if (drive.length() > 3) drive = drive.substring(0, 3); 237 238 // Now we have it :-) 239 dpath.append(drive); 240 241 // Ensure that we have a trailing backslash (in case drive was 242 // something 243 // like "C:") 244 if (drive.length() == 2) dpath.append("\\"); 245 246 String language = Locale.getDefault().getLanguage(); 247 String country = Locale.getDefault().getCountry(); 248 String language_country = language + "_" + country; 249 250 // Try the most specific combination first 251 if (null != props.getProperty(language_country)) 252 { 253 dpath.append(props.getProperty(language_country)); 254 } 255 else if (null != props.getProperty(language)) 256 { 257 dpath.append(props.getProperty(language)); 258 } 259 else 260 { 261 dpath.append(props.getProperty(Locale.ENGLISH.getLanguage())); 262 } 263 } 264 catch (Exception err) 265 { 266 dpath = new StringBuffer("C:\\Program Files"); 267 } 268 269 return dpath.toString(); 270 } 271 272 /** 273 * Loads custom data like listener and lib references if exist and fills the installdata. 274 * 275 * @param installdata installdata into which the custom action data should be stored 276 * @throws Exception 277 */ 278 private void loadCustomData(AutomatedInstallData installdata) throws Exception 279 { 280 // Usefull variables 281 InputStream in; 282 ObjectInputStream objIn; 283 int i; 284 // Load listeners if exist. 285 String[] streamNames = AutomatedInstallData.CUSTOM_ACTION_TYPES; 286 List[] out = new List[streamNames.length]; 287 for (i = 0; i < streamNames.length; ++i) 288 out[i] = new ArrayList(); 289 in = InstallerBase.class.getResourceAsStream("/customData"); 290 if (in != null) 291 { 292 objIn = new ObjectInputStream(in); 293 Object listeners = objIn.readObject(); 294 objIn.close(); 295 Iterator keys = ((List) listeners).iterator(); 296 while (keys != null && keys.hasNext()) 297 { 298 CustomData ca = (CustomData) keys.next(); 299 300 if (ca.osConstraints != null 301 && !OsConstraint.oneMatchesCurrentSystem(ca.osConstraints)) 302 { // OS constraint defined, but not matched; therefore ignore 303 // it. 304 continue; 305 } 306 switch (ca.type) 307 { 308 case CustomData.INSTALLER_LISTENER: 309 Class clazz = Class.forName(ca.listenerName); 310 if (clazz == null) 311 throw new InstallerException("Custom action " + ca.listenerName 312 + " not bound!"); 313 out[ca.type].add(clazz.newInstance()); 314 break; 315 case CustomData.UNINSTALLER_LISTENER: 316 case CustomData.UNINSTALLER_JAR: 317 out[ca.type].add(ca); 318 break; 319 case CustomData.UNINSTALLER_LIB: 320 out[ca.type].add(ca.contents); 321 break; 322 } 323 324 } 325 // Add the current custem action data to the installdata hash map. 326 for (i = 0; i < streamNames.length; ++i) 327 installdata.customData.put(streamNames[i], out[i]); 328 } 329 // uninstallerLib list if exist 330 331 } 332}