KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > zeus > util > ZeusTask


1 /*
2  * Enhydra Java Application Server Project
3  *
4  * The contents of this file are subject to the Enhydra Public License
5  * Version 1.1 (the "License"); you may not use this file except in
6  * compliance with the License. You may obtain a copy of the License on
7  * the Enhydra web site ( http://www.enhydra.org/ ).
8  *
9  * Software distributed under the License is distributed on an "AS IS"
10  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
11  * the License for the specific terms governing rights and limitations
12  * under the License.
13  *
14  * The Initial Developer of the Enhydra Application Server is Lutris
15  * Technologies, Inc. The Enhydra Application Server and portions created
16  * by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
17  * All Rights Reserved.
18  */

19 package org.enhydra.zeus.util;
20
21 import java.io.File JavaDoc;
22 import java.util.Enumeration JavaDoc;
23 import java.util.Hashtable JavaDoc;
24 import java.util.StringTokenizer JavaDoc;
25 import java.util.Vector JavaDoc;
26 import java.util.Properties JavaDoc;
27
28 // Ant imports
29
import org.apache.tools.ant.BuildException;
30 import org.apache.tools.ant.Task;
31 import org.apache.tools.ant.types.Path;
32 import org.apache.tools.ant.types.Reference;
33
34 // Reflection
35
import java.lang.reflect.*;
36
37 /**
38  * <p>
39  * <code>ZeusTask</code> is an Ant <code>Task</code> for generating Java
40  * source files from a set of constraints. Please refer to the
41  * <a HREF="http://jakarta.apache.org/ant/index.html">Ant website</a>
42  * for more information. The supported tags are as follows:
43  * </p>
44  * <p>
45  * The <code>zeus</code> element is the top-level element used to initiate
46  * data binding using Zeus. It specifies global options for all constraint
47  * generation processes initiated within it (each using the <code>constraint</code>
48  * element, see below).<br/>
49  * &nbsp;&nbsp;&nbsp;&nbsp;<b>&lt;zeus&gt;</b> Tag<br />
50  * <table border="1" cellspacing="3" cellpadding="3" width="100%">
51  * <tr>
52  * <th>attribute</th>
53  * <th>required</th>
54  * <th>default value</th>
55  * <th>description</th>
56  * </tr>
57  * <tr>
58  * <td>srcDir</td>
59  * <td>no</td>
60  * <td>[Current Working Directory]</td>
61  * <td>The base directory for constraint files</td>
62  * </tr>
63  * <tr>
64  * <td>destDir</td>
65  * <td>yes</td>
66  * <td><i>N/A</i></td>
67  * <td>The directory in which generated Java source files should be
68  * placed. Note that this will be the <i>base</i> directory, and
69  * directories equivalent to the package-level of the generated
70  * source code will be nested within this base.
71  * </td>
72  * </tr>
73  * <tr>
74  * <td>defaultJavaPackage</td>
75  * <td>no</td>
76  * <td>""</td>
77  * <td>The Java package to use on all constraint generation processes
78  * where an explicit Java package is not supplied (using the
79  * <code>javaPackage</code> attribute on the <code>constraint</code>
80  * element, see below).</td>
81  * </tr>
82  * </table>
83  * </p><p>
84  * The <code>constraint</code> element can be nested inside the <code>zeus</code>
85  * element, one or more times. This is used to specify a single constraint generation
86  * process (the conversion from one constraint file to one or more Java source
87  * files). All options specified here override the default options specified on
88  * the <code>zeus</code> element.<br/>
89  * &nbsp;&nbsp;&nbsp;&nbsp;<b>&lt;constraint&gt;</b> Tag<br />
90  * <table border="1" cellspacing="3" cellpadding="3" width="100%">
91  * <tr>
92  * <th>attribute</th>
93  * <th>required</th>
94  * <th>default value</th>
95  * <th>description</th>
96  * </tr>
97  * <tr>
98  * <td>type</td>
99  * <td>yes</td>
100  * <td><i>N/A</i></td>
101  * <td>The type of constraint being supplied. Currently, only <b>DTD</b>
102  * is supported, with <b>XSD</b> (XML Schema) in an alpha state.</td>
103  * </tr>
104  * <tr>
105  * <td>constraintFile</td>
106  * <td>yes</td>
107  * <td><i>N/A</i></td>
108  * <td>The path (working from the <code>sourceDir</code> path, specified
109  * in the <code>zeus</code> element) to the constraint file to generate
110  * source code from.</td>
111  * </tr>
112  * <tr>
113  * <td>javaPackage</td>
114  * <td>no</td>
115  * <td>""</td>
116  * <td>The Java package in which to place generated source code. This overrides
117  * any value supplied in the <code>defaultJavaPackage</code> attribute on
118  * the <code>zeus</code> element.)</td>
119  * </tr>
120  * <tr>
121  * <td>collapseSimpleElements</td>
122  * <td>no</td>
123  * <td>false</td>
124  * <td>Whether or not to collapse simple elements. A simple element is one
125  * in which there is only character content; there are no attributes, and
126  * no nested elements. Collapsing these elements results in properties
127  * that access the simple element's content as <code>get[ElementName]()</code>
128  * instead of <code>get[ElementName]().getValue()</code>.</td>
129  * </tr>
130  * <tr>
131  * <td>ignoreIDAttributes</td>
132  * <td>no</td>
133  * <td>false</td>
134  * <td>Whether or not to ignore ID attributes in deterimining if an element
135  * is simple. When IDREFs are used, most elements have ID attributes that
136  * have no functional meaning. This allows elements with just an ID attribute
137  * to still be collapsed as simple elements.</td>
138  * </tr>
139  * </table>
140  * </p>
141  *
142  * @author J. Matthew Pryor
143  * @author Brett McLaughlin
144  */

