source: release-kits/shared/ant-installer/src_ext/org/tp23/antinstaller/taskdefs/Installer.java@ 15210

Last change on this file since 15210 was 15210, checked in by oranfry, 16 years ago

Lots of changes to the installer. Now only look in LanguagePack resource bundle for strings.

File size: 12.7 KB
Line 
1/*
2 * Copyright 2005 Paul Hinds
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17package org.tp23.antinstaller.taskdefs;
18
19import java.io.File;
20import java.io.FileInputStream;
21import java.io.IOException;
22import java.io.InputStream;
23
24import javax.xml.parsers.SAXParser;
25import javax.xml.parsers.SAXParserFactory;
26
27import org.apache.tools.ant.BuildException;
28import org.apache.tools.ant.Project;
29import org.apache.tools.ant.taskdefs.Jar;
30import org.apache.tools.ant.taskdefs.Manifest;
31import org.apache.tools.ant.taskdefs.ManifestException;
32import org.apache.tools.ant.types.FileSet;
33import org.apache.tools.ant.types.ZipFileSet;
34import org.apache.tools.zip.ZipOutputStream;
35import org.tp23.antinstaller.renderer.swing.plaf.LookAndFeelFactory;
36import org.tp23.antinstaller.runtime.ConfigurationLoader;
37import org.xml.sax.InputSource;
38import org.xml.sax.SAXException;
39import org.xml.sax.SAXParseException;
40import org.xml.sax.helpers.DefaultHandler;
41
42/**
43 * Creates a Installer archive.
44 *
45 *
46 * @ant.task category="packaging"
47 */
48public class Installer extends Jar {
49
50 public static final String NON_EXTRACTOR = "NonExtractor";
51 public static final String SELF_EXTRACTOR = "SelfExtractor";
52
53 /** The extract type to use NonExtractor or SelfExtractor */
54 private String extractType;
55
56 /** The AntInstall config file */
57 private File installConfig;
58
59 /** The Ant build.xml to be used*/
60 private File buildFile;
61
62 /** The location of ant-installer.jar and ant-installer-ext.jar and possibly jgoodies-edited-1_2_2.jar */
63 private File antInstallLib;
64
65 /** The location of xercesImpl.jar and xml-apis.jar
66 * This is not requried Xerces is optional and will increase the download size */
67 private File xercesLib;
68
69 /** The location of ant.jar and ant-launcher.jar */
70 private File antLib;
71
72 /** The AntInstaller Look And Feel to be used */
73 private String laf;
74
75 /** The icon set to use */
76 private String icons;
77
78 /** Stop the build if there is a known error in the config */
79 protected boolean failOnError = false;
80
81 /** perform the validation */
82 protected boolean validateConfig = false;
83
84 private boolean buildFileSet = false;
85 private boolean configFileSet = false;
86 /** Indicates that the build.xml and antinstall-config.xml have been added to the fileset already */
87 private boolean startCheckDuplicates = false;
88
89 /** constructor */
90 public Installer() {
91 super();
92 archiveType = "jar";
93 emptyBehavior = "create";
94 setEncoding("UTF8");
95 }
96
97 protected void cleanUp() {
98 super.cleanUp();
99 }
100
101 public void reset() {
102 super.reset();
103 extractType = null;
104 installConfig = null;
105 buildFile = null;
106 }
107
108 /**
109 * @param installConfig The installConfig to set.
110 */
111 public void setInstallConfig(File installConfig) {
112 this.installConfig = installConfig;
113 if (!installConfig.exists()) {
114 throw new BuildException("AntInstall config: "
115 + installConfig
116 + " does not exist.");
117 }
118 // Create a ZipFileSet for this file, and pass it up.
119 ZipFileSet fs = new ZipFileSet();
120 fs.setFile(installConfig);
121 fs.setFullpath("antinstall-config.xml");
122 super.addFileset(fs);
123 if(this.buildFile != null) {
124 startCheckDuplicates = true;
125 }
126 }
127 /**
128 * @param buildFile The buildFile to set.
129 */
130 public void setBuildFile(File buildFile) {
131 this.buildFile = buildFile;
132 if (!buildFile.exists()) {
133 throw new BuildException("AntInstall build file: "
134 + buildFile
135 + " does not exist.");
136 }
137 // Create a ZipFileSet for this file, and pass it up.
138 ZipFileSet fs = new ZipFileSet();
139 fs.setFile(buildFile);
140 fs.setFullpath("build.xml");
141 super.addFileset(fs);
142 if(this.installConfig != null) {
143 startCheckDuplicates = true;
144 }
145 }
146 /**
147 * @param icons The ocons pack to use for buttons.
148 */
149 public void setIcons(String icons) {
150 this.icons = icons;
151 // Create a ZipFileSet for this file, and pass it up.
152 File iconJar = new File(antInstallLib, "ai-icons-" + icons + ".jar");
153 if (!iconJar.exists()) {
154 throw new BuildException("Missing icons: "
155 + iconJar
156 + " does not exist.");
157 }
158 FileSet set = new FileSet();
159 set.setFile(iconJar);
160 addZipGroupFileset(set);
161
162 }
163 /**
164 * @param extractType The extractType to set.
165 */
166 public void setExtractType(String extractType) {
167 this.extractType = extractType;
168 }
169
170 public void setFailOnError(boolean fail) {
171 failOnError = fail;
172 }
173
174 public void setValidateConfig(boolean validate) {
175 validateConfig = validate;
176 }
177
178 /**
179 * The location of ant-installer.jar and possibly jgoodies-edited-1_2_2.jar
180 * @param antInstallLib The antInstallLib to set.
181 */
182 public void setAntInstallLib(File antInstallLib) {
183 this.antInstallLib = antInstallLib;
184 FileSet set = new FileSet();
185 set.setFile(new File(antInstallLib, "ant-installer.jar"));
186 addZipGroupFileset(set);
187 }
188 /**
189 * The location of ant.jar and ant-launcher.jar
190 * @param antLib The antLib to set.
191 */
192 public void setAntLib(File antLib) {
193 this.antLib = antLib;
194 FileSet set = new FileSet();
195 set.setFile(new File(antLib, "ant.jar"));
196 set.setFile(new File(antLib, "ant-launcher.jar"));
197 addZipGroupFileset(set);
198 }
199 /**
200 * @param xercesLib The xercesLib to set.
201 */
202 public void setXercesLib(File xercesLib) {
203 this.xercesLib = xercesLib;
204 FileSet set = new FileSet();
205 set.setFile(new File(xercesLib, "xercesImpl.jar"));
206 set.setFile(new File(xercesLib, "xml-apis.jar"));
207 addZipGroupFileset(set);
208 }
209
210 /**
211 * Overrides the ZIP execute() method which creates filesets
212 */
213 public void execute(){
214 log(".-------------------------------.");
215 log("|-(o--~AntInstaller.sf.net~--o)-|");
216 log("`-----------------by-Paul-Hinds-ÂŽ");
217
218 if(validateConfig) {
219 validateConfig();
220 } else if(extractType.equals(SELF_EXTRACTOR)){
221 // this reads the config just
222 // to extract the lookAndFeel attribute for the manifest at the moment
223 readConfig();
224 }
225 if( LookAndFeelFactory.isDefault(getLaf()) ){
226 FileSet set = new FileSet();
227 set.setFile(new File(antInstallLib, "jgoodies-edited-1_2_2.jar"));
228 addZipGroupFileset(set);
229 }
230
231 super.execute();
232 }
233
234 /**
235 * override of parent; validates configuration
236 * before initializing the output stream. The Manifest is set in the Jar superclass's
237 * method so Manifest modifications must be performed in this method
238 */
239 protected void initZipOutputStream(ZipOutputStream zOut)
240 throws IOException, BuildException {
241 // If no buildFile file is specified, it's an error.
242 if (buildFile == null && !isInUpdateMode()) {
243 throw new BuildException("buildFile attribute is required", getLocation());
244 }
245 // If no installConfig file is specified, it's an error.
246 if (installConfig == null && !isInUpdateMode()) {
247 throw new BuildException("installConfig attribute is required", getLocation());
248 }
249 try{
250 addConfiguredManifest(this.getManifest());
251 }
252 catch(ManifestException me){
253 throw new BuildException("Cant add AntInstaller Manifest", me, getLocation());
254 }
255 super.initZipOutputStream(zOut);
256 }
257
258 protected void zipFile(InputStream is, ZipOutputStream zOut, String vPath,
259 long lastModified, File fromArchive, int mode)
260 throws IOException {
261
262 if(vPath.equalsIgnoreCase("antinstall-config.xml")) {
263 if(buildFileSet) {
264 log("Two antinstall-config.xml files in jar", Project.MSG_WARN);
265 }
266 buildFileSet = true;
267 }
268 if(vPath.equalsIgnoreCase("build.xml")) {
269 if(configFileSet) {
270 log("Two build.xml files in jar", Project.MSG_WARN);
271 }
272 configFileSet = true;
273 }
274
275 super.zipFile(is, zOut, vPath, lastModified, fromArchive, mode);
276 }
277
278 /**
279 * This method is only valid after readConfig() or validateConfig() have been run
280 * @return Returns the Look And Feel class.
281 */
282 private String getLaf() {
283 if(laf == null){
284 return LookAndFeelFactory.DEFAULT_LAF;
285 }
286 return laf;
287 }
288
289 private Manifest getManifest() throws ManifestException{
290 if(extractType.equalsIgnoreCase(NON_EXTRACTOR)){
291 return getNonExtractorManifest();
292 }
293 else if(extractType.equalsIgnoreCase(SELF_EXTRACTOR)){
294 return getSelfExtractorManifest();
295 }
296 else {
297 throw new BuildException("Invalid extractType: " + extractType);
298 }
299 }
300
301 private Manifest getNonExtractorManifest() throws ManifestException{
302 return getCustomManifest("org.tp23.antinstaller.selfextract.NonExtractor");
303 }
304 private Manifest getSelfExtractorManifest() throws ManifestException{
305 return getCustomManifest("org.tp23.antinstaller.selfextract.SelfExtractor");
306 }
307 private Manifest getCustomManifest(String mainClass) throws ManifestException{
308 log("Creating MANIFEST.mf");
309 Manifest newManifest = new Manifest();
310 Manifest.Section mainSection = newManifest.getMainSection();
311 Manifest.Attribute attmc = new Manifest.Attribute();
312 attmc.setName("Main-Class");
313 attmc.setValue(mainClass);
314 mainSection.addAttributeAndCheck(attmc);
315 Manifest.Attribute attlaf = new Manifest.Attribute();
316 attlaf.setName("Look-And-Feel");
317 attlaf.setValue(getLaf());
318 mainSection.addAttributeAndCheck(attlaf);
319 return newManifest;
320
321 }
322
323 protected void validateConfig(){
324
325 int ret = 1;
326 try {
327 log("validating config...");
328 ConfigurationLoader configurationLoader = new ConfigurationLoader();
329 configurationLoader.readConfig(installConfig.getParentFile(), installConfig.getName());
330 ret = configurationLoader.validate();
331 laf = configurationLoader.getInstaller().getLookAndFeel();
332 if(ret != 0){
333 err();
334 }
335 }
336 catch (Exception ex) {
337 log("validation failed");
338 ex.printStackTrace();
339 err();
340 }
341
342 try{
343 log("parsing included build.xml...");
344 InputSource xmlInp = new InputSource(new FileInputStream(buildFile));
345 SAXParserFactory parserFactory = SAXParserFactory.newInstance();
346 SAXParser parser = parserFactory.newSAXParser();
347 parser.parse(xmlInp, new DefaultHandler(){
348 public void error(SAXParseException e) throws SAXException{
349 throw e;
350 }
351 public void fatalError(SAXParseException e) throws SAXException{
352 throw e;
353 }
354 } );
355 log("build.xml is well formed");
356 }
357 catch (Exception ex) {
358 ex.printStackTrace();
359 errNestedBuildXml();
360 }
361 }
362
363 protected void readConfig(){
364
365 try {
366 log("reading config...");
367 ConfigurationLoader configurationLoader = new ConfigurationLoader();
368 configurationLoader.readConfig(installConfig.getParentFile(), installConfig.getName());
369 laf = configurationLoader.getInstaller().getLookAndFeel();
370 }
371 catch (Exception ex) {
372 ex.printStackTrace();
373 err();
374 }
375 }
376
377 /**
378 * error found on validation of the antinstall config
379 */
380 private void err(){
381 String errorMsg = "Error in config file:" + installConfig.getAbsolutePath();
382 if (failOnError) {
383 throw new BuildException(errorMsg);
384 } else {
385 log(errorMsg, Project.MSG_ERR);
386 }
387 }
388 /**
389 * error found in the build.xml used by ant installer (not the one
390 * running this task)
391 */
392 private void errNestedBuildXml(){
393 String errorMsg = "Error in included build file:" + buildFile.getAbsolutePath();
394 if (failOnError) {
395 throw new BuildException(errorMsg);
396 } else {
397 log(errorMsg, Project.MSG_ERR);
398 }
399 }
400}
Note: See TracBrowser for help on using the repository browser.