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

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

debugging lines added

File size: 12.8 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("reading config...");
328 ConfigurationLoader configurationLoader = new ConfigurationLoader();
329
330 log("parent file: " + installConfig.getParentFile() );
331 log("name of install config: " + installConfig.getName() );
332
333 configurationLoader.readConfig(installConfig.getParentFile(), installConfig.getName());
334 log("validating config...");
335 ret = configurationLoader.validate();
336 laf = configurationLoader.getInstaller().getLookAndFeel();
337 if(ret != 0){
338 err();
339 }
340 }
341 catch (Exception ex) {
342 log("validation failed");
343 ex.printStackTrace();
344 err();
345 }
346
347 try{
348 log("parsing included build.xml...");
349 InputSource xmlInp = new InputSource(new FileInputStream(buildFile));
350 SAXParserFactory parserFactory = SAXParserFactory.newInstance();
351 SAXParser parser = parserFactory.newSAXParser();
352 parser.parse(xmlInp, new DefaultHandler(){
353 public void error(SAXParseException e) throws SAXException{
354 throw e;
355 }
356 public void fatalError(SAXParseException e) throws SAXException{
357 throw e;
358 }
359 } );
360 log("build.xml is well formed");
361 }
362 catch (Exception ex) {
363 ex.printStackTrace();
364 errNestedBuildXml();
365 }
366 }
367
368 protected void readConfig(){
369
370 try {
371 log("reading config...");
372 ConfigurationLoader configurationLoader = new ConfigurationLoader();
373 configurationLoader.readConfig(installConfig.getParentFile(), installConfig.getName());
374 laf = configurationLoader.getInstaller().getLookAndFeel();
375 }
376 catch (Exception ex) {
377 ex.printStackTrace();
378 err();
379 }
380 }
381
382 /**
383 * error found on validation of the antinstall config
384 */
385 private void err(){
386 String errorMsg = "Error in config file:" + installConfig.getAbsolutePath();
387 if (failOnError) {
388 throw new BuildException(errorMsg);
389 } else {
390 log(errorMsg, Project.MSG_ERR);
391 }
392 }
393 /**
394 * error found in the build.xml used by ant installer (not the one
395 * running this task)
396 */
397 private void errNestedBuildXml(){
398 String errorMsg = "Error in included build file:" + buildFile.getAbsolutePath();
399 if (failOnError) {
400 throw new BuildException(errorMsg);
401 } else {
402 log(errorMsg, Project.MSG_ERR);
403 }
404 }
405}
Note: See TracBrowser for help on using the repository browser.