KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tools > ant > taskdefs > optional > ejb > BorlandDeploymentTool


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */

18
19
20 package org.apache.tools.ant.taskdefs.optional.ejb;
21
22
23 import java.io.BufferedReader JavaDoc;
24 import java.io.File JavaDoc;
25 import java.io.IOException JavaDoc;
26 import java.io.InputStream JavaDoc;
27 import java.io.InputStreamReader JavaDoc;
28 import java.io.OutputStream JavaDoc;
29 import java.util.Hashtable JavaDoc;
30 import java.util.Iterator JavaDoc;
31 import java.util.Vector JavaDoc;
32 import org.apache.tools.ant.BuildException;
33 import org.apache.tools.ant.Project;
34 import org.apache.tools.ant.taskdefs.ExecTask;
35 import org.apache.tools.ant.taskdefs.Execute;
36 import org.apache.tools.ant.taskdefs.ExecuteStreamHandler;
37 import org.apache.tools.ant.taskdefs.Java;
38 import org.apache.tools.ant.types.Commandline;
39 import org.apache.tools.ant.types.Path;
40
41
42 /**
43  * BorlandDeploymentTool is dedicated to the Borland Application Server 4.5 and 4.5.1
44  * This task generates and compiles the stubs and skeletons for all ejb described into the
45  * Deployment Descriptor, builds the jar file including the support files and verify
46  * whether the produced jar is valid or not.
47  * The supported options are:
48  * <ul>
49  * <li>debug (boolean) : turn on the debug mode for generation of
50  * stubs and skeletons (default:false)</li>
51  * <li>verify (boolean) : turn on the verification at the end of the jar
52  * production (default:true) </li>
53  * <li>verifyargs (String) : add optional argument to verify command
54  * (see vbj com.inprise.ejb.util.Verify)</li>
55  * <li>basdtd (String) : location of the BAS DTD </li>
56  * <li>generateclient (boolean) : turn on the client jar file generation </li>
57  * <li>version (int) : tell what is the Borland appserver version 4 or 5 </li>
58  * </ul>
59  *
60  *<PRE>
61  *
62  * &lt;ejbjar srcdir=&quot;${build.classes}&quot;
63  * basejarname=&quot;vsmp&quot;
64  * descriptordir=&quot;${rsc.dir}/hrmanager&quot;&gt;
65  * &lt;borland destdir=&quot;tstlib&quot;&gt;
66  * &lt;classpath refid=&quot;classpath&quot; /&gt;
67  * &lt;/borland&gt;
68  * &lt;include name=&quot;**\ejb-jar.xml&quot;/&gt;
69  * &lt;support dir=&quot;${build.classes}&quot;&gt;
70  * &lt;include name=&quot;demo\smp\*.class&quot;/&gt;
71  * &lt;include name=&quot;demo\helper\*.class&quot;/&gt;
72  * &lt;/support&gt;
73  * &lt;/ejbjar&gt;
74  *</PRE>
75  *
76  */