145 public class ZeusTask extends Task {
146
147     /** The name of the DTD constraint type */
148     private static final String JavaDoc CONSTRAINT_TYPE_DTD = "DTD";
149     
150     /** The name of the DTD constraint type */
151     private static final String JavaDoc CONSTRAINT_TYPE_XSD = "XSD";
152     
153     /** The directory for specified constraints */
154     private File JavaDoc sourceDir;
155     
156     /** The output directory for generated Java source files */
157     private File JavaDoc destDir;
158     
159     /** The default Java package */
160     private String JavaDoc defaultJavaPackage;
161     
162     /** Whether or not simple elements are collapsed in the default case */
163     private boolean defaultCollapseSimpleElements;
164
165     /** The constraints used as input for class generation */
166     private Vector JavaDoc constraints;
167
168
169     /**
170      * <p>
171      * This default constructor sets up task defaults.
172      * </p>
173      */

174     public ZeusTask() {
175         defaultCollapseSimpleElements = false;
176         defaultJavaPackage = "";
177         constraints = new Vector JavaDoc();
178     }
179
180     /**
181      * <p>
182      * This will handle task execution pre-processing tasks. It processes
183      * these parameters:
184      * <ul>
185      * <li>sourceDir: source directory for constraints supplied. If not
186      * specified, this defaults to the current working directory.</li>
187      * <li>destDir: destination directory for the generated source files. If
188      * this does not exist, a <code>BuildException</code> will result.</li>
189      * </ul>
190      * </p>
191      *
192      * @throws <code>BuildException</code> - when errors occur in processing the
193      * task.
194      */

195     public void execute() throws BuildException {
196         // See if there is a base source directory specified (sourceDir)
197
if (sourceDir == null) {
198             sourceDir = project.resolveFile(".");
199         }
200
201         // Ensure the destination directory is supplied (destDir)
202
if (destDir == null) {
203             throw new BuildException("The destDir attribute is required, and " +
204                 "should indicate the destination directory for generated " +
205                 "source files.");
206         }
207
208         // Process all the constraints marked for execution
209
for (Enumeration JavaDoc e = constraints.elements(); e.hasMoreElements(); ) {
210             generateFrom((Constraint)e.nextElement());
211         }
212     }
213     
214     /**
215      * <p>
216      * This will return the Java <code>File</code> object representing the
217      * source directory for constraints.
218      * </p>
219      *
220      * @return <code>File</code> - the source directory for constraints.
221      */

222     public File JavaDoc getSourceDir() {
223         return sourceDir;
224     }
225
226     /**
227      * <p>
228      * This sets the source directory to use as a base directory for resolving
229      * specified constraints.
230      * </p>
231      *
232      * @param sourceDir the <code>File</code> representing the source directory.
233      */

234     public void setSourceDir(File JavaDoc sourceDir) {
235         if (!sourceDir.isDirectory()) {
236             throw new IllegalArgumentException JavaDoc("The source directory " +
237                 "must be a valid, existing directory.");
238         }
239         this.sourceDir = sourceDir;
240     }
241
242     /**
243      * <p>
244      * This will return the destination directory in which Java source files
245      * are generated.
246      * </p>
247      *
248      * @return <code>File</code> - the output directory.
249      */

250     public File JavaDoc getDestDir() {
251         return destDir;
252     }
253
254     /**
255      * <p>
256      * This will set the destination directory to use for outputting Java
257      * source files within.
258      * </p>
259      *
260      * @param destDir <code>File</code> object for destination directory.
261      */

262     public void setDestDir(File JavaDoc destDir) {
263         if (!destDir.isDirectory()) {
264             throw new IllegalArgumentException JavaDoc("The destination directory " +
265                 "must be a valid, existing directory.");
266         }
267         this.destDir = destDir;
268     }
269
270     /**
271      * <p>
272      * This will indicate the Java package used for generated source files by
273      * default (if no other package is specified for a specific binding).
274      * </p>
275      *
276      * @return <code>String</code> - the Java package used by default.
277      */

278     public String JavaDoc getDefaultJavaPackage() {
279         return defaultJavaPackage;
280     }
281
282     /**
283      * <p>
284      * This sets the Java package to use for generated source files in the
285      * default case (unless overridden by a specific generation process).
286      * </p>
287      *
288      * @param defaultJavaPackage the Java package for generated classes.
289      */

290     public void setDefaultJavaPackage(String JavaDoc defaultJavaPackage) {
291         this.defaultJavaPackage = defaultJavaPackage;
292     }
293     
294     /**
295      * <p>
296      * This will set whether simple elements or collapsed, in the default
297      * case (when a specific constraint generation does not override it).
298      * </p>
299      *
300      * @param defaultCollapseSimpleElements whether to collapse simple elements.
301      */

302     public void setDefaultCollapseSimpleElements(
303         boolean defaultCollapseSimpleElements ) {
304             
305         this.defaultCollapseSimpleElements = defaultCollapseSimpleElements;
306     }
307
308     /**
309      * <p>
310      * This will create a new Ant <code>Constraint</code>, add it to the list
311      * of Ant constraints, and return the newly created
312      * <code>Constraint</code>.
313      * </p>
314      *
315      * @return <code>Constraint</code> - the created constraint.
316      */

317     public Constraint createConstraint() {
318         Constraint constraint = new Constraint();
319         constraints.addElement(constraint);
320         return constraint;
321     }
322
323     /**
324      * <Please write something about this operation>
325      * @param constraint <Please write something about this parameter>
326      * @exception BuildException <Please write something about why this exception would be thrown>
327      */

328     public void generateFrom(Constraint constraint) throws BuildException {
329         if (constraint.getType().equalsIgnoreCase(CONSTRAINT_TYPE_DTD)) {
330             try {
331                 String JavaDoc[] args = null;
332                 int i = 0;
333
334                 // Determine if a Java package is present
335
if (constraint.getJavaPackage() != null) {
336                     args = new String JavaDoc[6];
337                 } else {
338                     args = new String JavaDoc[5];
339                 }
340
341                 // Constraint to process
342
String JavaDoc filename = sourceDir.getAbsolutePath() + File.separator +
343                     constraint.getConstraintFile().getName();
344                 args[i++] = "-constraints=" + filename;
345                     
346                 // Output directory
347
args[i++] = "-outputDir=" + destDir.getAbsolutePath();
348                 
349                 // Whether or not to ignore ID attributes
350
args[i++] = "-ignoreIDAttributes=" +
351                     constraint.ignoreIDAttributes();
352                 
353                 // Whether or not to collapse simple elements
354
args[i++] = "-collapseSimpleElements=" +
355                     constraint.collapseSimpleElements();
356                 
357                 // Always use the "simple" generator
358
args[i++] = "-generator=simple";
359                 
360                 // The Java Package name to use
361
if (constraint.getJavaPackage() != null) {
362                     args[i++] = "-javaPackage=" + constraint.getJavaPackage();
363                 }
364                 
365                 System.out.println("Generating Java from DTD: " + filename);
366                 System.out.println(" + Output Directory: " +
367                     destDir.getAbsolutePath());
368                 System.out.println(" + Java Package: " +
369                     constraint.getJavaPackage());
370                 if (constraint.collapseSimpleElements()) {
371                     System.out.println(" + Collapsing Simple Elements");
372                 }
373                 if (constraint.ignoreIDAttributes()) {
374                     System.out.println(" + Ignoring ID Attributes");
375                 }
376                 System.out.println("\n");
377
378                 // Invoke the generator with supplied arguments
379
String JavaDoc generatorClassName = "org.enhydra.zeus.util.DTDSourceGenerator";
380                 Class JavaDoc c = null;
381                 Method m = null;
382                 try {
383                     c = Class.forName(generatorClassName);
384                     m = c.getMethod("main", new Class JavaDoc[] { String JavaDoc[].class });
385                 } catch (Exception JavaDoc e) {
386                     e.printStackTrace();
387                     throw new BuildException(e);
388                 }
389                 
390                 if (m != null) {
391                     m.invoke(null, new Object JavaDoc[] { args });
392                 }
393             } catch (Exception JavaDoc e) {
394                 e.printStackTrace();
395                 throw new BuildException(e);
396             }
397         } else {
398             throw new BuildException("The specified constraint type, '" +
399                 constraint.getType() + "', is not currently supported.");
400         }
401     }
402
403     /**
404      * <p>
405      * <code>Constraint</code> is an inner class used to represent a single
406      * constraint element (<code>constraint</code>). It determines all
407      * of the attributes specified on that element.
408      * </p>
409      */

410     public class Constraint {
411         
412         /** The constraint to use for input */
413         private File JavaDoc constraintFile;
414         
415         /** The constraint type */
416         private String JavaDoc type;
417         
418         /** The Java package for the generated source */
419         private String JavaDoc javaPackage;
420         
421         /** Whether or not to ignore ID attributes */
422         private boolean ignoreIDAttributes;
423         
424         /** Whether or not to collapse simpleElements */
425         private boolean collapseSimpleElements;
426         
427         /**
428          * <p>
429          * This constraint sets up default values.
430          * </p>
431          */

432         public Constraint() {
433             javaPackage = "";
434             ignoreIDAttributes = false;
435             collapseSimpleElements = false;
436         }
437         
438         /**
439          * <p>
440          * This will return the Java <code>File</code> object representing the
441          * constraint to use for source code generation.
442          * </p>
443          *
444          * @return <code>File</code> - the constraint to generate code from.
445          */

446         public File JavaDoc getConstraintFile() {
447             return constraintFile;
448         }
449
450         /**
451          * <p>
452          * This will set the file to use as a constraint for source code
453          * generation.
454          * </p>
455          *
456          * @param constraintFile <code>File</code> for XML constraint set.
457          */

458         public void setConstraintFile(File JavaDoc constraintFile) {
459             this.constraintFile = constraintFile;
460         }
461         
462         /**
463          * <p>
464          * This will return the type of constraint being processed.
465          * </p>
466          *
467          * @return <code>String</code> - the constraint type.
468          */

469         public String JavaDoc getType() {
470             return type;
471         }
472
473         /**
474          * <p>
475          * This will set the constraint type of the constraint file supplied.
476          * </p>
477          *
478          * @param type the type of constraint to process.
479          */

480         public void setType(String JavaDoc type) {
481             this.type = type;
482         }
483
484         /**
485          * <p>
486          * This returns the Java package used in generated classes.
487          * </p>
488          *
489          * @return <code>String</code> - the Java package for generated classes.
490          */

491         public String JavaDoc getJavaPackage() {
492             return javaPackage;
493         }
494         
495         /**
496          * <p>
497          * This sets the Java package to use for generated classes.
498          * </p>
499          *
500          * @param javaPackage the package to use for generated classes.
501          */

502         public void setJavaPackage(String JavaDoc javaPackage) {
503             this.javaPackage = javaPackage;
504         }
505         
506         /**
507          * <p>
508          * This indicates whether or not ID attributes are ignored in the
509          * constraint generation and determination of simple elements.
510          * </p>
511          *
512          * @return <code>boolean</code> - whether ID attributes are ignored.
513          */

514         public boolean ignoreIDAttributes() {
515             return ignoreIDAttributes;
516         }
517
518         /**
519          * <p>
520          * This will set whether or not to ignore ID attributes when
521          * determining if an element is "simple".
522          * </p>
523          *
524          * @param ignoreIDAttributes whether or not to ignore ID attributes.
525          */

526         public void setIgnoreIDAttributes(boolean ignoreIDAttributes) {
527             this.ignoreIDAttributes = ignoreIDAttributes;
528         }
529
530         /**
531          * <p>
532          * This will indicate whether or not simple elements are collapsed.
533          * </p>
534          *
535          * @return <code>boolean</code> - whether or not simple elements are
536          * collapsed.
537          */

538         public boolean collapseSimpleElements() {
539             return collapseSimpleElements;
540         }
541
542         /**
543          * <p>
544          * This will set whether or not simple elements are collapsed.
545          * </p>
546          *
547          * @param collapseSimpleElements - whether or not simple elements
548          * are collapsed.
549          */

550         public void setCollapseSimpleElements(boolean collapseSimpleElements ) {
551             this.collapseSimpleElements = collapseSimpleElements;
552         }
553     }
554 }
Popular Tags