KickJava   Java API By Example, From Geeks To Geeks.

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


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 package org.apache.tools.ant.taskdefs.optional.ejb;
19
20 import java.io.File JavaDoc;
21 import java.io.FileOutputStream JavaDoc;
22 import java.io.IOException JavaDoc;
23 import java.io.InputStream JavaDoc;
24 import java.util.Enumeration JavaDoc;
25 import java.util.Hashtable JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.jar.JarEntry JavaDoc;
28 import java.util.jar.JarFile JavaDoc;
29 import java.util.jar.JarOutputStream JavaDoc;
30 import org.apache.tools.ant.BuildException;
31 import org.apache.tools.ant.Project;
32 import org.apache.tools.ant.taskdefs.Java;
33 import org.apache.tools.ant.types.Environment;
34 import org.apache.tools.ant.types.Path;
35 import org.apache.tools.ant.util.FileUtils;
36
37 /**
38  * Websphere deployment tool that augments the ejbjar task.
39  * Searches for the websphere specific deployment descriptors and
40  * adds them to the final ejb jar file. Websphere has two specific descriptors for session
41  * beans:
42  * <ul>
43  * <li>ibm-ejb-jar-bnd.xmi</li>
44  * <li>ibm-ejb-jar-ext.xmi</li>
45  * </ul>
46  * and another two for container managed entity beans:
47  * <ul>
48  * <li>Map.mapxmi</li>
49  * <li>Schema.dbxmi</li>
50  * </ul>
51  * In terms of WebSphere, the generation of container code and stubs is
52  * called <code>deployment</code>. This step can be performed by the websphere
53  * element as part of the jar generation process. If the switch
54  * <code>ejbdeploy</code> is on, the ejbdeploy tool from the websphere toolset
55  * is called for every ejb-jar. Unfortunately, this step only works, if you
56  * use the ibm jdk. Otherwise, the rmic (called by ejbdeploy) throws a
57  * ClassFormatError. Be sure to switch ejbdeploy off, if run ant with
58  * sun jdk.
59  *
60  */