77 public class BorlandDeploymentTool extends GenericDeploymentTool
78                                    implements ExecuteStreamHandler {
79     /** Borland 1.1 ejb id */
80     public static final String JavaDoc PUBLICID_BORLAND_EJB
81     = "-//Inprise Corporation//DTD Enterprise JavaBeans 1.1//EN";
82
83     protected static final String JavaDoc DEFAULT_BAS45_EJB11_DTD_LOCATION
84     = "/com/inprise/j2ee/xml/dtds/ejb-jar.dtd";
85
86     protected static final String JavaDoc DEFAULT_BAS_DTD_LOCATION
87     = "/com/inprise/j2ee/xml/dtds/ejb-inprise.dtd";
88
89     protected static final String JavaDoc BAS_DD = "ejb-inprise.xml";
90     protected static final String JavaDoc BES_DD = "ejb-borland.xml";
91
92
93     /** Java2iiop executable **/
94     protected static final String JavaDoc JAVA2IIOP = "java2iiop";
95
96     /** Verify class */
97     protected static final String JavaDoc VERIFY = "com.inprise.ejb.util.Verify";
98
99     /** Instance variable that stores the suffix for the borland jarfile. */
100     private String JavaDoc jarSuffix = "-ejb.jar";
101
102     /** Instance variable that stores the location of the borland DTD file. */
103     private String JavaDoc borlandDTD;
104
105     /** Instance variable that determines whether the debug mode is on */
106     private boolean java2iiopdebug = false;
107
108     /** store additional param for java2iiop command used to build EJB Stubs */
109     private String JavaDoc java2iioparams = null;
110
111     /** Instance variable that determines whether the client jar file is generated */
112     private boolean generateclient = false;
113
114     /** Borland Enterprise Server = version 5 */
115     static final int BES = 5;
116     /** Borland Application Server or Inprise Application Server = version 4 */
117     static final int BAS = 4;
118
119     /** borland appserver version 4 or 5 */
120     private int version = BAS;
121
122
123     /**
124      * Instance variable that determines whether it is necessary to verify the
125      * produced jar
126      */

127     private boolean verify = true;
128     private String JavaDoc verifyArgs = "";
129
130     private Hashtable JavaDoc genfiles = new Hashtable JavaDoc();
131
132     /**
133      * set the debug mode for java2iiop (default false)
134      * @param debug the setting to use.
135      **/

136     public void setDebug(boolean debug) {
137         this.java2iiopdebug = debug;
138     }
139
140     /**
141      * set the verify mode for the produced jar (default true)
142      * @param verify the setting to use.
143      **/

144     public void setVerify(boolean verify) {
145         this.verify = verify;
146     }
147
148
149     /**
150      * Setter used to store the suffix for the generated borland jar file.
151      * @param inString the string to use as the suffix.
152      */

153     public void setSuffix(String JavaDoc inString) {
154         this.jarSuffix = inString;
155     }
156
157
158     /**
159      * sets some additional args to send to verify command
160      * @param args additional command line parameters
161      */

162     public void setVerifyArgs(String JavaDoc args) {
163         this.verifyArgs = args;
164     }
165
166     /**
167      * Setter used to store the location of the borland DTD. This can be a file on the system
168      * or a resource on the classpath.
169      * @param inString the string to use as the DTD location.
170      */

171     public void setBASdtd(String JavaDoc inString) {
172         this.borlandDTD = inString;
173     }
174
175
176     /**
177      * setter used to store whether the task will include the generate client task.
178      * (see : BorlandGenerateClient task)
179      * @param b if true generate the client task.
180      */

181     public void setGenerateclient(boolean b) {
182         this.generateclient = b;
183     }
184
185     /**
186      * setter used to store the borland appserver version [4 or 5]
187      * @param version app server version 4 or 5
188      */

189     public void setVersion(int version) {
190         this.version = version;
191     }
192
193     /**
194      * If filled, the params are added to the java2iiop command.
195      * (ex: -no_warn_missing_define)
196      * @param params additional params for java2iiop
197      */

198     public void setJava2iiopParams(String JavaDoc params) {
199         this.java2iioparams = params;
200     }
201
202
203     /**
204      * Get the borland descriptor handler.
205      * @param srcDir the source directory.
206      * @return the descriptor.
207      */

208     protected DescriptorHandler getBorlandDescriptorHandler(final File JavaDoc srcDir) {
209         DescriptorHandler handler =
210             new DescriptorHandler(getTask(), srcDir) {
211                     protected void processElement() {
212                         if (currentElement.equals("type-storage")) {
213                             // Get the filename of vendor specific descriptor
214
String JavaDoc fileNameWithMETA = currentText;
215                             //trim the META_INF\ off of the file name
216
String JavaDoc fileName
217                                 = fileNameWithMETA.substring(META_DIR.length(),
218                                     fileNameWithMETA.length());
219                             File JavaDoc descriptorFile = new File JavaDoc(srcDir, fileName);
220
221                             ejbFiles.put(fileNameWithMETA, descriptorFile);
222                         }
223                     }
224                 };
225         handler.registerDTD(PUBLICID_BORLAND_EJB,
226                             borlandDTD == null ? DEFAULT_BAS_DTD_LOCATION : borlandDTD);
227
228         for (Iterator JavaDoc i = getConfig().dtdLocations.iterator(); i.hasNext();) {
229             EjbJar.DTDLocation dtdLocation = (EjbJar.DTDLocation) i.next();
230             handler.registerDTD(dtdLocation.getPublicId(), dtdLocation.getLocation());
231         }
232         return handler;
233     }
234
235     /**
236      * Add any vendor specific files which should be included in the
237      * EJB Jar.
238      * @param ejbFiles the map to add the files to.
239      * @param ddPrefix the prefix to use.
240      */

241     protected void addVendorFiles(Hashtable JavaDoc ejbFiles, String JavaDoc ddPrefix) {
242
243         //choose the right vendor DD
244
if (!(version == BES || version == BAS)) {
245             throw new BuildException("version " + version + " is not supported");
246         }
247
248         String JavaDoc dd = (version == BES ? BES_DD : BAS_DD);
249
250         log("vendor file : " + ddPrefix + dd, Project.MSG_DEBUG);
251
252         File JavaDoc borlandDD = new File JavaDoc(getConfig().descriptorDir, ddPrefix + dd);
253         if (borlandDD.exists()) {
254             log("Borland specific file found " + borlandDD, Project.MSG_VERBOSE);
255             ejbFiles.put(META_DIR + dd , borlandDD);
256         } else {
257             log("Unable to locate borland deployment descriptor. "
258                 + "It was expected to be in "
259                 + borlandDD.getPath(), Project.MSG_WARN);
260             return;
261         }
262     }
263
264     /**
265      * Get the vendor specific name of the Jar that will be output. The modification date
266      * of this jar will be checked against the dependent bean classes.
267      */

268     File JavaDoc getVendorOutputJarFile(String JavaDoc baseName) {
269         return new File JavaDoc(getDestDir(), baseName + jarSuffix);
270     }
271
272     /**
273      * Verify the produced jar file by invoking the Borland verify tool
274      * @param sourceJar java.io.File representing the produced jar file
275      */

276     private void verifyBorlandJar(File JavaDoc sourceJar) {
277         if (version == BAS) {
278             verifyBorlandJarV4(sourceJar);
279             return;
280         }
281         if (version == BES) {
282             verifyBorlandJarV5(sourceJar);
283             return;
284         }
285         log("verify jar skipped because the version is invalid ["
286             + version + "]", Project.MSG_WARN);
287     }
288
289     /**
290      * Verify the produced jar file by invoking the Borland iastool tool
291      * @param sourceJar java.io.File representing the produced jar file
292      */

293     private void verifyBorlandJarV5(File JavaDoc sourceJar) {
294         log("verify BES " + sourceJar, Project.MSG_INFO);
295         try {
296             ExecTask execTask = null;
297             execTask = new ExecTask(getTask());
298             execTask.setDir(new File JavaDoc("."));
299             execTask.setExecutable("iastool");
300             //classpath
301
if (getCombinedClasspath() != null) {
302                 execTask.createArg().setValue("-VBJclasspath");
303                 execTask.createArg().setValue(getCombinedClasspath().toString());
304             }
305
306             if (java2iiopdebug) {
307                 execTask.createArg().setValue("-debug");
308             }
309             execTask.createArg().setValue("-verify");
310             execTask.createArg().setValue("-src");
311             // ejb jar file to verify
312
execTask.createArg().setValue(sourceJar.getPath());
313             log("Calling iastool", Project.MSG_VERBOSE);
314             execTask.execute();
315         } catch (Exception JavaDoc e) {
316             // Have to catch this because of the semantics of calling main()
317
String JavaDoc msg = "Exception while calling generateclient Details: "
318                 + e.toString();
319             throw new BuildException(msg, e);
320         }
321     }
322
323     /**
324      * Verify the produced jar file by invoking the Borland verify tool
325      * @param sourceJar java.io.File representing the produced jar file
326      */

327     private void verifyBorlandJarV4(File JavaDoc sourceJar) {
328         org.apache.tools.ant.taskdefs.Java javaTask = null;
329         log("verify BAS " + sourceJar, Project.MSG_INFO);
330         try {
331             String JavaDoc args = verifyArgs;
332             args += " " + sourceJar.getPath();
333
334             javaTask = new Java(getTask());
335             javaTask.setTaskName("verify");
336             javaTask.setClassname(VERIFY);
337             Commandline.Argument arguments = javaTask.createArg();
338             arguments.setLine(args);
339             Path classpath = getCombinedClasspath();
340             if (classpath != null) {
341                 javaTask.setClasspath(classpath);
342                 javaTask.setFork(true);
343             }
344
345             log("Calling " + VERIFY + " for " + sourceJar.toString(),
346                 Project.MSG_VERBOSE);
347             javaTask.execute();
348         } catch (Exception JavaDoc e) {
349             //TO DO : delete the file if it is not a valid file.
350
String JavaDoc msg = "Exception while calling " + VERIFY + " Details: "
351                 + e.toString();
352             throw new BuildException(msg, e);
353         }
354     }
355
356
357     /**
358      * Generate the client jar corresponding to the jar file passed as parameter
359      * the method uses the BorlandGenerateClient task.
360      * @param sourceJar java.io.File representing the produced jar file
361      */

362     private void generateClient(File JavaDoc sourceJar) {
363         getTask().getProject().addTaskDefinition("internal_bas_generateclient",
364             org.apache.tools.ant.taskdefs.optional.ejb.BorlandGenerateClient.class);
365
366         org.apache.tools.ant.taskdefs.optional.ejb.BorlandGenerateClient gentask = null;
367         log("generate client for " + sourceJar, Project.MSG_INFO);
368         try {
369             Project project = getTask().getProject();
370             gentask
371                 = (BorlandGenerateClient) project.createTask("internal_bas_generateclient");
372             gentask.setEjbjar(sourceJar);
373             gentask.setDebug(java2iiopdebug);
374             Path classpath = getCombinedClasspath();
375             if (classpath != null) {
376                 gentask.setClasspath(classpath);
377             }
378             gentask.setVersion(version);
379             gentask.setTaskName("generate client");
380             gentask.execute();
381         } catch (Exception JavaDoc e) {
382             //TO DO : delete the file if it is not a valid file.
383
String JavaDoc msg = "Exception while calling " + VERIFY + " Details: "
384                 + e.toString();
385             throw new BuildException(msg, e);
386         }
387     }
388
389     /**
390      * Generate stubs & skeleton for each home found into the DD
391      * Add all the generate class file into the ejb files
392      * @param ithomes : iterator on home class
393      */

394     private void buildBorlandStubs(Iterator JavaDoc ithomes) {
395         Execute execTask = null;
396
397         execTask = new Execute(this);
398         Project project = getTask().getProject();
399         execTask.setAntRun(project);
400         execTask.setWorkingDirectory(project.getBaseDir());
401
402         Commandline commandline = new Commandline();
403         commandline.setExecutable(JAVA2IIOP);
404         //debug ?
405
if (java2iiopdebug) {
406             commandline.createArgument().setValue("-VBJdebug");
407         }
408         //set the classpath
409
commandline.createArgument().setValue("-VBJclasspath");
410         commandline.createArgument().setPath(getCombinedClasspath());
411         //list file
412
commandline.createArgument().setValue("-list_files");
413         //no TIE classes
414
commandline.createArgument().setValue("-no_tie");
415
416         if (java2iioparams != null) {
417             log("additional " + java2iioparams + " to java2iiop ", 0);
418             commandline.createArgument().setValue(java2iioparams);
419         }
420
421
422         //root dir
423
commandline.createArgument().setValue("-root_dir");
424         commandline.createArgument().setValue(getConfig().srcDir.getAbsolutePath());
425         //compiling order
426
commandline.createArgument().setValue("-compile");
427         //add the home class
428
while (ithomes.hasNext()) {
429             commandline.createArgument().setValue(ithomes.next().toString());
430         }
431
432         try {
433             log("Calling java2iiop", Project.MSG_VERBOSE);
434             log(commandline.describeCommand(), Project.MSG_DEBUG);
435             execTask.setCommandline(commandline.getCommandline());
436             int result = execTask.execute();
437             if (Execute.isFailure(result)) {
438                 String JavaDoc msg = "Failed executing java2iiop (ret code is "
439                     + result + ")";
440                 throw new BuildException(msg, getTask().getLocation());
441             }
442         } catch (java.io.IOException JavaDoc e) {
443             log("java2iiop exception :" + e.getMessage(), Project.MSG_ERR);
444             throw new BuildException(e, getTask().getLocation());
445         }
446     }
447
448     /**
449      * Method used to encapsulate the writing of the JAR file. Iterates over the
450      * filenames/java.io.Files in the Hashtable stored on the instance variable
451      * ejbFiles.
452      * @param baseName the base name.
453      * @param jarFile the jar file to write to.
454      * @param files the files to write to the jar.
455      * @param publicId the id to use.
456      * @throws BuildException if there is an error.
457      */

458     protected void writeJar(String JavaDoc baseName, File JavaDoc jarFile, Hashtable JavaDoc files, String JavaDoc publicId)
459         throws BuildException {
460         //build the home classes list.
461
Vector JavaDoc homes = new Vector JavaDoc();
462         Iterator JavaDoc it = files.keySet().iterator();
463         while (it.hasNext()) {
464             String JavaDoc clazz = (String JavaDoc) it.next();
465             if (clazz.endsWith("Home.class")) {
466                 //remove .class extension
467
String JavaDoc home = toClass(clazz);
468                 homes.add(home);
469                 log(" Home " + home, Project.MSG_VERBOSE);
470             }
471         }
472
473         buildBorlandStubs(homes.iterator());
474
475         //add the gen files to the collection
476
files.putAll(genfiles);
477
478         super.writeJar(baseName, jarFile, files, publicId);
479
480         if (verify) {
481             verifyBorlandJar(jarFile);
482         }
483
484         if (generateclient) {
485             generateClient(jarFile);
486         }
487     }
488
489     /**
490      * convert a class file name : A/B/C/toto.class
491      * into a class name: A.B.C.toto
492      */

493     private String JavaDoc toClass(String JavaDoc filename) {
494         //remove the .class
495
String JavaDoc classname = filename.substring(0, filename.lastIndexOf(".class"));
496         classname = classname.replace('\\', '.');
497         return classname;
498     }
499
500     /**
501      * convert a file name : A/B/C/toto.java
502      * into a class name: A/B/C/toto.class
503      */

504     private String JavaDoc toClassFile(String JavaDoc filename) {
505         //remove the .class
506
String JavaDoc classfile = filename.substring(0, filename.lastIndexOf(".java"));
507         classfile = classfile + ".class";
508         return classfile;
509     }
510
511     // implementation of org.apache.tools.ant.taskdefs.ExecuteStreamHandler interface
512

513     /** {@inheritDoc}. */
514     public void start() throws IOException JavaDoc { }
515     /** {@inheritDoc}. */
516     public void stop() { }
517     /** {@inheritDoc}. */
518     public void setProcessInputStream(OutputStream JavaDoc param1) throws IOException JavaDoc { }
519
520     /**
521      * Set the output stream of the process.
522      * @param is the input stream.
523      * @throws IOException if there is an error.
524      */

525     public void setProcessOutputStream(InputStream JavaDoc is) throws IOException JavaDoc {
526         try {
527             BufferedReader JavaDoc reader = new BufferedReader JavaDoc(new InputStreamReader JavaDoc(is));
528             String JavaDoc javafile;
529             while ((javafile = reader.readLine()) != null) {
530                 if (javafile.endsWith(".java")) {
531                     String JavaDoc classfile = toClassFile(javafile);
532                     String JavaDoc key = classfile.substring(
533                         getConfig().srcDir.getAbsolutePath().length() + 1);
534                     genfiles.put(key, new File JavaDoc(classfile));
535                 }
536             }
537             reader.close();
538         } catch (Exception JavaDoc e) {
539             String JavaDoc msg = "Exception while parsing java2iiop output. Details: " + e.toString();
540             throw new BuildException(msg, e);
541         }
542     }
543
544     /**
545      * Set the error stream of the process.
546      * @param is the input stream.
547      * @throws IOException if there is an error.
548      */

549     public void setProcessErrorStream(InputStream JavaDoc is) throws IOException JavaDoc {
550         BufferedReader JavaDoc reader = new BufferedReader JavaDoc(new InputStreamReader JavaDoc(is));
551         String JavaDoc s = reader.readLine();
552         if (s != null) {
553             log("[java2iiop] " + s, Project.MSG_ERR);
554         }
555     }
556 }
557
558
Popular Tags