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

Last change on this file since 17639 was 17639, checked in by oranfry, 15 years ago

antinstaller inserts the progress icon itself now so rks dont have to

File size: 12.9 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
152 // Create a ZipFileSet for this file, and pass it up.
153 FileSet set = null;
154 File iconJar = new File(antInstallLib, "ai-icons-" + icons + ".jar");
155 if (!iconJar.exists()) {
156 throw new BuildException("Missing icons: "
157 + iconJar
158 + " does not exist.");
159 }
160 set = new ZipFileSet();
161 set.setFile(iconJar);
162 addZipGroupFileset(set);
163
164 }
165 /**
166 * @param extractType The extractType to set.
167 */
168 public void setExtractType(String extractType) {
169 this.extractType = extractType;
170 }
171
172 public void setFailOnError(boolean fail) {
173 failOnError = fail;
174 }
175
176 public void setValidateConfig(boolean validate) {
177 validateConfig = validate;
178 }
179
180 /**
181 * The location of ant-installer.jar and possibly jgoodies-edited-1_2_2.jar
182 * @param antInstallLib The antInstallLib to set.
183 */
184 public void setAntInstallLib(File antInstallLib) {
185 this.antInstallLib = antInstallLib;
186 FileSet set = new FileSet();
187 set.setFile(new File(antInstallLib, "ant-installer.jar"));
188 addZipGroupFileset(set);
189 }
190 /**
191 * The location of ant.jar and ant-launcher.jar
192 * @param antLib The antLib to set.
193 */
194 public void setAntLib(File antLib) {
195 this.antLib = antLib;
196 FileSet set = new FileSet();
197 set.setFile(new File(antLib, "ant.jar"));
198 set.setFile(new File(antLib, "ant-launcher.jar"));
199 addZipGroupFileset(set);
200 }
201 /**
202 * @param xercesLib The xercesLib to set.
203 */
204 public void setXercesLib(File xercesLib) {
205 this.xercesLib = xercesLib;
206 FileSet set = new FileSet();
207 set.setFile(new File(xercesLib, "xercesImpl.jar"));
208 set.setFile(new File(xercesLib, "xml-apis.jar"));
209 addZipGroupFileset(set);
210 }
211
212 /**
213 * Overrides the ZIP execute() method which creates filesets
214 */
215 public void execute(){
216 log(".-------------------------------.");
217 log("|-(o--~AntInstaller.sf.net~--o)-|");
218 log("`-----------------by-Paul-Hinds-ÂŽ");
219
220 if(validateConfig) {
221 validateConfig();
222 } else if(extractType.equals(SELF_EXTRACTOR)){
223 // this reads the config just
224 // to extract the lookAndFeel attribute for the manifest at the moment
225 readConfig();
226 }
227 if( LookAndFeelFactory.isDefault(getLaf()) ){
228 FileSet set = new FileSet();
229 set.setFile(new File(antInstallLib, "jgoodies-edited-1_2_2.jar"));
230 addZipGroupFileset(set);
231 }
232
233 super.execute();
234 }
235
236 /**
237 * override of parent; validates configuration
238 * before initializing the output stream. The Manifest is set in the Jar superclass's
239 * method so Manifest modifications must be performed in this method
240 */
241 protected void initZipOutputStream(ZipOutputStream zOut)
242 throws IOException, BuildException {
243 // If no buildFile file is specified, it's an error.
244 if (buildFile == null && !isInUpdateMode()) {
245 throw new BuildException("buildFile attribute is required", getLocation());
246 }
247 // If no installConfig file is specified, it's an error.
248 if (installConfig == null && !isInUpdateMode()) {
249 throw new BuildException("installConfig attribute is required", getLocation());
250 }
251 try{
252 addConfiguredManifest(this.getManifest());
253 }
254 catch(ManifestException me){
255 throw new BuildException("Cant add AntInstaller Manifest", me, getLocation());
256 }
257 super.initZipOutputStream(zOut);
258 }
259
260 protected void zipFile(InputStream is, ZipOutputStream zOut, String vPath,
261 long lastModified, File fromArchive, int mode)
262 throws IOException {
263
264 if(vPath.equalsIgnoreCase("antinstall-config.xml")) {
265 if(buildFileSet) {
266 log("Two antinstall-config.xml files in jar", Project.MSG_WARN);
267 }
268 buildFileSet = true;
269 }
270 if(vPath.equalsIgnoreCase("build.xml")) {
271 if(configFileSet) {
272 log("Two build.xml files in jar", Project.MSG_WARN);
273 }
274 configFileSet = true;
275 }
276
277 super.zipFile(is, zOut, vPath, lastModified, fromArchive, mode);
278 }
279
280 /**
281 * This method is only valid after readConfig() or validateConfig() have been run
282 * @return Returns the Look And Feel class.
283 */
284 private String getLaf() {
285 if(laf == null){
286 return LookAndFeelFactory.DEFAULT_LAF;
287 }
288 return laf;
289 }
290
291 private Manifest getManifest() throws ManifestException{
292 if(extractType.equalsIgnoreCase(NON_EXTRACTOR)){
293 return getNonExtractorManifest();
294 }
295 else if(extractType.equalsIgnoreCase(SELF_EXTRACTOR)){
296 return getSelfExtractorManifest();
297 }
298 else {
299 throw new BuildException("Invalid extractType: " + extractType);
300 }
301 }
302
303 private Manifest getNonExtractorManifest() throws ManifestException{
304 return getCustomManifest("org.tp23.antinstaller.selfextract.NonExtractor");
305 }
306 private Manifest getSelfExtractorManifest() throws ManifestException{
307 return getCustomManifest("org.tp23.antinstaller.selfextract.SelfExtractor");
308 }
309 private Manifest getCustomManifest(String mainClass) throws ManifestException{
310 log("Creating MANIFEST.mf");
311 Manifest newManifest = new Manifest();
312 Manifest.Section mainSection = newManifest.getMainSection();
313 Manifest.Attribute attmc = new Manifest.Attribute();
314 attmc.setName("Main-Class");
315 attmc.setValue(mainClass);
316 mainSection.addAttributeAndCheck(attmc);
317 Manifest.Attribute attlaf = new Manifest.Attribute();
318 attlaf.setName("Look-And-Feel");
319 attlaf.setValue(getLaf());
320 mainSection.addAttributeAndCheck(attlaf);
321 return newManifest;
322
323 }
324
325 protected void validateConfig() {
326
327 int ret = 1;
328 try {
329 log("reading config...");
330 ConfigurationLoader configurationLoader = new ConfigurationLoader();
331
332 log("parent file: " + installConfig.getParentFile() );
333 log("name of install config: " + installConfig.getName() );
334
335 configurationLoader.readConfig(installConfig.getParentFile(), installConfig.getName());
336 log("validating config...");
337 ret = configurationLoader.validate();
338 laf = configurationLoader.getInstaller().getLookAndFeel();
339 if(ret != 0){
340 err();
341 }
342 }
343 catch (Exception ex) {
344 log("validation failed");
345 ex.printStackTrace();
346 err();
347 }
348
349 try{
350 log("parsing included build.xml...");
351 InputSource xmlInp = new InputSource(new FileInputStream(buildFile));
352 SAXParserFactory parserFactory = SAXParserFactory.newInstance();
353 SAXParser parser = parserFactory.newSAXParser();
354 parser.parse(xmlInp, new DefaultHandler(){
355 public void error(SAXParseException e) throws SAXException{
356 throw e;
357 }
358 public void fatalError(SAXParseException e) throws SAXException{
359 throw e;
360 }
361 } );
362 log("build.xml is well formed");
363 }
364 catch (Exception ex) {
365 ex.printStackTrace();
366 errNestedBuildXml();
367 }
368 }
369
370 protected void readConfig(){
371
372 try {
373 log("reading config...");
374 ConfigurationLoader configurationLoader = new ConfigurationLoader();
375 configurationLoader.readConfig(installConfig.getParentFile(), installConfig.getName());
376 laf = configurationLoader.getInstaller().getLookAndFeel();
377 }
378 catch (Exception ex) {
379 ex.printStackTrace();
380 err();
381 }
382 }
383
384 /**
385 * error found on validation of the antinstall config
386 */
387 private void err(){
388 String errorMsg = "Error in config file:" + installConfig.getAbsolutePath();
389 if (failOnError) {
390 throw new BuildException(errorMsg);
391 } else {
392 log(errorMsg, Project.MSG_ERR);
393 }
394 }
395 /**
396 * error found in the build.xml used by ant installer (not the one
397 * running this task)
398 */
399 private void errNestedBuildXml(){
400 String errorMsg = "Error in included build file:" + buildFile.getAbsolutePath();
401 if (failOnError) {
402 throw new BuildException(errorMsg);
403 } else {
404 log(errorMsg, Project.MSG_ERR);
405 }
406 }
407}
Note: See TracBrowser for help on using the repository browser.