KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jonas > ant > EjbJar


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  * Copyright (c) 2000-2003 The Apache Software Foundation. All rights
5  * reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in
16  * the documentation and/or other materials provided with the
17  * distribution.
18  *
19  * 3. The end-user documentation included with the redistribution, if
20  * any, must include the following acknowlegement:
21  * "This product includes software developed by the
22  * Apache Software Foundation (http://www.apache.org/)."
23  * Alternately, this acknowlegement may appear in the software itself,
24  * if and wherever such third-party acknowlegements normally appear.
25  *
26  * 4. The names "Ant" and "Apache Software
27  * Foundation" must not be used to endorse or promote products derived
28  * from this software without prior written permission. For written
29  * permission, please contact apache@apache.org.
30  *
31  * 5. Products derived from this software may not be called "Apache"
32  * nor may "Apache" appear in their names without prior written
33  * permission of the Apache Group.
34  *
35  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
36  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
37  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
39  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
42  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
44  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
45  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46  * SUCH DAMAGE.
47  * ====================================================================
48  *
49  * This software consists of voluntary contributions made by many
50  * individuals on behalf of the Apache Software Foundation. For more
51  * information on the Apache Software Foundation, please see
52  * <http://www.apache.org/>.
53  */

54
55 package org.objectweb.jonas.ant;
56
57 // Standard java imports
58
import java.io.File JavaDoc;
59 import java.util.ArrayList JavaDoc;
60 import java.util.Iterator JavaDoc;
61 import java.util.List JavaDoc;
62 import javax.xml.parsers.ParserConfigurationException JavaDoc;
63 import javax.xml.parsers.SAXParser JavaDoc;
64 import javax.xml.parsers.SAXParserFactory JavaDoc;
65 import org.apache.tools.ant.BuildException;
66 import org.apache.tools.ant.DirectoryScanner;
67 import org.apache.tools.ant.Project;
68 import org.apache.tools.ant.taskdefs.MatchingTask;
69 import org.apache.tools.ant.types.EnumeratedAttribute;
70 import org.apache.tools.ant.types.FileSet;
71 import org.apache.tools.ant.types.Path;
72 import org.xml.sax.SAXException JavaDoc;
73
74 /**
75  * Provides automated EJB JAR file creation.
76  * <p>
77  * Extends the
78  * MatchingTask class provided in the default ant distribution to provide a
79  * directory scanning EJB jarfile generator.
80  * </p>
81  *
82  * <p>
83  * The task works by taking the deployment descriptors one at a time and
84  * parsing them to locate the names of the classes which should be placed in
85  * the jar. The classnames are translated to java.io.Files by replacing
86  * periods with File.separatorChar and resolving the generated filename as a
87  * relative path under the srcDir attribute. All necessary files are then
88  * assembled into a jarfile. One jarfile is constructed for each deployment
89  * descriptor found.
90  * </p>
91  *
92  * @author <a HREF="mailto:tfennell@sapient.com">Tim Fennell</a>
93  * @author Conor MacNeill
94  * @author <a HREF="mailto:rob@springwellfarms.ca">Rob van Oostrum</a>
95  * */

96 public class EjbJar extends MatchingTask {
97
98     /**
99      * Inner class used to record information about the location of a local DTD
100      */

101     public static class DTDLocation
102         extends org.apache.tools.ant.types.DTDLocation {
103     }
104
105     /**
106      * A class which contains the configuration state of the ejbjar task.
107      * This state is passed to the deployment tools for configuration
108      */

109     static class Config {
110         /**
111          * Stores a handle to the directory under which to search for class
112          * files
113          */

114         public File JavaDoc srcDir;
115
116         /**
117          * Stores a handle to the directory under which to search for
118          * deployment descriptors
119          */

120         public File JavaDoc descriptorDir;
121
122         /** Instance variable that marks the end of the 'basename' */
123         public String JavaDoc baseNameTerminator = "-";
124
125         /** Stores a handle to the destination EJB Jar file */
126         public String JavaDoc baseJarName;
127
128         /**
129          * Instance variable that determines whether to use a package structure
130          * of a flat directory as the destination for the jar files.
131          */

132         public boolean flatDestDir = false;
133
134         /**
135          * The classpath to use when loading classes
136          */

137         public Path classpath;
138
139         /**
140          * A Fileset of support classes
141          */

142         public List JavaDoc supportFileSets = new ArrayList JavaDoc();
143
144         /**
145          * The list of configured DTD locations
146          */

147         public ArrayList JavaDoc dtdLocations = new ArrayList JavaDoc();
148
149         /**
150          * The naming scheme used to determine the generated jar name
151          * from the descriptor information
152          */

153         public NamingScheme namingScheme;
154
155         /**
156          * The Manifest file
157          */

158         public File JavaDoc manifest;
159
160         /**
161          * The dependency analyzer to use to add additional classes to the jar
162          */

163         public String JavaDoc analyzer;
164     }
165
166     /**
167      * An EnumeratedAttribute class for handling different EJB jar naming
168      * schemes
169      */

170     public static class NamingScheme extends EnumeratedAttribute {
171         /**
172          * Naming scheme where generated jar is determined from the ejb-name in
173          * the deployment descripor
174          */

175         public static final String JavaDoc EJB_NAME = "ejb-name";
176
177         /**
178          * Naming scheme where the generated jar name is based on the
179          * name of the directory containing the deployment descriptor
180          */

181         public static final String JavaDoc DIRECTORY = "directory";
182
183         /**
184          * Naming scheme where the generated jar name is based on the name of
185          * the deployment descriptor file
186          */

187         public static final String JavaDoc DESCRIPTOR = "descriptor";
188
189         /**
190          * Naming scheme where the generated jar is named by the basejarname
191          * attribute
192          */

193         public static final String JavaDoc BASEJARNAME = "basejarname";
194
195         /**
196          * Gets the values of the NamingScheme
197          *
198          * @return an array of the values of this attribute class.
199          */

200         public String JavaDoc[] getValues() {
201             return new String JavaDoc[] {EJB_NAME, DIRECTORY, DESCRIPTOR, BASEJARNAME};
202         }
203     }
204
205     /**
206      * CMP versions supported
207      * valid CMP versions are 1.0 and 2.0
208      * @since ant 1.6
209      */

210     public static class CMPVersion extends EnumeratedAttribute {
211         public static final String JavaDoc CMP1_0 = "1.0";
212         public static final String JavaDoc CMP2_0 = "2.0";
213         public String JavaDoc[] getValues() {
214             return new String JavaDoc[]{
215                 CMP1_0,
216                 CMP2_0,
217             };
218         }
219     }
220     /**
221      * The config which is built by this task and used by the various deployment
222      * tools to access the configuration of the ejbjar task
223      */

224     private Config config = new Config();
225
226
227     /**
228      * Stores a handle to the directory to put the Jar files in. This is
229      * only used by the generic deployment descriptor tool which is created
230      * if no other deployment descriptor tools are provided. Normally each
231      * deployment tool will specify the desitination dir itself.
232      */

233     private File JavaDoc destDir;
234
235     /** Instance variable that stores the suffix for the generated jarfile. */
236     private String JavaDoc genericJarSuffix = "-generic.jar";
237
238     /** Instance variable that stores the CMP version for the jboss jarfile. */
239     private String JavaDoc cmpVersion = CMPVersion.CMP1_0;
240
241     /** The list of deployment tools we are going to run. */
242     private ArrayList JavaDoc deploymentTools = new ArrayList JavaDoc();
243
244     /**
245      * Add a deployment tool to the list of deployment tools that will be
246      * processed
247      *
248      * @param deploymentTool a deployment tool instance to which descriptors
249      * will be passed for processing.
250      */

251     protected void addDeploymentTool(EJBDeploymentTool deploymentTool) {
252         deploymentTool.setTask(this);
253         deploymentTools.add(deploymentTool);
254     }
255
256     /**
257      * Adds a deployment tool for JOnAS server.
258      *
259      * @return the deployment tool instance to be configured.
260      */

261     public JonasDeploymentTool createJonas() {
262         log("JOnAS deployment tools", Project.MSG_VERBOSE);
263
264         JonasDeploymentTool tool = new JonasDeploymentTool();
265         addDeploymentTool(tool);
266         return tool;
267     }
268
269     /**
270      * Adds to the classpath used to locate the super classes and
271      * interfaces of the classes that will make up the EJB JAR.
272      *
273      * @return the path to be configured.
274      */

275     public Path createClasspath() {
276         if (config.classpath == null) {
277             config.classpath = new Path(getProject());
278         }
279         return config.classpath.createPath();
280     }
281
282     /**
283      * Create a DTD location record. This stores the location of a DTD. The
284      * DTD is identified by its public Id. The location may either be a file
285      * location or a resource location.
286      *
287      * @return the DTD location object to be configured by Ant
288      */

289     public DTDLocation createDTD() {
290         DTDLocation dtdLocation = new DTDLocation();
291         config.dtdLocations.add(dtdLocation);
292
293         return dtdLocation;
294     }
295
296     /**
297      * Adds a fileset for support elements.
298      *
299      * @return a fileset which can be populated with support files.
300      */

301     public FileSet createSupport() {
302         FileSet supportFileSet = new FileSet();
303         config.supportFileSets.add(supportFileSet);
304         return supportFileSet;
305     }
306
307
308     /**
309      * Set the Manifest file to use when jarring. As of EJB 1.1, manifest
310      * files are no longer used to configure the EJB. However, they still
311      * have a vital importance if the EJB is intended to be packaged in an
312      * EAR file. By adding "Class-Path" settings to a Manifest file, the EJB
313      * can look for classes inside the EAR file itself, allowing for easier
314      * deployment. This is outlined in the J2EE specification, and all J2EE
315      * components are meant to support it.
316      *
317      * @param manifest the manifest to be used in the EJB jar
318      */

319      public void setManifest(File JavaDoc manifest) {
320          config.manifest = manifest;
321      }
322
323     /**
324      * Sets the source directory, which is the directory that
325      * contains the classes that will be added to the EJB jar. Typically
326      * this will include the home and remote interfaces and the bean class.
327      *
328      * @param inDir the source directory.
329      */

330     public void setSrcdir(File JavaDoc inDir) {
331         config.srcDir = inDir;
332     }
333
334     /**
335      * Set the descriptor directory. The descriptor directory contains the
336      * EJB deployment descriptors. These are XML files that declare the
337      * properties of a bean in a particular deployment scenario. Such
338      * properties include, for example, the transactional nature of the bean
339      * and the security access control to the bean's methods.
340      *
341      * @param inDir the directory containing the deployment descriptors.
342      */

343     public void setDescriptordir(File JavaDoc inDir) {
344         config.descriptorDir = inDir;
345     }
346
347     /**
348      * Set the analyzer to use when adding in dependencies to the JAR.
349      *
350      * @param analyzer the name of the dependency analyzer or a class.
351      */

352     public void setDependency(String JavaDoc analyzer) {
353         config.analyzer = analyzer;
354     }
355
356     /**
357      * Set the base name of the EJB JAR that is to be created if it is not
358      * to be determined from the name of the deployment descriptor files.
359      *
360      * @param inValue the basename that will be used when writing the jar
361      * file containing the EJB
362      */

363     public void setBasejarname(String JavaDoc inValue) {
364         config.baseJarName = inValue;
365         if (config.namingScheme == null) {
366             config.namingScheme = new NamingScheme();
367             config.namingScheme.setValue(NamingScheme.BASEJARNAME);
368         } else if (!config.namingScheme.getValue().equals(NamingScheme.BASEJARNAME)) {
369             throw new BuildException("The basejarname attribute is not "
370                 + "compatible with the "
371                 + config.namingScheme.getValue() + " naming scheme");
372         }
373     }
374
375     /**
376      * Set the naming scheme used to determine the name of the generated jars
377      * from the deployment descriptor
378      *
379      * @param namingScheme the naming scheme to be used
380      */

381     public void setNaming(NamingScheme namingScheme) {
382         config.namingScheme = namingScheme;
383         if (!config.namingScheme.getValue().equals(NamingScheme.BASEJARNAME)
384             && config.baseJarName != null) {
385             throw new BuildException("The basejarname attribute is not "
386                 + "compatible with the "
387                 + config.namingScheme.getValue() + " naming scheme");
388         }
389     }
390
391     /**
392      * Gets the destination directory.
393      *
394      * @return destination directory
395      * @since ant 1.6
396      */

397     public File JavaDoc getDestdir() {
398         return this.destDir;
399     }
400
401     /**
402      * Set the destination directory. The EJB jar files will be written into
403      * this directory. The jar files that exist in this directory are also
404      * used when determining if the contents of the jar file have changed.
405      * Note that this parameter is only used if no deployment tools are
406      * specified. Typically each deployment tool will specify its own
407      * destination directory.
408      *
409      * @param inDir the destination directory in which to generate jars
410      */

411     public void setDestdir(File JavaDoc inDir) {
412         this.destDir = inDir;
413     }
414
415     /**
416      * Gets the CMP version.
417      *
418      * @return CMP version
419      * @since ant 1.6
420      */

421     public String JavaDoc getCmpversion() {
422         return this.cmpVersion;
423     }
424
425     /**
426      * Sets the CMP version.
427      *
428      * @param version CMP version.
429      * Must be either <code>1.0</code> or <code>2.0</code>.<br/>
430      * Default is <code>1.0</code>.<br/>
431      * Initially, only the JBoss implementation does something specific for CMP 2.0.<br/>
432      * @since ant 1.6
433      */

434     public void setCmpversion(CMPVersion version) {
435         this.cmpVersion = version.getValue();
436     }
437
438     /**
439      * Set the classpath to use when resolving classes for inclusion in the jar.
440      *
441      * @param classpath the classpath to use.
442      */

443     public void setClasspath(Path classpath) {
444         config.classpath = classpath;
445     }
446
447     /**
448      * Controls whether the
449      * destination JARs are written out in the destination directory with
450      * the same hierarchical structure from which the deployment descriptors
451      * have been read. If this is set to true the generated EJB jars are
452      * written into the root of the destination directory, otherwise they
453      * are written out in the same relative position as the deployment
454      * descriptors in the descriptor directory.
455      *
456      * @param inValue the new value of the flatdestdir flag.
457      */

458     public void setFlatdestdir(boolean inValue) {
459         config.flatDestDir = inValue;
460     }
461
462     /**
463      * Set the suffix for the generated jar file. When generic jars are
464      * generated, they have a suffix which is appended to the the bean name
465      * to create the name of the jar file. Note that this suffix includes
466      * the extension fo te jar file and should therefore end with an
467      * appropriate extension such as .jar or .ear
468      *
469      * @param inString the string to use as the suffix.
470      */

471     public void setGenericjarsuffix(String JavaDoc inString) {
472         this.genericJarSuffix = inString;
473     }
474
475     /**
476      * The string which terminates the bean name.
477      * The convention used by this task is
478      * that bean descriptors are named as the BeanName with some suffix. The
479      * baseNameTerminator string separates the bean name and the suffix and
480      * is used to determine the bean name.
481      *
482      * @param inValue a string which marks the end of the basename.
483      */

484     public void setBasenameterminator(String JavaDoc inValue) {
485         config.baseNameTerminator = inValue;
486     }
487
488     /**
489      * Validate the config that has been configured from the build file
490      *
491      * @throws BuildException if the config is not valid
492      */

493     private void validateConfig() throws BuildException {
494         if (config.srcDir == null) {
495             throw new BuildException("The srcDir attribute must be specified");
496         }
497
498         if (config.descriptorDir == null) {
499             config.descriptorDir = config.srcDir;
500         }
501
502         if (config.namingScheme == null) {
503             config.namingScheme = new NamingScheme();
504             config.namingScheme.setValue(NamingScheme.DESCRIPTOR);
505         } else if (config.namingScheme.getValue().equals(NamingScheme.BASEJARNAME)
506                     && config.baseJarName == null) {
507             throw new BuildException("The basejarname attribute must "
508                 + "be specified with the basejarname naming scheme");
509         }
510     }
511
512     /**
513      * Invoked by Ant after the task is prepared, when it is ready to execute
514      * this task.
515      *
516      * This will configure all of the nested deployment tools to allow them to
517      * process the jar. If no deployment tools have been configured a generic
518      * tool is created to handle the jar.
519      *
520      * A parser is configured and then each descriptor found is passed to all
521      * the deployment tool elements for processing.
522      *
523      * @exception BuildException thrown whenever a problem is
524      * encountered that cannot be recovered from, to signal to ant
525      * that a major problem occurred within this task.
526      */

527     public void execute() throws BuildException {
528         validateConfig();
529
530         if (deploymentTools.size() == 0) {
531             GenericDeploymentTool genericTool = new GenericDeploymentTool();
532             genericTool.setTask(this);
533             genericTool.setDestdir(destDir);
534             genericTool.setGenericJarSuffix(genericJarSuffix);
535             deploymentTools.add(genericTool);
536         }
537
538         for (Iterator JavaDoc i = deploymentTools.iterator(); i.hasNext();) {
539             EJBDeploymentTool tool = (EJBDeploymentTool) i.next();
540             tool.configure(config);
541             tool.validateConfigured();
542         }
543
544         try {
545             // Create the parser using whatever parser the system dictates
546
SAXParserFactory JavaDoc saxParserFactory = SAXParserFactory.newInstance();
547             saxParserFactory.setValidating(true);
548             saxParserFactory.setNamespaceAware(true);
549             SAXParser JavaDoc saxParser = saxParserFactory.newSAXParser();
550
551
552             DirectoryScanner ds = getDirectoryScanner(config.descriptorDir);
553             ds.scan();
554             String JavaDoc[] files = ds.getIncludedFiles();
555
556             log(files.length + " deployment descriptors located.",
557                 Project.MSG_VERBOSE);
558
559             // Loop through the files. Each file represents one deployment
560
// descriptor, and hence one bean in our model.
561
for (int index = 0; index < files.length; ++index) {
562                 // process the deployment descriptor in each tool
563
for (Iterator JavaDoc i = deploymentTools.iterator(); i.hasNext();) {
564                     EJBDeploymentTool tool = (EJBDeploymentTool) i.next();
565                     tool.processDescriptor(files[index], saxParser);
566                 }
567             }
568         } catch (SAXException JavaDoc se) {
569             String JavaDoc msg = "SAXException while creating parser."
570                 + " Details: "
571                 + se.getMessage();
572             throw new BuildException(msg, se);
573         } catch (ParserConfigurationException JavaDoc pce) {
574             String JavaDoc msg = "ParserConfigurationException while creating parser. "
575                        + "Details: " + pce.getMessage();
576             throw new BuildException(msg, pce);
577         }
578     } // end of execute()
579

580 }
581
582
583
584
585
586
587
588
Popular Tags