001: /*
002: * IzPack - Copyright 2001-2008 Julien Ponge, All Rights Reserved.
003: *
004: * http://izpack.org/
005: * http://izpack.codehaus.org/
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:
022: package com.izforge.izpack.installer;
023:
024: import java.io.File;
025: import java.io.InputStream;
026: import java.io.ObjectInputStream;
027: import java.util.ArrayList;
028: import java.util.Enumeration;
029: import java.util.Iterator;
030: import java.util.List;
031: import java.util.Locale;
032: import java.util.Properties;
033: import java.net.InetAddress;
034:
035: import com.izforge.izpack.CustomData;
036: import com.izforge.izpack.Info;
037: import com.izforge.izpack.Pack;
038: import com.izforge.izpack.util.Debug;
039: import com.izforge.izpack.util.IoHelper;
040: import com.izforge.izpack.util.OsConstraint;
041: import com.izforge.izpack.util.OsVersion;
042: import com.izforge.izpack.util.VariableSubstitutor;
043:
044: /**
045: * Common utility functions for the GUI and text installers. (Do not import swing/awt classes to
046: * this class.)
047: *
048: * @author Jonathan Halliday
049: * @author Julien Ponge
050: */
051: public class InstallerBase {
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)
070: throws Exception {
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: objIn = new ObjectInputStream(in);
082: variables = (Properties) objIn.readObject();
083: objIn.close();
084: }
085:
086: // We load the Info data
087: in = InstallerBase.class.getResourceAsStream("/info");
088: objIn = new ObjectInputStream(in);
089: Info inf = (Info) objIn.readObject();
090: objIn.close();
091:
092: // We put the Info data as variables
093: installdata
094: .setVariable(ScriptParser.APP_NAME, inf.getAppName());
095: if (inf.getAppURL() != null)
096: installdata.setVariable(ScriptParser.APP_URL, inf
097: .getAppURL());
098: installdata.setVariable(ScriptParser.APP_VER, inf
099: .getAppVersion());
100:
101: // We read the panels order data
102: in = InstallerBase.class.getResourceAsStream("/panelsOrder");
103: objIn = new ObjectInputStream(in);
104: List panelsOrder = (List) objIn.readObject();
105: objIn.close();
106:
107: // We read the packs data
108: in = InstallerBase.class.getResourceAsStream("/packs.info");
109: objIn = new ObjectInputStream(in);
110: size = objIn.readInt();
111: ArrayList availablePacks = new ArrayList();
112: ArrayList<Pack> allPacks = new ArrayList<Pack>();
113: for (i = 0; i < size; i++) {
114: Pack pk = (Pack) objIn.readObject();
115: allPacks.add(pk);
116: if (OsConstraint.oneMatchesCurrentSystem(pk.osConstraints))
117: availablePacks.add(pk);
118: }
119: objIn.close();
120:
121: // We determine the operating system and the initial installation path
122: String dir;
123: String installPath;
124: if (OsVersion.IS_WINDOWS) {
125: dir = buildWindowsDefaultPath();
126: } else if (OsVersion.IS_OSX) {
127: dir = "/Applications";
128: } else {
129: if (new File("/usr/local/").canWrite()) {
130: dir = "/usr/local";
131: } else {
132: dir = System.getProperty("user.home");
133: }
134: }
135:
136: // We determine the hostname and IPAdress
137: String hostname;
138: String IPAddress;
139:
140: try {
141: InetAddress addr = InetAddress.getLocalHost();
142:
143: // Get IP Address
144: IPAddress = addr.getHostAddress();
145:
146: // Get hostname
147: hostname = addr.getHostName();
148: } catch (Exception e) {
149: hostname = "";
150: IPAddress = "";
151: }
152:
153: installdata.setVariable("APPLICATIONS_DEFAULT_ROOT", dir);
154: dir += File.separator;
155: installdata.setVariable(ScriptParser.JAVA_HOME, System
156: .getProperty("java.home"));
157: installdata.setVariable(ScriptParser.CLASS_PATH, System
158: .getProperty("java.class.path"));
159: installdata.setVariable(ScriptParser.USER_HOME, System
160: .getProperty("user.home"));
161: installdata.setVariable(ScriptParser.USER_NAME, System
162: .getProperty("user.name"));
163: installdata.setVariable(ScriptParser.IP_ADDRESS, IPAddress);
164: installdata.setVariable(ScriptParser.HOST_NAME, hostname);
165: installdata.setVariable(ScriptParser.FILE_SEPARATOR,
166: File.separator);
167:
168: Enumeration e = System.getProperties().keys();
169: while (e.hasMoreElements()) {
170: String varName = (String) e.nextElement();
171: String varValue = System.getProperty(varName);
172: if (varValue != null) {
173: varName = varName.replace('.', '_');
174: installdata.setVariable("SYSTEM_" + varName, varValue);
175: }
176: }
177:
178: if (null != variables) {
179: Enumeration enumeration = variables.keys();
180: String varName;
181: String varValue;
182: while (enumeration.hasMoreElements()) {
183: varName = (String) enumeration.nextElement();
184: varValue = variables.getProperty(varName);
185: installdata.setVariable(varName, varValue);
186: }
187: }
188:
189: installdata.info = inf;
190: installdata.panelsOrder = panelsOrder;
191: installdata.availablePacks = availablePacks;
192: installdata.allPacks = allPacks;
193:
194: // get list of preselected packs
195: Iterator pack_it = availablePacks.iterator();
196: while (pack_it.hasNext()) {
197: Pack pack = (Pack) pack_it.next();
198: if (pack.preselected)
199: installdata.selectedPacks.add(pack);
200: }
201: // Set the installation path in a default manner
202: installPath = dir + inf.getAppName();
203: if (inf.getInstallationSubPath() != null) { // A subpath was defined, use it.
204: installPath = IoHelper
205: .translatePath(dir + inf.getInstallationSubPath(),
206: new VariableSubstitutor(installdata
207: .getVariables()));
208: }
209: installdata.setInstallPath(installPath);
210: // Load custom action data.
211: loadCustomData(installdata);
212:
213: }
214:
215: /**
216: * Add the contents of a custom langpack (if exist) to the previos loaded comman langpack. If
217: * not exist, trace an info and do nothing more.
218: *
219: * @param idata install data to be used
220: */
221: protected void addCustomLangpack(AutomatedInstallData idata) {
222: // We try to load and add a custom langpack.
223: try {
224: idata.langpack.add(ResourceManager.getInstance()
225: .getInputStream(LANG_FILE_NAME));
226: } catch (Throwable exception) {
227: Debug.trace("No custom langpack available.");
228: return;
229: }
230: Debug.trace("Custom langpack for " + idata.localeISO3
231: + " available.");
232: }
233:
234: /**
235: * Get the default path for Windows (i.e Program Files/...).
236: * Windows has a Setting for this in the environment and in the registry.
237: * Just try to use the setting in the environment. If it fails for whatever reason, we take the former solution (buildWindowsDefaultPathFromProps).
238: * @return The Windows default installation path for applications.
239: */
240: private String buildWindowsDefaultPath() {
241: try {
242: //get value from environment...
243: String prgFilesPath = IoHelper.getenv("ProgramFiles");
244: if (prgFilesPath != null && prgFilesPath.length() > 0) {
245: return prgFilesPath;
246: } else {
247: return buildWindowsDefaultPathFromProps();
248: }
249: } catch (Exception x) {
250: x.printStackTrace();
251: return buildWindowsDefaultPathFromProps();
252: }
253: }
254:
255: /**
256: * just plain wrong in case the programfiles are not stored where the developer expects them.
257: * E.g. in custom installations of large companies or if used internationalized version of windows with a language pack.
258: * @return the program files path
259: */
260: private String buildWindowsDefaultPathFromProps() {
261: StringBuffer dpath = new StringBuffer("");
262: try {
263: // We load the properties
264: Properties props = new Properties();
265: props
266: .load(InstallerBase.class
267: .getResourceAsStream("/com/izforge/izpack/installer/win32-defaultpaths.properties"));
268:
269: // We look for the drive mapping
270: String drive = System.getProperty("user.home");
271: if (drive.length() > 3)
272: drive = drive.substring(0, 3);
273:
274: // Now we have it :-)
275: dpath.append(drive);
276:
277: // Ensure that we have a trailing backslash (in case drive was
278: // something
279: // like "C:")
280: if (drive.length() == 2)
281: dpath.append("\\");
282:
283: String language = Locale.getDefault().getLanguage();
284: String country = Locale.getDefault().getCountry();
285: String language_country = language + "_" + country;
286:
287: // Try the most specific combination first
288: if (null != props.getProperty(language_country)) {
289: dpath.append(props.getProperty(language_country));
290: } else if (null != props.getProperty(language)) {
291: dpath.append(props.getProperty(language));
292: } else {
293: dpath.append(props.getProperty(Locale.ENGLISH
294: .getLanguage()));
295: }
296: } catch (Exception err) {
297: dpath = new StringBuffer("C:\\Program Files");
298: }
299:
300: return dpath.toString();
301: }
302:
303: /**
304: * Loads custom data like listener and lib references if exist and fills the installdata.
305: *
306: * @param installdata installdata into which the custom action data should be stored
307: * @throws Exception
308: */
309: private void loadCustomData(AutomatedInstallData installdata)
310: throws Exception {
311: // Usefull variables
312: InputStream in;
313: ObjectInputStream objIn;
314: int i;
315: // Load listeners if exist.
316: String[] streamNames = AutomatedInstallData.CUSTOM_ACTION_TYPES;
317: List[] out = new List[streamNames.length];
318: for (i = 0; i < streamNames.length; ++i)
319: out[i] = new ArrayList();
320: in = InstallerBase.class.getResourceAsStream("/customData");
321: if (in != null) {
322: objIn = new ObjectInputStream(in);
323: Object listeners = objIn.readObject();
324: objIn.close();
325: Iterator keys = ((List) listeners).iterator();
326: while (keys != null && keys.hasNext()) {
327: CustomData ca = (CustomData) keys.next();
328:
329: if (ca.osConstraints != null
330: && !OsConstraint
331: .oneMatchesCurrentSystem(ca.osConstraints)) { // OS constraint defined, but not matched; therefore ignore
332: // it.
333: continue;
334: }
335: switch (ca.type) {
336: case CustomData.INSTALLER_LISTENER:
337: Class clazz = Class.forName(ca.listenerName);
338: if (clazz == null)
339: throw new InstallerException("Custom action "
340: + ca.listenerName + " not bound!");
341: out[ca.type].add(clazz.newInstance());
342: break;
343: case CustomData.UNINSTALLER_LISTENER:
344: case CustomData.UNINSTALLER_JAR:
345: out[ca.type].add(ca);
346: break;
347: case CustomData.UNINSTALLER_LIB:
348: out[ca.type].add(ca.contents);
349: break;
350: }
351:
352: }
353: // Add the current custem action data to the installdata hash map.
354: for (i = 0; i < streamNames.length; ++i)
355: installdata.customData.put(streamNames[i], out[i]);
356: }
357: // uninstallerLib list if exist
358:
359: }
360: }
|