001: /*
002: * $Id:$
003: * IzPack - Copyright 2001-2008 Julien Ponge, All Rights Reserved.
004: *
005: * http://izpack.org/
006: * http://izpack.codehaus.org/
007: *
008: * Copyright 2007 Klaus Bartz
009: *
010: * Licensed under the Apache License, Version 2.0 (the "License");
011: * you may not use this file except in compliance with the License.
012: * You may obtain a copy of the License at
013: *
014: * http://www.apache.org/licenses/LICENSE-2.0
015: *
016: * Unless required by applicable law or agreed to in writing, software
017: * distributed under the License is distributed on an "AS IS" BASIS,
018: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
019: * See the License for the specific language governing permissions and
020: * limitations under the License.
021: */
022:
023: package com.izforge.izpack.compiler;
024:
025: import java.io.File;
026: import java.io.IOException;
027: import java.io.FilterOutputStream;
028: import java.net.URL;
029: import java.util.ArrayList;
030: import java.util.HashMap;
031: import java.util.HashSet;
032: import java.util.List;
033: import java.util.Map;
034: import java.util.Properties;
035: import java.util.Set;
036:
037: import com.izforge.izpack.CustomData;
038: import com.izforge.izpack.GUIPrefs;
039: import com.izforge.izpack.Info;
040: import com.izforge.izpack.Panel;
041: import com.izforge.izpack.rules.Condition;
042: import com.izforge.izpack.compressor.PackCompressor;
043: import com.izforge.izpack.compressor.PackCompressorFactory;
044:
045: /**
046: * The packager base class. The packager interface <code>IPackager</code> is used by the compiler to put files into an installer, and
047: * create the actual installer files. The packager implementation depends on different requirements (e.g. normal packager versus multi volume packager).
048: * This class implements the common used method which can also be overload as needed.
049: *
050: * @author Klaus Bartz
051: *
052: */
053: public abstract class PackagerBase implements IPackager {
054:
055: /** Path to the skeleton installer. */
056: public static final String SKELETON_SUBPATH = "lib/installer.jar";
057:
058: /** Base file name of all jar files. This has no ".jar" suffix. */
059: protected File baseFile = null;
060:
061: /** Basic installer info. */
062: protected Info info = null;
063:
064: /** Gui preferences of instatller. */
065: protected GUIPrefs guiPrefs = null;
066:
067: /** The variables used in the project */
068: protected Properties variables = new Properties();
069:
070: /** The ordered panels informations. */
071: protected List<Panel> panelList = new ArrayList<Panel>();
072:
073: /** The ordered packs informations (as PackInfo objects). */
074: protected List<PackInfo> packsList = new ArrayList<PackInfo>();
075:
076: /** The ordered langpack locale names. */
077: protected List<String> langpackNameList = new ArrayList<String>();
078:
079: /** The ordered custom actions informations. */
080: protected List<CustomData> customDataList = new ArrayList<CustomData>();
081:
082: /** The langpack URLs keyed by locale name (e.g. de_CH). */
083: protected Map<String, URL> installerResourceURLMap = new HashMap<String, URL>();
084:
085: /** the conditions */
086: protected Map<String, Condition> rules = new HashMap<String, Condition>();
087:
088: /** dynamic variables */
089: protected Map<String, DynamicVariable> dynamicvariables = new HashMap<String, DynamicVariable>();
090:
091: /** Jar file URLs who's contents will be copied into the installer. */
092: protected Set<Object[]> includedJarURLs = new HashSet<Object[]>();
093:
094: /** Each pack is created in a separte jar if webDirURL is non-null. */
095: protected boolean packJarsSeparate = false;
096:
097: /** The listeners. */
098: protected PackagerListener listener;
099:
100: /** The compression format to be used for pack compression */
101: protected PackCompressor compressor;
102:
103: /** Files which are always written into the container file */
104: protected HashMap<FilterOutputStream, HashSet<String>> alreadyWrittenFiles = new HashMap<FilterOutputStream, HashSet<String>>();
105:
106: /**
107: * Dispatches a message to the listeners.
108: *
109: * @param job The job description.
110: */
111: protected void sendMsg(String job) {
112: sendMsg(job, PackagerListener.MSG_INFO);
113: }
114:
115: /**
116: * Dispatches a message to the listeners at specified priority.
117: *
118: * @param job The job description.
119: * @param priority The message priority.
120: */
121: protected void sendMsg(String job, int priority) {
122: if (listener != null)
123: listener.packagerMsg(job, priority);
124: }
125:
126: /** Dispatches a start event to the listeners. */
127: protected void sendStart() {
128: if (listener != null)
129: listener.packagerStart();
130: }
131:
132: /** Dispatches a stop event to the listeners. */
133: protected void sendStop() {
134: if (listener != null)
135: listener.packagerStop();
136: }
137:
138: /* (non-Javadoc)
139: * @see com.izforge.izpack.compiler.IPackager#addCustomJar(com.izforge.izpack.CustomData, java.net.URL)
140: */
141: public void addCustomJar(CustomData ca, URL url) {
142: customDataList.add(ca); // serialized to keep order/variables correct
143: addJarContent(url); // each included once, no matter how many times
144: // added
145: }
146:
147: /* (non-Javadoc)
148: * @see com.izforge.izpack.compiler.IPackager#addJarContent(java.net.URL)
149: */
150: public void addJarContent(URL jarURL) {
151: addJarContent(jarURL, null);
152: }
153:
154: /* (non-Javadoc)
155: * @see com.izforge.izpack.compiler.IPackager#addJarContent(java.net.URL, java.util.List)
156: */
157: public void addJarContent(URL jarURL, List<String> files) {
158: Object[] cont = { jarURL, files };
159: sendMsg("Adding content of jar: " + jarURL.getFile(),
160: PackagerListener.MSG_VERBOSE);
161: includedJarURLs.add(cont);
162: }
163:
164: /* (non-Javadoc)
165: * @see com.izforge.izpack.compiler.IPackager#addLangPack(java.lang.String, java.net.URL, java.net.URL)
166: */
167: public void addLangPack(String iso3, URL xmlURL, URL flagURL) {
168: sendMsg("Adding langpack: " + iso3,
169: PackagerListener.MSG_VERBOSE);
170: // put data & flag as entries in installer, and keep array of iso3's
171: // names
172: langpackNameList.add(iso3);
173: addResource("flag." + iso3, flagURL);
174: installerResourceURLMap.put("langpacks/" + iso3 + ".xml",
175: xmlURL);
176: }
177:
178: /* (non-Javadoc)
179: * @see com.izforge.izpack.compiler.IPackager#addNativeLibrary(java.lang.String, java.net.URL)
180: */
181: public void addNativeLibrary(String name, URL url) throws Exception {
182: sendMsg("Adding native library: " + name,
183: PackagerListener.MSG_VERBOSE);
184: installerResourceURLMap.put("native/" + name, url);
185: }
186:
187: /* (non-Javadoc)
188: * @see com.izforge.izpack.compiler.IPackager#addNativeUninstallerLibrary(com.izforge.izpack.CustomData)
189: */
190: public void addNativeUninstallerLibrary(CustomData data) {
191: customDataList.add(data); // serialized to keep order/variables
192: // correct
193:
194: }
195:
196: /* (non-Javadoc)
197: * @see com.izforge.izpack.compiler.IPackager#addPack(com.izforge.izpack.compiler.PackInfo)
198: */
199: public void addPack(PackInfo pack) {
200: packsList.add(pack);
201: }
202:
203: /* (non-Javadoc)
204: * @see com.izforge.izpack.compiler.IPackager#addPanelJar(com.izforge.izpack.Panel, java.net.URL)
205: */
206: public void addPanelJar(Panel panel, URL jarURL) {
207: panelList.add(panel); // serialized to keep order/variables correct
208: addJarContent(jarURL); // each included once, no matter how many times
209: // added
210: }
211:
212: /* (non-Javadoc)
213: * @see com.izforge.izpack.compiler.IPackager#addResource(java.lang.String, java.net.URL)
214: */
215: public void addResource(String resId, URL url) {
216: sendMsg("Adding resource: " + resId,
217: PackagerListener.MSG_VERBOSE);
218: installerResourceURLMap.put("res/" + resId, url);
219: }
220:
221: /* (non-Javadoc)
222: * @see com.izforge.izpack.compiler.IPackager#getCompressor()
223: */
224: public PackCompressor getCompressor() {
225: return compressor;
226: }
227:
228: /* (non-Javadoc)
229: * @see com.izforge.izpack.compiler.IPackager#getPackagerListener()
230: */
231: public PackagerListener getPackagerListener() {
232: return listener;
233: }
234:
235: /* (non-Javadoc)
236: * @see com.izforge.izpack.compiler.IPackager#getPacksList()
237: */
238: public List<PackInfo> getPacksList() {
239: return packsList;
240: }
241:
242: /* (non-Javadoc)
243: * @see com.izforge.izpack.compiler.IPackager#getVariables()
244: */
245: public Properties getVariables() {
246: return variables;
247: }
248:
249: /* (non-Javadoc)
250: * @see com.izforge.izpack.compiler.IPackager#initPackCompressor(java.lang.String, int)
251: */
252: public void initPackCompressor(String compr_format, int compr_level)
253: throws CompilerException {
254: compressor = PackCompressorFactory.get(compr_format);
255: compressor.setCompressionLevel(compr_level);
256: }
257:
258: /* (non-Javadoc)
259: * @see com.izforge.izpack.compiler.IPackager#setGUIPrefs(com.izforge.izpack.GUIPrefs)
260: */
261: public void setGUIPrefs(GUIPrefs prefs) {
262: sendMsg("Setting the GUI preferences",
263: PackagerListener.MSG_VERBOSE);
264: guiPrefs = prefs;
265: }
266:
267: /* (non-Javadoc)
268: * @see com.izforge.izpack.compiler.IPackager#setInfo(com.izforge.izpack.Info)
269: */
270: public void setInfo(Info info) throws Exception {
271: sendMsg("Setting the installer information",
272: PackagerListener.MSG_VERBOSE);
273: this .info = info;
274: if (!getCompressor().useStandardCompression()
275: && getCompressor().getDecoderMapperName() != null) {
276: this .info.setPackDecoderClassName(getCompressor()
277: .getDecoderMapperName());
278: }
279: }
280:
281: /* (non-Javadoc)
282: * @see com.izforge.izpack.compiler.IPackager#setPackagerListener(com.izforge.izpack.compiler.PackagerListener)
283: */
284: public void setPackagerListener(PackagerListener listener) {
285: this .listener = listener;
286: }
287:
288: /**
289: * @return the rules
290: */
291: public Map<String, Condition> getRules() {
292: return this .rules;
293: }
294:
295: /**
296: * @param rules the rules to set
297: */
298: public void setRules(Map<String, Condition> rules) {
299: this .rules = rules;
300: }
301:
302: protected void writeInstaller() throws Exception {
303: // write the primary jar. MUST be first so manifest is not overwritten
304: // by
305: // an included jar
306: writeSkeletonInstaller();
307:
308: writeInstallerObject("info", info);
309: writeInstallerObject("vars", variables);
310: writeInstallerObject("GUIPrefs", guiPrefs);
311: writeInstallerObject("panelsOrder", panelList);
312: writeInstallerObject("customData", customDataList);
313: writeInstallerObject("langpacks.info", langpackNameList);
314: writeInstallerObject("rules", rules);
315: writeInstallerObject("dynvariables", dynamicvariables);
316: writeInstallerResources();
317: writeIncludedJars();
318:
319: // Pack File Data may be written to separate jars
320: writePacks();
321: }
322:
323: protected abstract void writeInstallerObject(String entryName,
324: Object object) throws IOException;
325:
326: protected abstract void writeSkeletonInstaller() throws IOException;
327:
328: protected abstract void writeInstallerResources()
329: throws IOException;
330:
331: protected abstract void writeIncludedJars() throws IOException;
332:
333: protected abstract void writePacks() throws Exception;
334:
335: /**
336: * @return the dynamicvariables
337: */
338: public Map<String, DynamicVariable> getDynamicVariables() {
339: return this .dynamicvariables;
340: }
341:
342: /**
343: * @param dynamicvariables the dynamicvariables to set
344: */
345: public void setDynamicVariables(
346: Map<String, DynamicVariable> dynamicvariables) {
347: this.dynamicvariables = dynamicvariables;
348: }
349: }
|