61 public class WebsphereDeploymentTool extends GenericDeploymentTool {
62
63     /** ID for ejb 1.1 */
64     public static final String JavaDoc PUBLICID_EJB11
65          = "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN";
66     /** ID for ejb 2.0 */
67     public static final String JavaDoc PUBLICID_EJB20
68          = "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN";
69     /** Schema directory */
70     protected static final String JavaDoc SCHEMA_DIR = "Schema/";
71
72     protected static final String JavaDoc WAS_EXT = "ibm-ejb-jar-ext.xmi";
73     protected static final String JavaDoc WAS_BND = "ibm-ejb-jar-bnd.xmi";
74     protected static final String JavaDoc WAS_CMP_MAP = "Map.mapxmi";
75     protected static final String JavaDoc WAS_CMP_SCHEMA = "Schema.dbxmi";
76
77     private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
78
79     /** Instance variable that stores the suffix for the websphere jarfile. */
80     private String JavaDoc jarSuffix = ".jar";
81
82     /** Instance variable that stores the location of the ejb 1.1 DTD file. */
83     private String JavaDoc ejb11DTD;
84
85     /** Instance variable that determines whether generic ejb jars are kept. */
86
87     private boolean keepGeneric = false;
88
89     private boolean alwaysRebuild = true;
90
91     private boolean ejbdeploy = true;
92
93     /** Indicates if the old CMP location convention is to be used. */
94     private boolean newCMP = false;
95
96     /** The classpath to the websphere classes. */
97     private Path wasClasspath = null;
98
99     /** The DB Vendor name, the EJB is persisted against */
100     private String JavaDoc dbVendor;
101
102     /** The name of the database to create. (For top-down mapping only) */
103     private String JavaDoc dbName;
104
105     /** The name of the schema to create. (For top-down mappings only) */
106     private String JavaDoc dbSchema;
107
108     /** true - Only generate the deployment code, do not run RMIC or Javac */
109     private boolean codegen;
110
111     /** true - Only output error messages, suppress informational messages */
112     private boolean quiet = true;
113
114     /** true - Disable the validation steps */
115     private boolean novalidate;
116
117     /** true - Disable warning and informational messages */
118     private boolean nowarn;
119
120     /** true - Disable informational messages */
121     private boolean noinform;
122
123     /** true - Enable internal tracing */
124     private boolean trace;
125
126     /** Additional options for RMIC */
127     private String JavaDoc rmicOptions;
128
129     /** true- Use the WebSphere 3.5 compatible mapping rules */
130     private boolean use35MappingRules;
131
132     /** the scratchdir for the ejbdeploy operation */
133     private String JavaDoc tempdir = "_ejbdeploy_temp";
134
135     /** the home directory for websphere */
136     private File JavaDoc websphereHome;
137
138     /**
139      * Get the classpath to the websphere classpaths.
140      * @return the websphere classpath.
141      */

142     public Path createWASClasspath() {
143         if (wasClasspath == null) {
144             wasClasspath = new Path(getTask().getProject());
145         }
146         return wasClasspath.createPath();
147     }
148
149
150     /**
151      * Set the websphere classpath.
152      * @param wasClasspath the websphere classpath.
153      */

154     public void setWASClasspath(Path wasClasspath) {
155         this.wasClasspath = wasClasspath;
156     }
157
158
159     /** Sets the DB Vendor for the Entity Bean mapping ; optional.
160      * <p>
161      * Valid options can be obtained by running the following command:
162      * <code>
163      * &lt;WAS_HOME&gt;/bin/EJBDeploy.[sh/bat] -help
164      * </code>
165      * </p>
166      * <p>
167      * This is also used to determine the name of the Map.mapxmi and
168      * Schema.dbxmi files, for example Account-DB2UDB_V81-Map.mapxmi
169      * and Account-DB2UDB_V81-Schema.dbxmi.
170      * </p>
171      *
172      * @param dbvendor database vendor type
173      */

174     public void setDbvendor(String JavaDoc dbvendor) {
175         this.dbVendor = dbvendor;
176     }
177
178
179     /**
180      * Sets the name of the Database to create; optional.
181      *
182      * @param dbName name of the database
183      */

184     public void setDbname(String JavaDoc dbName) {
185         this.dbName = dbName;
186     }
187
188
189     /**
190      * Sets the name of the schema to create; optional.
191      *
192      * @param dbSchema name of the schema
193      */

194     public void setDbschema(String JavaDoc dbSchema) {
195         this.dbSchema = dbSchema;
196     }
197
198
199     /**
200      * Flag, default false, to only generate the deployment
201      * code, do not run RMIC or Javac
202      *
203      * @param codegen option
204      */

205     public void setCodegen(boolean codegen) {
206         this.codegen = codegen;
207     }
208
209
210     /**
211      * Flag, default true, to only output error messages.
212      *
213      * @param quiet option
214      */

215     public void setQuiet(boolean quiet) {
216         this.quiet = quiet;
217     }
218
219
220     /**
221      * Flag to disable the validation steps; optional, default false.
222      *
223      * @param novalidate option
224      */

225     public void setNovalidate(boolean novalidate) {
226         this.novalidate = novalidate;
227     }
228
229
230     /**
231      * Flag to disable warning and informational messages; optional, default false.
232      *
233      * @param nowarn option
234      */

235     public void setNowarn(boolean nowarn) {
236         this.nowarn = nowarn;
237     }
238
239
240     /**
241      * Flag to disable informational messages; optional, default false.
242      *
243      * @param noinform if true disables informational messages
244      */

245     public void setNoinform(boolean noinform) {
246         this.noinform = noinform;
247     }
248
249
250     /**
251      * Flag to enable internal tracing when set, optional, default false.
252      *
253      * @param trace a <code>boolean</code> vaule.
254      */

255     public void setTrace(boolean trace) {
256         this.trace = trace;
257     }
258
259     /**
260      * Set the rmic options.
261      *
262      * @param options the options to use.
263      */

264     public void setRmicoptions(String JavaDoc options) {
265         this.rmicOptions = options;
266     }
267
268     /**
269      * Flag to use the WebSphere 3.5 compatible mapping rules ; optional, default false.
270      *
271      * @param attr a <code>boolean</code> value.
272      */

273     public void setUse35(boolean attr) {
274         use35MappingRules = attr;
275     }
276
277
278     /**
279      * Set the rebuild flag to false to only update changes in the jar rather
280      * than rerunning ejbdeploy; optional, default true.
281      * @param rebuild a <code>boolean</code> value.
282      */

283     public void setRebuild(boolean rebuild) {
284         this.alwaysRebuild = rebuild;
285     }
286
287
288     /**
289      * String value appended to the basename of the deployment
290      * descriptor to create the filename of the WebLogic EJB
291      * jar file. Optional, default '.jar'.
292      * @param inString the string to use as the suffix.
293      */

294     public void setSuffix(String JavaDoc inString) {
295         this.jarSuffix = inString;
296     }
297
298
299     /**
300      * This controls whether the generic file used as input to
301      * ejbdeploy is retained; optional, default false.
302      * @param inValue either 'true' or 'false'.
303      */

304     public void setKeepgeneric(boolean inValue) {
305         this.keepGeneric = inValue;
306     }
307
308
309     /**
310      * Decide, wether ejbdeploy should be called or not;
311      * optional, default true.
312      *
313      * @param ejbdeploy a <code>boolean</code> value.
314      */

315     public void setEjbdeploy(boolean ejbdeploy) {
316         this.ejbdeploy = ejbdeploy;
317     }
318
319
320     /**
321      * Setter used to store the location of the Sun's Generic EJB DTD. This
322      * can be a file on the system or a resource on the classpath.
323      *
324      * @param inString the string to use as the DTD location.
325      */

326     public void setEJBdtd(String JavaDoc inString) {
327         this.ejb11DTD = inString;
328     }
329
330
331     /**
332      * Set the value of the oldCMP scheme. This is an antonym for newCMP
333      * @ant.attribute ignore="true"
334      * @param oldCMP a <code>boolean</code> value.
335      */

336     public void setOldCMP(boolean oldCMP) {
337         this.newCMP = !oldCMP;
338     }
339
340
341     /**
342      * Set the value of the newCMP scheme. The old CMP scheme locates the
343      * websphere CMP descriptor based on the naming convention where the
344      * websphere CMP file is expected to be named with the bean name as the
345      * prefix. Under this scheme the name of the CMP descriptor does not match
346      * the name actually used in the main websphere EJB descriptor. Also,
347      * descriptors which contain multiple CMP references could not be used.
348      * @param newCMP a <code>boolean</code> value.
349      */

350     public void setNewCMP(boolean newCMP) {
351         this.newCMP = newCMP;
352     }
353
354
355     /**
356      * The directory, where ejbdeploy will write temporary files;
357      * optional, defaults to '_ejbdeploy_temp'.
358      * @param tempdir the directory name to use.
359      */

360     public void setTempdir(String JavaDoc tempdir) {
361         this.tempdir = tempdir;
362     }
363
364
365     /** {@inheritDoc}. */
366     protected DescriptorHandler getDescriptorHandler(File JavaDoc srcDir) {
367         DescriptorHandler handler = new DescriptorHandler(getTask(), srcDir);
368         // register all the DTDs, both the ones that are known and
369
// any supplied by the user
370
handler.registerDTD(PUBLICID_EJB11, ejb11DTD);
371
372         for (Iterator JavaDoc i = getConfig().dtdLocations.iterator(); i.hasNext();) {
373             EjbJar.DTDLocation dtdLocation = (EjbJar.DTDLocation) i.next();
374
375             handler.registerDTD(dtdLocation.getPublicId(), dtdLocation.getLocation());
376         }
377
378         return handler;
379     }
380
381
382     /**
383      * Get a description handler.
384      * @param srcDir the source directory.
385      * @return the handler.
386      */

387     protected DescriptorHandler getWebsphereDescriptorHandler(final File JavaDoc srcDir) {
388         DescriptorHandler handler =
389             new DescriptorHandler(getTask(), srcDir) {
390                 protected void processElement() {
391                 }
392             };
393
394         for (Iterator JavaDoc i = getConfig().dtdLocations.iterator(); i.hasNext();) {
395             EjbJar.DTDLocation dtdLocation = (EjbJar.DTDLocation) i.next();
396
397             handler.registerDTD(dtdLocation.getPublicId(), dtdLocation.getLocation());
398         }
399         return handler;
400     }
401
402
403     /**
404      * Add any vendor specific files which should be included in the EJB Jar.
405      * @param ejbFiles a hashtable entryname -> file.
406      * @param baseName a prefix to use.
407      */

408     protected void addVendorFiles(Hashtable JavaDoc ejbFiles, String JavaDoc baseName) {
409
410         String JavaDoc ddPrefix = (usingBaseJarName() ? "" : baseName);
411         String JavaDoc dbPrefix = (dbVendor == null) ? "" : dbVendor + "-";
412
413         // Get the Extensions document
414
File JavaDoc websphereEXT = new File JavaDoc(getConfig().descriptorDir, ddPrefix + WAS_EXT);
415
416         if (websphereEXT.exists()) {
417             ejbFiles.put(META_DIR + WAS_EXT,
418                 websphereEXT);
419         } else {
420             log("Unable to locate websphere extensions. "
421                 + "It was expected to be in "
422                 + websphereEXT.getPath(), Project.MSG_VERBOSE);
423         }
424
425         File JavaDoc websphereBND = new File JavaDoc(getConfig().descriptorDir, ddPrefix + WAS_BND);
426
427         if (websphereBND.exists()) {
428             ejbFiles.put(META_DIR + WAS_BND,
429                 websphereBND);
430         } else {
431             log("Unable to locate websphere bindings. "
432                 + "It was expected to be in "
433                 + websphereBND.getPath(), Project.MSG_VERBOSE);
434         }
435
436         if (!newCMP) {
437             log("The old method for locating CMP files has been DEPRECATED.",
438                 Project.MSG_VERBOSE);
439             log("Please adjust your websphere descriptor and set "
440                 + "newCMP=\"true\" to use the new CMP descriptor "
441                 + "inclusion mechanism. ", Project.MSG_VERBOSE);
442         } else {
443             // We attempt to put in the MAP and Schema files of CMP beans
444
try {
445                 // Add the Map file
446
File JavaDoc websphereMAP = new File JavaDoc(getConfig().descriptorDir,
447                     ddPrefix + dbPrefix + WAS_CMP_MAP);
448
449                 if (websphereMAP.exists()) {
450                     ejbFiles.put(META_DIR + WAS_CMP_MAP,
451                         websphereMAP);
452                 } else {
453                     log("Unable to locate the websphere Map: "
454                         + websphereMAP.getPath(), Project.MSG_VERBOSE);
455                 }
456
457                 File JavaDoc websphereSchema = new File JavaDoc(getConfig().descriptorDir,
458                     ddPrefix + dbPrefix + WAS_CMP_SCHEMA);
459
460                 if (websphereSchema.exists()) {
461                     ejbFiles.put(META_DIR + SCHEMA_DIR + WAS_CMP_SCHEMA,
462                         websphereSchema);
463                 } else {
464                     log("Unable to locate the websphere Schema: "
465                         + websphereSchema.getPath(), Project.MSG_VERBOSE);
466                 }
467                 // Theres nothing else to see here...keep moving sonny
468
} catch (Exception JavaDoc e) {
469                 String JavaDoc msg = "Exception while adding Vendor specific files: "
470                     + e.toString();
471
472                 throw new BuildException(msg, e);
473             }
474         }
475     }
476
477
478     /**
479      * Get the vendor specific name of the Jar that will be output. The
480      * modification date of this jar will be checked against the dependent
481      * bean classes.
482      */

483     File JavaDoc getVendorOutputJarFile(String JavaDoc baseName) {
484         return new File JavaDoc(getDestDir(), baseName + jarSuffix);
485     }
486
487
488     /**
489      * Gets the options for the EJB Deploy operation
490      *
491      * @return String
492      */

493     protected String JavaDoc getOptions() {
494         // Set the options
495
StringBuffer JavaDoc options = new StringBuffer JavaDoc();
496
497         if (dbVendor != null) {
498             options.append(" -dbvendor ").append(dbVendor);
499         }
500         if (dbName != null) {
501             options.append(" -dbname \"").append(dbName).append("\"");
502         }
503
504         if (dbSchema != null) {
505             options.append(" -dbschema \"").append(dbSchema).append("\"");
506         }
507
508         if (codegen) {
509             options.append(" -codegen");
510         }
511
512         if (quiet) {
513             options.append(" -quiet");
514         }
515
516         if (novalidate) {
517             options.append(" -novalidate");
518         }
519
520         if (nowarn) {
521             options.append(" -nowarn");
522         }
523
524         if (noinform) {
525             options.append(" -noinform");
526         }
527
528         if (trace) {
529             options.append(" -trace");
530         }
531
532         if (use35MappingRules) {
533             options.append(" -35");
534         }
535
536         if (rmicOptions != null) {
537             options.append(" -rmic \"").append(rmicOptions).append("\"");
538         }
539
540         return options.toString();
541     }
542
543
544     /**
545      * Helper method invoked by execute() for each websphere jar to be built.
546      * Encapsulates the logic of constructing a java task for calling
547      * websphere.ejbdeploy and executing it.
548      *
549      * @param sourceJar java.io.File representing the source (EJB1.1) jarfile.
550      * @param destJar java.io.File representing the destination, websphere
551      * jarfile.
552      */

553     private void buildWebsphereJar(File JavaDoc sourceJar, File JavaDoc destJar) {
554         try {
555             if (ejbdeploy) {
556                 Java javaTask = new Java(getTask());
557                 // Set the JvmArgs
558
javaTask.createJvmarg().setValue("-Xms64m");
559                 javaTask.createJvmarg().setValue("-Xmx128m");
560
561                 // Set the Environment variable
562
Environment.Variable var = new Environment.Variable();
563
564                 var.setKey("websphere.lib.dir");
565                 File JavaDoc libdir = new File JavaDoc(websphereHome, "lib");
566                 var.setValue(libdir.getAbsolutePath());
567                 javaTask.addSysproperty(var);
568
569                 // Set the working directory
570
javaTask.setDir(websphereHome);
571
572                 // Set the Java class name
573
javaTask.setTaskName("ejbdeploy");
574                 javaTask.setClassname("com.ibm.etools.ejbdeploy.EJBDeploy");
575
576                 javaTask.createArg().setValue(sourceJar.getPath());
577                 javaTask.createArg().setValue(tempdir);
578                 javaTask.createArg().setValue(destJar.getPath());
579                 javaTask.createArg().setLine(getOptions());
580                 if (getCombinedClasspath() != null
581                     && getCombinedClasspath().toString().length() > 0) {
582                     javaTask.createArg().setValue("-cp");
583                     javaTask.createArg().setValue(getCombinedClasspath().toString());
584                 }
585
586                 Path classpath = wasClasspath;
587
588                 if (classpath == null) {
589                     classpath = getCombinedClasspath();
590                 }
591
592                 if (classpath != null) {
593                     javaTask.setClasspath(classpath);
594                     javaTask.setFork(true);
595                 } else {
596                     javaTask.setFork(true);
597                 }
598
599                 log("Calling websphere.ejbdeploy for " + sourceJar.toString(),
600                     Project.MSG_VERBOSE);
601
602                 javaTask.execute();
603             }
604         } catch (Exception JavaDoc e) {
605             // Have to catch this because of the semantics of calling main()
606
String JavaDoc msg = "Exception while calling ejbdeploy. Details: " + e.toString();
607
608             throw new BuildException(msg, e);
609         }
610     }
611
612     /** {@inheritDoc}. */
613     protected void writeJar(String JavaDoc baseName, File JavaDoc jarFile, Hashtable JavaDoc files, String JavaDoc publicId)
614          throws BuildException {
615         if (ejbdeploy) {
616             // create the -generic.jar, if required
617
File JavaDoc genericJarFile = super.getVendorOutputJarFile(baseName);
618
619             super.writeJar(baseName, genericJarFile, files, publicId);
620
621             // create the output .jar, if required
622
if (alwaysRebuild || isRebuildRequired(genericJarFile, jarFile)) {
623                 buildWebsphereJar(genericJarFile, jarFile);
624             }
625             if (!keepGeneric) {
626                 log("deleting generic jar " + genericJarFile.toString(),
627                     Project.MSG_VERBOSE);
628                 genericJarFile.delete();
629             }
630         } else {
631             // create the "undeployed" output .jar, if required
632
super.writeJar(baseName, jarFile, files, publicId);
633         }
634     }
635
636
637     /**
638      * Called to validate that the tool parameters have been configured.
639      * @throws BuildException if there is an error.
640      */

641     public void validateConfigured() throws BuildException {
642         super.validateConfigured();
643         if (ejbdeploy) {
644             String JavaDoc home = getTask().getProject().getProperty("websphere.home");
645             if (home == null) {
646                 throw new BuildException("The 'websphere.home' property must "
647                     + "be set when 'ejbdeploy=true'");
648             }
649             websphereHome = getTask().getProject().resolveFile(home);
650         }
651     }
652
653
654     /**
655      * Helper method to check to see if a websphere EBJ1.1 jar needs to be
656      * rebuilt using ejbdeploy. Called from writeJar it sees if the "Bean"
657      * classes are the only thing that needs to be updated and either updates
658      * the Jar with the Bean classfile or returns true, saying that the whole
659      * websphere jar needs to be regened with ejbdeploy. This allows faster
660      * build times for working developers. <p>
661      *
662      * The way websphere ejbdeploy works is it creates wrappers for the
663      * publicly defined methods as they are exposed in the remote interface.
664      * If the actual bean changes without changing the the method signatures
665      * then only the bean classfile needs to be updated and the rest of the
666      * websphere jar file can remain the same. If the Interfaces, ie. the
667      * method signatures change or if the xml deployment descriptors changed,
668      * the whole jar needs to be rebuilt with ejbdeploy. This is not strictly
669      * true for the xml files. If the JNDI name changes then the jar doesnt
670      * have to be rebuild, but if the resources references change then it
671      * does. At this point the websphere jar gets rebuilt if the xml files
672      * change at all.
673      *
674      * @param genericJarFile java.io.File The generic jar file.
675      * @param websphereJarFile java.io.File The websphere jar file to check to
676      * see if it needs to be rebuilt.
677      * @return true if a rebuild is required.
678      */

679     protected boolean isRebuildRequired(File JavaDoc genericJarFile, File JavaDoc websphereJarFile) {
680         boolean rebuild = false;
681
682         JarFile JavaDoc genericJar = null;
683         JarFile JavaDoc wasJar = null;
684         File JavaDoc newwasJarFile = null;
685         JarOutputStream JavaDoc newJarStream = null;
686
687         try {
688             log("Checking if websphere Jar needs to be rebuilt for jar "
689                 + websphereJarFile.getName(), Project.MSG_VERBOSE);
690             // Only go forward if the generic and the websphere file both exist
691
if (genericJarFile.exists() && genericJarFile.isFile()
692                  && websphereJarFile.exists() && websphereJarFile.isFile()) {
693                 //open jar files
694
genericJar = new JarFile JavaDoc(genericJarFile);
695                 wasJar = new JarFile JavaDoc(websphereJarFile);
696
697                 Hashtable JavaDoc genericEntries = new Hashtable JavaDoc();
698                 Hashtable JavaDoc wasEntries = new Hashtable JavaDoc();
699                 Hashtable JavaDoc replaceEntries = new Hashtable JavaDoc();
700
701                 //get the list of generic jar entries
702
for (Enumeration JavaDoc e = genericJar.entries(); e.hasMoreElements();) {
703                     JarEntry JavaDoc je = (JarEntry JavaDoc) e.nextElement();
704
705                     genericEntries.put(je.getName().replace('\\', '/'), je);
706                 }
707                 //get the list of websphere jar entries
708
for (Enumeration JavaDoc e = wasJar.entries(); e.hasMoreElements();) {
709                     JarEntry JavaDoc je = (JarEntry JavaDoc) e.nextElement();
710
711                     wasEntries.put(je.getName(), je);
712                 }
713
714                 //Cycle Through generic and make sure its in websphere
715
ClassLoader JavaDoc genericLoader = getClassLoaderFromJar(genericJarFile);
716
717                 for (Enumeration JavaDoc e = genericEntries.keys(); e.hasMoreElements();) {
718                     String JavaDoc filepath = (String JavaDoc) e.nextElement();
719
720                     if (wasEntries.containsKey(filepath)) {
721                         // File name/path match
722
// Check files see if same
723
JarEntry JavaDoc genericEntry = (JarEntry JavaDoc) genericEntries.get(filepath);
724                         JarEntry JavaDoc wasEntry = (JarEntry JavaDoc) wasEntries.get(filepath);
725
726                         if ((genericEntry.getCrc() != wasEntry.getCrc())
727                             || (genericEntry.getSize() != wasEntry.getSize())) {
728
729                             if (genericEntry.getName().endsWith(".class")) {
730                                 //File are different see if its an object or an interface
731
String JavaDoc classname
732                                     = genericEntry.getName().replace(File.separatorChar, '.');
733
734                                 classname = classname.substring(0, classname.lastIndexOf(".class"));
735
736                                 Class JavaDoc genclass = genericLoader.loadClass(classname);
737
738                                 if (genclass.isInterface()) {
739                                     //Interface changed rebuild jar.
740
log("Interface " + genclass.getName()
741                                         + " has changed", Project.MSG_VERBOSE);
742                                     rebuild = true;
743                                     break;
744                                 } else {
745                                     //Object class Changed update it.
746
replaceEntries.put(filepath, genericEntry);
747                                 }
748                             } else {
749                                 // is it the manifest. If so ignore it
750
if (!genericEntry.getName().equals("META-INF/MANIFEST.MF")) {
751                                     //File other then class changed rebuild
752
log("Non class file " + genericEntry.getName()
753                                         + " has changed", Project.MSG_VERBOSE);
754                                     rebuild = true;
755                                 }
756                                 break;
757                             }
758                         }
759                     } else {
760                         // a file doesn't exist rebuild
761

762                         log("File " + filepath + " not present in websphere jar",
763                             Project.MSG_VERBOSE);
764                         rebuild = true;
765                         break;
766                     }
767                 }
768
769                 if (!rebuild) {
770                     log("No rebuild needed - updating jar", Project.MSG_VERBOSE);
771                     newwasJarFile = new File JavaDoc(websphereJarFile.getAbsolutePath() + ".temp");
772                     if (newwasJarFile.exists()) {
773                         newwasJarFile.delete();
774                     }
775
776                     newJarStream = new JarOutputStream JavaDoc(new FileOutputStream JavaDoc(newwasJarFile));
777                     newJarStream.setLevel(0);
778
779                     //Copy files from old websphere jar
780
for (Enumeration JavaDoc e = wasEntries.elements(); e.hasMoreElements();) {
781                         byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
782                         int bytesRead;
783                         InputStream JavaDoc is;
784                         JarEntry JavaDoc je = (JarEntry JavaDoc) e.nextElement();
785
786                         if (je.getCompressedSize() == -1
787                             || je.getCompressedSize() == je.getSize()) {
788                             newJarStream.setLevel(0);
789                         } else {
790                             newJarStream.setLevel(JAR_COMPRESS_LEVEL);
791                         }
792
793                         // Update with changed Bean class
794
if (replaceEntries.containsKey(je.getName())) {
795                             log("Updating Bean class from generic Jar " + je.getName(),
796                                 Project.MSG_VERBOSE);
797                             // Use the entry from the generic jar
798
je = (JarEntry JavaDoc) replaceEntries.get(je.getName());
799                             is = genericJar.getInputStream(je);
800                         } else {
801                             //use fle from original websphere jar
802

803                             is = wasJar.getInputStream(je);
804                         }
805                         newJarStream.putNextEntry(new JarEntry JavaDoc(je.getName()));
806
807                         while ((bytesRead = is.read(buffer)) != -1) {
808                             newJarStream.write(buffer, 0, bytesRead);
809                         }
810                         is.close();
811                     }
812                 } else {
813                     log("websphere Jar rebuild needed due to changed "
814                         + "interface or XML", Project.MSG_VERBOSE);
815                 }
816             } else {
817                 rebuild = true;
818             }
819         } catch (ClassNotFoundException JavaDoc cnfe) {
820             String JavaDoc cnfmsg = "ClassNotFoundException while processing ejb-jar file"
821                  + ". Details: "
822                  + cnfe.getMessage();
823
824             throw new BuildException(cnfmsg, cnfe);
825         } catch (IOException JavaDoc ioe) {
826             String JavaDoc msg = "IOException while processing ejb-jar file "
827                  + ". Details: "
828                  + ioe.getMessage();
829
830             throw new BuildException(msg, ioe);
831         } finally {
832             // need to close files and perhaps rename output
833
if (genericJar != null) {
834                 try {
835                     genericJar.close();
836                 } catch (IOException JavaDoc closeException) {
837                     // Ignore
838
}
839             }
840
841             if (wasJar != null) {
842                 try {
843                     wasJar.close();
844                 } catch (IOException JavaDoc closeException) {
845                     // Ignore
846
}
847             }
848
849             if (newJarStream != null) {
850                 try {
851                     newJarStream.close();
852                 } catch (IOException JavaDoc closeException) {
853                     // Ignore
854
}
855
856                 try {
857                     FILE_UTILS.rename(newwasJarFile, websphereJarFile);
858                 } catch (IOException JavaDoc renameException) {
859                     log(renameException.getMessage(), Project.MSG_WARN);
860                     rebuild = true;
861                 }
862             }
863         }
864
865         return rebuild;
866     }
867
868
869     /**
870      * Helper method invoked by isRebuildRequired to get a ClassLoader for a
871      * Jar File passed to it.
872      *
873      * @param classjar java.io.File representing jar file to get classes from.
874      * @return a classloader for the jar file.
875      * @throws IOException if there is an error.
876      */

877     protected ClassLoader JavaDoc getClassLoaderFromJar(File JavaDoc classjar) throws IOException JavaDoc {
878         Path lookupPath = new Path(getTask().getProject());
879
880         lookupPath.setLocation(classjar);
881
882         Path classpath = getCombinedClasspath();
883
884         if (classpath != null) {
885             lookupPath.append(classpath);
886         }
887
888         return getTask().getProject().createClassLoader(lookupPath);
889     }
890 }
891
892
Popular Tags