1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package installtoolkit;
19
20 import java.io.BufferedReader;
21 import java.io.File;
22 import java.io.IOException;
23 import java.io.StringReader;
24 import java.util.ArrayList;
25 import java.util.List;
26
27 import javax.xml.parsers.ParserConfigurationException;
28
29 import org.apache.tools.ant.BuildException;
30 import org.apache.tools.ant.Task;
31 import org.apache.tools.ant.taskdefs.Copy;
32 import org.apache.tools.ant.types.FileSet;
33 import org.dom4j.Document;
34 import org.dom4j.DocumentException;
35 import org.dom4j.Element;
36 import org.dom4j.io.SAXReader;
37 import org.xml.sax.SAXException;
38
39 /**
40 * Base class for installer-builder tasks. <br/>
41 * This class holds common functions for all install-builder
42 * tasks and handles the reading of the descriptorfile.
43 *
44 *
45 * @author Christian Elberfeld <elberfeld@web.de>
46 *
47 */
48 public abstract class InstallerGeneratorTask extends Task {
49
50 /** The XML Namespace of the desriptor file */
51 public static final String DESCRIPTOR_NAMESPACE = "http://install-toolkit.sourceforge.net/InstallerDescription";
52
53 protected boolean debug = false;
54 protected String version;
55 protected File descriptor;
56 protected File destdir;
57 protected File workdir;
58 protected boolean validate = true;
59 protected File schema;
60
61 protected String packageName;
62 protected String manufacturer;
63 protected String email;
64 protected String shortDescription;
65 protected List<String> longDescription;
66 protected List<String> license;
67
68
69
70
71 /**
72 * The execute method reads the descriptor file and executes the
73 * logic of the concrete class by calling the build() method.
74 *
75 * @see Task#execute()
76 */
77 @Override
78 public void execute() throws BuildException {
79
80 try {
81
82 if (debug) handleOutput("Starting execute()");
83
84 if (this.version == null) throw new BuildException("Attribute \"version\" must be set");
85 if (this.descriptor == null) throw new BuildException("Attribute \"descriptor\" must be set");
86 if (this.destdir == null) throw new BuildException("Attribute \"destdir\" must be set");
87 if (this.workdir == null) throw new BuildException("Attribute \"workdir\" must be set");
88 if (this.schema == null) throw new BuildException("Attribute \"schema\" must be set");
89
90 readDescriptorFile();
91 build();
92
93 if (debug) handleOutput("execute() finished");
94
95 } catch (Exception e) {
96
97 e.printStackTrace();
98 throw new BuildException(e.getMessage(),e);
99 }
100
101 }
102
103 /**
104 * The build() method must be overridden by the concrete install-builder
105 * classes.
106 *
107 * @throws Exception
108 */
109 protected abstract void build() throws Exception;
110
111
112
113
114 private void readDescriptorFile() throws SAXException, DocumentException, IOException, ParserConfigurationException {
115
116
117 if (debug) handleOutput("Reading Descriptor file: "+this.descriptor);
118
119 SAXReader reader = new SAXReader();
120 reader.setFeature("http://apache.org/xml/features/validation/schema", this.validate);
121 reader.setProperty("http://apache.org/xml/properties/schema/external-schemaLocation", DESCRIPTOR_NAMESPACE + " " + this.schema.getAbsolutePath());
122 Document doc = reader.read(descriptor);
123
124 Element root = doc.getRootElement();
125 if (debug) handleOutput("Reading Tag <Installer> ...");
126
127 for (Object obj : root.elements()) {
128
129 Element element = (Element) obj;
130
131 if (element.getName() == "Package") {
132
133 this.packageName = element.attributeValue("Name");
134 if (debug) handleOutput("Package -> Name: "+this.packageName);
135
136 this.manufacturer = element.attributeValue("Manufacturer");
137 if (debug) handleOutput("Package -> Manufacturer: "+this.manufacturer);
138
139 this.email = element.attributeValue("Email");
140 if (debug) handleOutput("Package -> Email: "+this.email);
141
142 }
143
144
145 if (element.getName() == "Description") {
146
147 if (debug) handleOutput("Reading Tag: Description ...");
148 readDescription(element);
149 }
150
151
152 if (element.getName() == "License") {
153
154
155 BufferedReader license_reader = new BufferedReader(new StringReader(element.getText()));
156
157 this.license = new ArrayList<String>();
158
159 String line = license_reader.readLine();
160
161 while(line != null) {
162
163 String l = line.trim();
164 if (debug) handleOutput("License (Line): "+l);
165 this.license.add(l);
166
167 line = license_reader.readLine();
168 }
169
170 }
171
172 if (element.getName() == "Windows") {
173
174 if (debug) handleOutput("Reading Tag: Windows ...");
175 readWindowsTag(element);
176 }
177
178 if (element.getName() == "Deb") {
179
180 if (debug) handleOutput("Reading Tag: Deb ...");
181 readDebTag(element);
182 }
183
184 }
185
186 if (debug) handleOutput("Finished reading Descriptor file");
187 }
188
189 /**
190 * Helper method to read the <Description> tag.
191 *
192 * @param root The <Description> element.
193 * @throws IOException
194 */
195 private void readDescription(Element root) throws IOException {
196
197 for (Object obj : root.elements()) {
198
199 Element element = (Element) obj;
200
201 if (element.getName() == "Short") {
202
203 this.shortDescription = element.getText();
204 if (debug) handleOutput("Short Description: "+this.shortDescription);
205 }
206
207 if (element.getName() == "Long") {
208
209 BufferedReader desc_reader = new BufferedReader(new StringReader(element.getText()));
210
211 this.longDescription = new ArrayList<String>();
212
213 String line = desc_reader.readLine();
214 while(line != null) {
215
216 String l = line.trim();
217
218 if (l.length() > 0) {
219
220 if (debug) handleOutput("Long Description (Line): "+l);
221 this.longDescription.add(l);
222 }
223
224 line = desc_reader.readLine();
225 }
226
227 }
228
229 }
230
231 }
232
233 /**
234 * This method should be overridden if the task needs
235 * informations from the <Win> element of the
236 * descriptor file.
237 *
238 * @param root
239 */
240 protected void readWindowsTag(Element root) {};
241
242 /**
243 * This method should be overridden if the task needs
244 * informations from the <Deb> element of the
245 * descriptor file.
246 *
247 * @param root
248 */
249 protected void readDebTag(Element root) {}
250
251
252
253
254 /**
255 * Read patterns from the descriptor file
256 *
257 * @param root The element containig <Include> and <Exclude> Elements as childs
258 * @returns The patterns as list of Pattern classes
259 *
260 */
261 protected List<Pattern> readPatterns(Element root) {
262
263 List<Pattern> patterns = new ArrayList<Pattern>();
264
265 for (Object obj : root.elements()) {
266
267 Element element = (Element) obj;
268
269 if (element.getName() == "Include") {
270
271 Pattern pattern = new Pattern(element.getText(),false);
272 if (debug) handleOutput("Include Pattern: "+pattern);
273 patterns.add(pattern);
274 }
275
276 if (element.getName() == "Exclude") {
277
278 Pattern pattern = new Pattern(element.getText(),true);
279 if (debug) handleOutput("Exclude Pattern: "+pattern);
280 patterns.add(pattern);
281 }
282
283 }
284
285 return patterns;
286
287 }
288
289
290 /**
291 * Create an Ant FileSet from a list of patterns
292 *
293 * @param patterns List of Patterns
294 * @param dir The basedirectory for the fileset
295 * @return
296 */
297 protected FileSet createFilesetFromPatterns(List<Pattern> patterns,File dir) {
298
299 FileSet fileset = new FileSet();
300
301 if (debug) handleOutput("Creating FileSet [Basedir: "+dir.getAbsolutePath()+"]");
302 fileset.setDir(dir);
303
304 for (Pattern p : patterns) {
305
306 if (p.isInvert()) {
307
308 if (debug) handleOutput("Adding Exclude: "+p.getPattern());
309 fileset.createExclude().setName(p.getPattern());
310
311 } else {
312
313 if (debug) handleOutput("Adding Include: "+p.getPattern());
314 fileset.createInclude().setName(p.getPattern());
315
316 }
317
318 }
319
320 return fileset;
321
322 }
323
324
325 /**
326 * Copy a file
327 *
328 * @param src Source file
329 * @param dst Destination file
330 */
331 protected void copy(File src, File dst) {
332
333 Copy copy_task = new Copy();
334 copy_task.setProject(getProject());
335 copy_task.setTaskName("copy");
336 copy_task.setVerbose(this.debug);
337 copy_task.setFile(src);
338 copy_task.setTofile(dst);
339 copy_task.execute();
340
341 }
342
343
344
345
346 /**
347 * Enable debug output
348 *
349 * @param debug
350 */
351 public void setDebug(boolean debug) {
352 this.debug = debug;
353 }
354
355
356 /**
357 * The descriptor file to read
358 *
359 * @param descriptor
360 */
361 public void setDescriptor(File descriptor) {
362 this.descriptor = descriptor;
363 }
364
365
366 /**
367 * The version number of the generatd installer package
368 *
369 * @param version
370 */
371 public void setVersion(String version) {
372 this.version = version;
373 }
374
375 /**
376 * The XML Schema for the descriptor file
377 *
378 * @param schema
379 */
380 public void setSchema(File schema) {
381 this.schema = schema;
382 }
383
384 /**
385 * If false, the descriptor file will not be validated
386 *
387 * @param validate
388 */
389 public void setValidate(boolean validate) {
390 this.validate = validate;
391 }
392
393 /**
394 * The directory where the installer packge will be created
395 *
396 * @param destdir
397 */
398 public void setDestdir(File destdir) {
399 this.destdir = destdir;
400 }
401
402 /**
403 * The directory to compile the installer package
404 *
405 * @param workdir
406 */
407 public void setWorkdir(File workdir) {
408 this.workdir = workdir;
409 }
410
411
412 }