1 | /*
|
---|
2 | * Copyright 2001-2004 The Apache Software Foundation
|
---|
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 | */
|
---|
17 |
|
---|
18 | package org.apache.tools.ant.taskdefs.optional.ejb;
|
---|
19 |
|
---|
20 | import java.io.File;
|
---|
21 | import java.io.IOException;
|
---|
22 | import javax.xml.parsers.ParserConfigurationException;
|
---|
23 | import javax.xml.parsers.SAXParser;
|
---|
24 | import javax.xml.parsers.SAXParserFactory;
|
---|
25 | import org.apache.tools.ant.BuildException;
|
---|
26 | import org.apache.tools.ant.Task;
|
---|
27 | import org.apache.tools.ant.types.Path;
|
---|
28 | import org.xml.sax.SAXException;
|
---|
29 |
|
---|
30 | /**
|
---|
31 | * Compiles EJB stubs and skeletons for the iPlanet Application Server.
|
---|
32 | * The EJBs to be processed are specified by the EJB 1.1 standard XML
|
---|
33 | * descriptor, and additional attributes are obtained from the iPlanet Application
|
---|
34 | * Server-specific XML descriptor. Since the XML descriptors can include
|
---|
35 | * multiple EJBs, this is a convenient way of specifying many EJBs in a single
|
---|
36 | * Ant task. The following attributes are allowed:
|
---|
37 | * <ul>
|
---|
38 | * <li><i>ejbdescriptor</i> -- Standard EJB 1.1 XML descriptor (typically
|
---|
39 | * titled "ejb-jar.xml"). This attribute is
|
---|
40 | * required.
|
---|
41 | * <li><i>iasdescriptor</i> -- EJB XML descriptor for iPlanet Application
|
---|
42 | * Server (typically titled "ias-ejb-jar.xml).
|
---|
43 | * This attribute is required.
|
---|
44 | * <li><i>dest</i> -- The is the base directory where the RMI stubs and
|
---|
45 | * skeletons are written. In addition, the class files
|
---|
46 | * for each bean (home interface, remote interface, and
|
---|
47 | * EJB implementation) must be found in this directory.
|
---|
48 | * This attribute is required.
|
---|
49 | * <li><i>classpath</i> -- The classpath used when generating EJB stubs and
|
---|
50 | * skeletons. This is an optional attribute (if
|
---|
51 | * omitted, the classpath specified when Ant was
|
---|
52 | * started will be used). Nested "classpath"
|
---|
53 | * elements may also be used.
|
---|
54 | * <li><i>keepgenerated</i> -- Indicates whether or not the Java source
|
---|
55 | * files which are generated by ejbc will be
|
---|
56 | * saved or automatically deleted. If "yes",
|
---|
57 | * the source files will be retained. This is
|
---|
58 | * an optional attribute (if omitted, it
|
---|
59 | * defaults to "no").
|
---|
60 | * <li><i>debug</i> -- Indicates whether or not the ejbc utility should
|
---|
61 | * log additional debugging statements to the standard
|
---|
62 | * output. If "yes", the additional debugging statements
|
---|
63 | * will be generated (if omitted, it defaults to "no").
|
---|
64 | * <li><i>iashome</i> -- May be used to specify the "home" directory for
|
---|
65 | * this iPlanet Application Server installation. This
|
---|
66 | * is used to find the ejbc utility if it isn't
|
---|
67 | * included in the user's system path. This is an
|
---|
68 | * optional attribute (if specified, it should refer
|
---|
69 | * to the <code>[install-location]/iplanet/ias6/ias
|
---|
70 | * </code> directory). If omitted, the ejbc utility
|
---|
71 | * must be on the user's system path.
|
---|
72 | * </ul>
|
---|
73 | * <p>
|
---|
74 | * For each EJB specified, this task will locate the three classes that comprise
|
---|
75 | * the EJB. If these class files cannot be located in the <code>dest</code>
|
---|
76 | * directory, the task will fail. The task will also attempt to locate the EJB
|
---|
77 | * stubs and skeletons in this directory. If found, the timestamps on the
|
---|
78 | * stubs and skeletons will be checked to ensure they are up to date. Only if
|
---|
79 | * these files cannot be found or if they are out of date will ejbc be called
|
---|
80 | * to generate new stubs and skeletons.
|
---|
81 | *
|
---|
82 | * @see IPlanetEjbc
|
---|
83 | *
|
---|
84 | * @ant.task name="iplanet-ejbc" category="ejb"
|
---|
85 | */
|
---|
86 | public class IPlanetEjbcTask extends Task {
|
---|
87 |
|
---|
88 | /* Attributes set by the Ant build file */
|
---|
89 | private File ejbdescriptor;
|
---|
90 | private File iasdescriptor;
|
---|
91 | private File dest;
|
---|
92 | private Path classpath;
|
---|
93 | private boolean keepgenerated = false;
|
---|
94 | private boolean debug = false;
|
---|
95 | private File iashome;
|
---|
96 |
|
---|
97 | /**
|
---|
98 | * Sets the location of the standard XML EJB descriptor. Typically, this
|
---|
99 | * file is named "ejb-jar.xml".
|
---|
100 | *
|
---|
101 | * @param ejbdescriptor The name and location of the EJB descriptor.
|
---|
102 | */
|
---|
103 | public void setEjbdescriptor(File ejbdescriptor) {
|
---|
104 | this.ejbdescriptor = ejbdescriptor;
|
---|
105 | }
|
---|
106 |
|
---|
107 | /**
|
---|
108 | * Sets the location of the iAS-specific XML EJB descriptor. Typically,
|
---|
109 | * this file is named "ias-ejb-jar.xml".
|
---|
110 | *
|
---|
111 | * @param iasdescriptor The name and location of the iAS-specific EJB
|
---|
112 | * descriptor.
|
---|
113 | */
|
---|
114 | public void setIasdescriptor (File iasdescriptor) {
|
---|
115 | this.iasdescriptor = iasdescriptor;
|
---|
116 | }
|
---|
117 |
|
---|
118 | /**
|
---|
119 | * Sets the destination directory where the EJB source classes must exist
|
---|
120 | * and where the stubs and skeletons will be written. The destination
|
---|
121 | * directory must exist before this task is executed.
|
---|
122 | *
|
---|
123 | * @param dest The directory where the compiled classes will be written.
|
---|
124 | */
|
---|
125 | public void setDest(File dest) {
|
---|
126 | this.dest = dest;
|
---|
127 | }
|
---|
128 |
|
---|
129 | /**
|
---|
130 | * Sets the classpath to be used when compiling the EJB stubs and skeletons.
|
---|
131 | *
|
---|
132 | * @param classpath The classpath to be used.
|
---|
133 | */
|
---|
134 | public void setClasspath(Path classpath) {
|
---|
135 | if (this.classpath == null) {
|
---|
136 | this.classpath = classpath;
|
---|
137 | } else {
|
---|
138 | this.classpath.append(classpath);
|
---|
139 | }
|
---|
140 | }
|
---|
141 |
|
---|
142 | /**
|
---|
143 | * Adds to the classpath used when compiling the EJB stubs and skeletons.
|
---|
144 | */
|
---|
145 | public Path createClasspath() {
|
---|
146 | if (classpath == null) {
|
---|
147 | classpath = new Path(getProject());
|
---|
148 | }
|
---|
149 | return classpath.createPath();
|
---|
150 | }
|
---|
151 |
|
---|
152 | /**
|
---|
153 | * If true, the Java source files which are generated by ejbc will be saved .
|
---|
154 | *
|
---|
155 | * @param keepgenerated A boolean indicating if the Java source files for
|
---|
156 | * the stubs and skeletons should be retained.
|
---|
157 | */
|
---|
158 | public void setKeepgenerated(boolean keepgenerated) {
|
---|
159 | this.keepgenerated = keepgenerated;
|
---|
160 | }
|
---|
161 |
|
---|
162 | /**
|
---|
163 | * If true, debugging output will be generated when ejbc is
|
---|
164 | * executed.
|
---|
165 | *
|
---|
166 | * @param debug A boolean indicating if debugging output should be generated
|
---|
167 | */
|
---|
168 | public void setDebug(boolean debug) {
|
---|
169 | this.debug = debug;
|
---|
170 | }
|
---|
171 |
|
---|
172 | /**
|
---|
173 | * May be used to specify the "home" directory for this iAS installation.
|
---|
174 | * The directory specified should typically be
|
---|
175 | * <code>[install-location]/iplanet/ias6/ias</code>.
|
---|
176 | *
|
---|
177 | * @param iashome The home directory for the user's iAS installation.
|
---|
178 | */
|
---|
179 | public void setIashome(File iashome) {
|
---|
180 | this.iashome = iashome;
|
---|
181 | }
|
---|
182 |
|
---|
183 | /**
|
---|
184 | * Does the work.
|
---|
185 | */
|
---|
186 | public void execute() throws BuildException {
|
---|
187 | checkConfiguration();
|
---|
188 |
|
---|
189 | executeEjbc(getParser());
|
---|
190 | }
|
---|
191 |
|
---|
192 | /**
|
---|
193 | * Verifies that the user selections are valid.
|
---|
194 | *
|
---|
195 | * @throws BuildException If the user selections are invalid.
|
---|
196 | */
|
---|
197 | private void checkConfiguration() throws BuildException {
|
---|
198 |
|
---|
199 | if (ejbdescriptor == null) {
|
---|
200 | String msg = "The standard EJB descriptor must be specified using "
|
---|
201 | + "the \"ejbdescriptor\" attribute.";
|
---|
202 | throw new BuildException(msg, getLocation());
|
---|
203 | }
|
---|
204 | if ((!ejbdescriptor.exists()) || (!ejbdescriptor.isFile())) {
|
---|
205 | String msg = "The standard EJB descriptor (" + ejbdescriptor
|
---|
206 | + ") was not found or isn't a file.";
|
---|
207 | throw new BuildException(msg, getLocation());
|
---|
208 | }
|
---|
209 |
|
---|
210 | if (iasdescriptor == null) {
|
---|
211 | String msg = "The iAS-speific XML descriptor must be specified using"
|
---|
212 | + " the \"iasdescriptor\" attribute.";
|
---|
213 | throw new BuildException(msg, getLocation());
|
---|
214 | }
|
---|
215 | if ((!iasdescriptor.exists()) || (!iasdescriptor.isFile())) {
|
---|
216 | String msg = "The iAS-specific XML descriptor (" + iasdescriptor
|
---|
217 | + ") was not found or isn't a file.";
|
---|
218 | throw new BuildException(msg, getLocation());
|
---|
219 | }
|
---|
220 |
|
---|
221 | if (dest == null) {
|
---|
222 | String msg = "The destination directory must be specified using "
|
---|
223 | + "the \"dest\" attribute.";
|
---|
224 | throw new BuildException(msg, getLocation());
|
---|
225 | }
|
---|
226 | if ((!dest.exists()) || (!dest.isDirectory())) {
|
---|
227 | String msg = "The destination directory (" + dest + ") was not "
|
---|
228 | + "found or isn't a directory.";
|
---|
229 | throw new BuildException(msg, getLocation());
|
---|
230 | }
|
---|
231 |
|
---|
232 | if ((iashome != null) && (!iashome.isDirectory())) {
|
---|
233 | String msg = "If \"iashome\" is specified, it must be a valid "
|
---|
234 | + "directory (it was set to " + iashome + ").";
|
---|
235 | throw new BuildException(msg, getLocation());
|
---|
236 | }
|
---|
237 | }
|
---|
238 |
|
---|
239 | /**
|
---|
240 | * Returns a SAXParser that may be used to process the XML descriptors.
|
---|
241 | *
|
---|
242 | * @return Parser which may be used to process the EJB descriptors.
|
---|
243 | * @throws BuildException If the parser cannot be created or configured.
|
---|
244 | */
|
---|
245 | private SAXParser getParser() throws BuildException {
|
---|
246 |
|
---|
247 | SAXParser saxParser = null;
|
---|
248 | try {
|
---|
249 | SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
|
---|
250 | saxParserFactory.setValidating(true);
|
---|
251 | saxParser = saxParserFactory.newSAXParser();
|
---|
252 | } catch (SAXException e) {
|
---|
253 | String msg = "Unable to create a SAXParser: " + e.getMessage();
|
---|
254 | throw new BuildException(msg, e, getLocation());
|
---|
255 | } catch (ParserConfigurationException e) {
|
---|
256 | String msg = "Unable to create a SAXParser: " + e.getMessage();
|
---|
257 | throw new BuildException(msg, e, getLocation());
|
---|
258 | }
|
---|
259 |
|
---|
260 | return saxParser;
|
---|
261 | }
|
---|
262 |
|
---|
263 | /**
|
---|
264 | * Executes the EJBc utility using the SAXParser provided.
|
---|
265 | *
|
---|
266 | * @param saxParser SAXParser that may be used to process the EJB
|
---|
267 | * descriptors
|
---|
268 | * @throws BuildException If there is an error reading or parsing the XML
|
---|
269 | * descriptors
|
---|
270 | */
|
---|
271 | private void executeEjbc(SAXParser saxParser) throws BuildException {
|
---|
272 | IPlanetEjbc ejbc = new IPlanetEjbc(ejbdescriptor,
|
---|
273 | iasdescriptor,
|
---|
274 | dest,
|
---|
275 | getClasspath().toString(),
|
---|
276 | saxParser);
|
---|
277 | ejbc.setRetainSource(keepgenerated);
|
---|
278 | ejbc.setDebugOutput(debug);
|
---|
279 | if (iashome != null) {
|
---|
280 | ejbc.setIasHomeDir(iashome);
|
---|
281 | }
|
---|
282 |
|
---|
283 | try {
|
---|
284 | ejbc.execute();
|
---|
285 | } catch (IOException e) {
|
---|
286 | String msg = "An IOException occurred while trying to read the XML "
|
---|
287 | + "descriptor file: " + e.getMessage();
|
---|
288 | throw new BuildException(msg, e, getLocation());
|
---|
289 | } catch (SAXException e) {
|
---|
290 | String msg = "A SAXException occurred while trying to read the XML "
|
---|
291 | + "descriptor file: " + e.getMessage();
|
---|
292 | throw new BuildException(msg, e, getLocation());
|
---|
293 | } catch (IPlanetEjbc.EjbcException e) {
|
---|
294 | String msg = "An exception occurred while trying to run the ejbc "
|
---|
295 | + "utility: " + e.getMessage();
|
---|
296 | throw new BuildException(msg, e, getLocation());
|
---|
297 | }
|
---|
298 | }
|
---|
299 |
|
---|
300 | /**
|
---|
301 | * Returns the CLASSPATH to be used when calling EJBc. If no user CLASSPATH
|
---|
302 | * is specified, the System classpath is returned instead.
|
---|
303 | *
|
---|
304 | * @return Path The classpath to be used for EJBc.
|
---|
305 | */
|
---|
306 | private Path getClasspath() {
|
---|
307 | Path cp = null;
|
---|
308 | if (classpath == null) {
|
---|
309 | cp = (new Path(getProject())).concatSystemClasspath("last");
|
---|
310 | } else {
|
---|
311 | cp = classpath.concatSystemClasspath("ignore");
|
---|
312 | }
|
---|
313 |
|
---|
314 | return cp;
|
---|
315 | }
|
---|
316 | }
|
---|