Source Code Cross Referenced for GenericDeploymentTool.java in  » Build » ANT » org » apache » tools » ant » taskdefs » optional » ejb » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Build » ANT » org.apache.tools.ant.taskdefs.optional.ejb 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *  Licensed to the Apache Software Foundation (ASF) under one or more
003:         *  contributor license agreements.  See the NOTICE file distributed with
004:         *  this work for additional information regarding copyright ownership.
005:         *  The ASF licenses this file to You under the Apache License, Version 2.0
006:         *  (the "License"); you may not use this file except in compliance with
007:         *  the License.  You may obtain a copy of the License at
008:         *
009:         *      http://www.apache.org/licenses/LICENSE-2.0
010:         *
011:         *  Unless required by applicable law or agreed to in writing, software
012:         *  distributed under the License is distributed on an "AS IS" BASIS,
013:         *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         *  See the License for the specific language governing permissions and
015:         *  limitations under the License.
016:         *
017:         */
018:        package org.apache.tools.ant.taskdefs.optional.ejb;
019:
020:        import java.io.File;
021:        import java.io.FileInputStream;
022:        import java.io.FileOutputStream;
023:        import java.io.IOException;
024:        import java.io.InputStream;
025:        import java.util.Enumeration;
026:        import java.util.HashSet;
027:        import java.util.Hashtable;
028:        import java.util.Iterator;
029:        import java.util.Set;
030:        import java.util.jar.JarOutputStream;
031:        import java.util.jar.Manifest;
032:        import java.util.zip.ZipEntry;
033:
034:        import javax.xml.parsers.SAXParser;
035:
036:        import org.apache.tools.ant.BuildException;
037:        import org.apache.tools.ant.DirectoryScanner;
038:        import org.apache.tools.ant.Location;
039:        import org.apache.tools.ant.Project;
040:        import org.apache.tools.ant.Task;
041:        import org.apache.tools.ant.types.FileSet;
042:        import org.apache.tools.ant.types.Path;
043:        import org.apache.tools.ant.util.depend.DependencyAnalyzer;
044:        import org.xml.sax.InputSource;
045:        import org.xml.sax.SAXException;
046:
047:        /**
048:         * A deployment tool which creates generic EJB jars. Generic jars contains
049:         * only those classes and META-INF entries specified in the EJB 1.1 standard
050:         *
051:         * This class is also used as a framework for the creation of vendor specific
052:         * deployment tools. A number of template methods are provided through which the
053:         * vendor specific tool can hook into the EJB creation process.
054:         *
055:         */
056:        public class GenericDeploymentTool implements  EJBDeploymentTool {
057:            /** The default buffer byte size to use for IO */
058:            public static final int DEFAULT_BUFFER_SIZE = 1024;
059:            /** The level to use for compression */
060:            public static final int JAR_COMPRESS_LEVEL = 9;
061:
062:            /** The standard META-INF directory in jar files */
063:            protected static final String META_DIR = "META-INF/";
064:
065:            /** The standard MANIFEST file */
066:            protected static final String MANIFEST = META_DIR + "MANIFEST.MF";
067:
068:            /** Name for EJB Deployment descriptor within EJB jars */
069:            protected static final String EJB_DD = "ejb-jar.xml";
070:
071:            /** A dependency analyzer name to find ancestor classes */
072:            public static final String ANALYZER_SUPER = "super";
073:            /** A dependency analyzer name to find all related classes */
074:            public static final String ANALYZER_FULL = "full";
075:            /** A dependency analyzer name for no analyzer */
076:            public static final String ANALYZER_NONE = "none";
077:
078:            /** The default analyzer */
079:            public static final String DEFAULT_ANALYZER = ANALYZER_SUPER;
080:
081:            /** The analyzer class for the super analyzer */
082:            public static final String ANALYZER_CLASS_SUPER = "org.apache.tools.ant.util.depend.bcel.AncestorAnalyzer";
083:            /** The analyzer class for the super analyzer */
084:            public static final String ANALYZER_CLASS_FULL = "org.apache.tools.ant.util.depend.bcel.FullAnalyzer";
085:
086:            /**
087:             * The configuration from the containing task. This config combined
088:             * with the settings of the individual attributes here constitues the
089:             * complete config for this deployment tool.
090:             */
091:            private EjbJar.Config config;
092:
093:            /** Stores a handle to the directory to put the Jar files in */
094:            private File destDir;
095:
096:            /** The classpath to use with this deployment tool. This is appended to
097:                any paths from the ejbjar task itself.*/
098:            private Path classpath;
099:
100:            /** Instance variable that stores the suffix for the generated jarfile. */
101:            private String genericJarSuffix = "-generic.jar";
102:
103:            /**
104:             * The task to which this tool belongs. This is used to access services
105:             * provided by the ant core, such as logging.
106:             */
107:            private Task task;
108:
109:            /**
110:             * The classloader generated from the given classpath to load
111:             * the super classes and super interfaces.
112:             */
113:            private ClassLoader classpathLoader = null;
114:
115:            /**
116:             * Set of files have been loaded into the EJB jar
117:             */
118:            private Set addedfiles;
119:
120:            /**
121:             * Handler used to parse the EJB XML descriptor
122:             */
123:            private DescriptorHandler handler;
124:
125:            /**
126:             * Dependency analyzer used to collect class dependencies
127:             */
128:            private DependencyAnalyzer dependencyAnalyzer;
129:
130:            /** No arg constructor */
131:            public GenericDeploymentTool() {
132:            }
133:
134:            /**
135:             * Set the destination directory; required.
136:             * @param inDir the destination directory.
137:             */
138:            public void setDestdir(File inDir) {
139:                this .destDir = inDir;
140:            }
141:
142:            /**
143:             * Get the destination directory.
144:             *
145:             * @return the destination directory into which EJB jars are to be written
146:             */
147:            protected File getDestDir() {
148:                return destDir;
149:            }
150:
151:            /**
152:             * Set the task which owns this tool
153:             *
154:             * @param task the Task to which this deployment tool is associated.
155:             */
156:            public void setTask(Task task) {
157:                this .task = task;
158:            }
159:
160:            /**
161:             * Get the task for this tool.
162:             *
163:             * @return the Task instance this tool is associated with.
164:             */
165:            protected Task getTask() {
166:                return task;
167:            }
168:
169:            /**
170:             * Get the basename terminator.
171:             *
172:             * @return an ejbjar task configuration
173:             */
174:            protected EjbJar.Config getConfig() {
175:                return config;
176:            }
177:
178:            /**
179:             * Indicate if this build is using the base jar name.
180:             *
181:             * @return true if the name of the generated jar is coming from the
182:             *              basejarname attribute
183:             */
184:            protected boolean usingBaseJarName() {
185:                return config.baseJarName != null;
186:            }
187:
188:            /**
189:             * Set the suffix for the generated jar file.
190:             * @param inString the string to use as the suffix.
191:             */
192:            public void setGenericJarSuffix(String inString) {
193:                this .genericJarSuffix = inString;
194:            }
195:
196:            /**
197:             * Add the classpath for the user classes
198:             *
199:             * @return a Path instance to be configured by Ant.
200:             */
201:            public Path createClasspath() {
202:                if (classpath == null) {
203:                    classpath = new Path(task.getProject());
204:                }
205:                return classpath.createPath();
206:            }
207:
208:            /**
209:             * Set the classpath to be used for this compilation.
210:             *
211:             * @param classpath the classpath to be used for this build.
212:             */
213:            public void setClasspath(Path classpath) {
214:                this .classpath = classpath;
215:            }
216:
217:            /**
218:             * Get the classpath by combining the one from the surrounding task, if any
219:             * and the one from this tool.
220:             *
221:             * @return the combined classpath
222:             */
223:            protected Path getCombinedClasspath() {
224:                Path combinedPath = classpath;
225:                if (config.classpath != null) {
226:                    if (combinedPath == null) {
227:                        combinedPath = config.classpath;
228:                    } else {
229:                        combinedPath.append(config.classpath);
230:                    }
231:                }
232:
233:                return combinedPath;
234:            }
235:
236:            /**
237:             * Log a message to the Ant output.
238:             *
239:             * @param message the message to be logged.
240:             * @param level the severity of this message.
241:             */
242:            protected void log(String message, int level) {
243:                getTask().log(message, level);
244:            }
245:
246:            /**
247:             * Get the build file location associated with this element's task.
248:             *
249:             * @return the task's location instance.
250:             */
251:            protected Location getLocation() {
252:                return getTask().getLocation();
253:            }
254:
255:            private void createAnalyzer() {
256:                String analyzer = config.analyzer;
257:                if (analyzer == null) {
258:                    analyzer = DEFAULT_ANALYZER;
259:                }
260:
261:                if (analyzer.equals(ANALYZER_NONE)) {
262:                    return;
263:                }
264:
265:                String analyzerClassName = null;
266:                if (analyzer.equals(ANALYZER_SUPER)) {
267:                    analyzerClassName = ANALYZER_CLASS_SUPER;
268:                } else if (analyzer.equals(ANALYZER_FULL)) {
269:                    analyzerClassName = ANALYZER_CLASS_FULL;
270:                } else {
271:                    analyzerClassName = analyzer;
272:                }
273:
274:                try {
275:                    Class analyzerClass = Class.forName(analyzerClassName);
276:                    dependencyAnalyzer = (DependencyAnalyzer) analyzerClass
277:                            .newInstance();
278:                    dependencyAnalyzer.addClassPath(new Path(task.getProject(),
279:                            config.srcDir.getPath()));
280:                    dependencyAnalyzer.addClassPath(config.classpath);
281:                } catch (NoClassDefFoundError e) {
282:                    dependencyAnalyzer = null;
283:                    task.log(
284:                            "Unable to load dependency analyzer: "
285:                                    + analyzerClassName
286:                                    + " - dependent class not found: "
287:                                    + e.getMessage(), Project.MSG_WARN);
288:                } catch (Exception e) {
289:                    dependencyAnalyzer = null;
290:                    task.log("Unable to load dependency analyzer: "
291:                            + analyzerClassName + " - exception: "
292:                            + e.getMessage(), Project.MSG_WARN);
293:                }
294:            }
295:
296:            /**
297:             * Configure this tool for use in the ejbjar task.
298:             *
299:             * @param config the configuration from the surrounding ejbjar task.
300:             */
301:            public void configure(EjbJar.Config config) {
302:                this .config = config;
303:
304:                createAnalyzer();
305:                classpathLoader = null;
306:            }
307:
308:            /**
309:             * Utility method that encapsulates the logic of adding a file entry to
310:             * a .jar file.  Used by execute() to add entries to the jar file as it is
311:             * constructed.
312:             * @param jStream A JarOutputStream into which to write the
313:             *        jar entry.
314:             * @param inputFile A File from which to read the
315:             *        contents the file being added.
316:             * @param logicalFilename A String representing the name, including
317:             *        all relevant path information, that should be stored for the entry
318:             *        being added.
319:             * @throws BuildException if there is a problem.
320:             */
321:            protected void addFileToJar(JarOutputStream jStream,
322:                    File inputFile, String logicalFilename)
323:                    throws BuildException {
324:                FileInputStream iStream = null;
325:                try {
326:                    if (!addedfiles.contains(logicalFilename)) {
327:                        iStream = new FileInputStream(inputFile);
328:                        // Create the zip entry and add it to the jar file
329:                        ZipEntry zipEntry = new ZipEntry(logicalFilename
330:                                .replace('\\', '/'));
331:                        jStream.putNextEntry(zipEntry);
332:
333:                        // Create the file input stream, and buffer everything over
334:                        // to the jar output stream
335:                        byte[] byteBuffer = new byte[2 * DEFAULT_BUFFER_SIZE];
336:                        int count = 0;
337:                        do {
338:                            jStream.write(byteBuffer, 0, count);
339:                            count = iStream.read(byteBuffer, 0,
340:                                    byteBuffer.length);
341:                        } while (count != -1);
342:
343:                        //add it to list of files in jar
344:                        addedfiles.add(logicalFilename);
345:                    }
346:                } catch (IOException ioe) {
347:                    log(
348:                            "WARNING: IOException while adding entry "
349:                                    + logicalFilename + " to jarfile from "
350:                                    + inputFile.getPath() + " "
351:                                    + ioe.getClass().getName() + "-"
352:                                    + ioe.getMessage(), Project.MSG_WARN);
353:                } finally {
354:                    // Close up the file input stream for the class file
355:                    if (iStream != null) {
356:                        try {
357:                            iStream.close();
358:                        } catch (IOException closeException) {
359:                            // ignore
360:                        }
361:                    }
362:                }
363:            }
364:
365:            /**
366:             * Get a descriptionHandler.
367:             * @param srcDir the source directory.
368:             * @return a handler.
369:             */
370:            protected DescriptorHandler getDescriptorHandler(File srcDir) {
371:                DescriptorHandler h = new DescriptorHandler(getTask(), srcDir);
372:
373:                registerKnownDTDs(h);
374:
375:                // register any DTDs supplied by the user
376:                for (Iterator i = getConfig().dtdLocations.iterator(); i
377:                        .hasNext();) {
378:                    EjbJar.DTDLocation dtdLocation = (EjbJar.DTDLocation) i
379:                            .next();
380:                    h.registerDTD(dtdLocation.getPublicId(), dtdLocation
381:                            .getLocation());
382:                }
383:                return h;
384:            }
385:
386:            /**
387:             * Register the locations of all known DTDs.
388:             *
389:             * vendor-specific subclasses should override this method to define
390:             * the vendor-specific locations of the EJB DTDs
391:             * @param handler no used in this class.
392:             */
393:            protected void registerKnownDTDs(DescriptorHandler handler) {
394:                // none to register for generic
395:            }
396:
397:            /** {@inheritDoc}. */
398:            public void processDescriptor(String descriptorFileName,
399:                    SAXParser saxParser) {
400:
401:                checkConfiguration(descriptorFileName, saxParser);
402:
403:                try {
404:                    handler = getDescriptorHandler(config.srcDir);
405:
406:                    // Retrive the files to be added to JAR from EJB descriptor
407:                    Hashtable ejbFiles = parseEjbFiles(descriptorFileName,
408:                            saxParser);
409:
410:                    // Add any support classes specified in the build file
411:                    addSupportClasses(ejbFiles);
412:
413:                    // Determine the JAR filename (without filename extension)
414:                    String baseName = getJarBaseName(descriptorFileName);
415:
416:                    String ddPrefix = getVendorDDPrefix(baseName,
417:                            descriptorFileName);
418:
419:                    File manifestFile = getManifestFile(ddPrefix);
420:                    if (manifestFile != null) {
421:                        ejbFiles.put(MANIFEST, manifestFile);
422:                    }
423:
424:                    // First the regular deployment descriptor
425:                    ejbFiles.put(META_DIR + EJB_DD, new File(
426:                            config.descriptorDir, descriptorFileName));
427:
428:                    // now the vendor specific files, if any
429:                    addVendorFiles(ejbFiles, ddPrefix);
430:
431:                    // add any dependent files
432:                    checkAndAddDependants(ejbFiles);
433:
434:                    // Lastly create File object for the Jar files. If we are using
435:                    // a flat destination dir, then we need to redefine baseName!
436:                    if (config.flatDestDir && baseName.length() != 0) {
437:                        int startName = baseName.lastIndexOf(File.separator);
438:                        if (startName == -1) {
439:                            startName = 0;
440:                        }
441:
442:                        int endName = baseName.length();
443:                        baseName = baseName.substring(startName, endName);
444:                    }
445:
446:                    File jarFile = getVendorOutputJarFile(baseName);
447:
448:                    // Check to see if we need a build and start doing the work!
449:                    if (needToRebuild(ejbFiles, jarFile)) {
450:                        // Log that we are going to build...
451:                        log("building " + jarFile.getName() + " with "
452:                                + String.valueOf(ejbFiles.size()) + " files",
453:                                Project.MSG_INFO);
454:
455:                        // Use helper method to write the jarfile
456:                        String publicId = getPublicId();
457:                        writeJar(baseName, jarFile, ejbFiles, publicId);
458:
459:                    } else {
460:                        // Log that the file is up to date...
461:                        log(jarFile.toString() + " is up to date.",
462:                                Project.MSG_VERBOSE);
463:                    }
464:
465:                } catch (SAXException se) {
466:                    String msg = "SAXException while parsing '"
467:                            + descriptorFileName
468:                            + "'. This probably indicates badly-formed XML."
469:                            + "  Details: " + se.getMessage();
470:                    throw new BuildException(msg, se);
471:                } catch (IOException ioe) {
472:                    String msg = "IOException while parsing'"
473:                            + descriptorFileName.toString()
474:                            + "'.  This probably indicates that the descriptor"
475:                            + " doesn't exist. Details: " + ioe.getMessage();
476:                    throw new BuildException(msg, ioe);
477:                }
478:            }
479:
480:            /**
481:             * This method is called as the first step in the processDescriptor method
482:             * to allow vendor-specific subclasses to validate the task configuration
483:             * prior to processing the descriptor.  If the configuration is invalid,
484:             * a BuildException should be thrown.
485:             *
486:             * @param descriptorFileName String representing the file name of an EJB
487:             *                           descriptor to be processed
488:             * @param saxParser          SAXParser which may be used to parse the XML
489:             *                           descriptor
490:             * @throws BuildException if there is a problem.
491:             */
492:            protected void checkConfiguration(String descriptorFileName,
493:                    SAXParser saxParser) throws BuildException {
494:
495:                /*
496:                 * For the GenericDeploymentTool, do nothing.  Vendor specific
497:                 * subclasses should throw a BuildException if the configuration is
498:                 * invalid for their server.
499:                 */
500:            }
501:
502:            /**
503:             * This method returns a list of EJB files found when the specified EJB
504:             * descriptor is parsed and processed.
505:             *
506:             * @param descriptorFileName String representing the file name of an EJB
507:             *                           descriptor to be processed
508:             * @param saxParser          SAXParser which may be used to parse the XML
509:             *                           descriptor
510:             * @return                   Hashtable of EJB class (and other) files to be
511:             *                           added to the completed JAR file
512:             * @throws SAXException      Any SAX exception, possibly wrapping another
513:             *                           exception
514:             * @throws IOException       An IOException from the parser, possibly from a
515:             *                           the byte stream or character stream
516:             */
517:            protected Hashtable parseEjbFiles(String descriptorFileName,
518:                    SAXParser saxParser) throws IOException, SAXException {
519:                FileInputStream descriptorStream = null;
520:                Hashtable ejbFiles = null;
521:
522:                try {
523:
524:                    /* Parse the ejb deployment descriptor.  While it may not
525:                     * look like much, we use a SAXParser and an inner class to
526:                     * get hold of all the classfile names for the descriptor.
527:                     */
528:                    descriptorStream = new FileInputStream(new File(
529:                            config.descriptorDir, descriptorFileName));
530:                    saxParser.parse(new InputSource(descriptorStream), handler);
531:
532:                    ejbFiles = handler.getFiles();
533:
534:                } finally {
535:                    if (descriptorStream != null) {
536:                        try {
537:                            descriptorStream.close();
538:                        } catch (IOException closeException) {
539:                            // ignore
540:                        }
541:                    }
542:                }
543:
544:                return ejbFiles;
545:            }
546:
547:            /**
548:             * Adds any classes the user specifies using <i>support</i> nested elements
549:             * to the <code>ejbFiles</code> Hashtable.
550:             *
551:             * @param ejbFiles Hashtable of EJB classes (and other) files that will be
552:             *                 added to the completed JAR file
553:             */
554:            protected void addSupportClasses(Hashtable ejbFiles) {
555:                // add in support classes if any
556:                Project project = task.getProject();
557:                for (Iterator i = config.supportFileSets.iterator(); i
558:                        .hasNext();) {
559:                    FileSet supportFileSet = (FileSet) i.next();
560:                    File supportBaseDir = supportFileSet.getDir(project);
561:                    DirectoryScanner supportScanner = supportFileSet
562:                            .getDirectoryScanner(project);
563:                    supportScanner.scan();
564:                    String[] supportFiles = supportScanner.getIncludedFiles();
565:                    for (int j = 0; j < supportFiles.length; ++j) {
566:                        ejbFiles.put(supportFiles[j], new File(supportBaseDir,
567:                                supportFiles[j]));
568:                    }
569:                }
570:            }
571:
572:            /**
573:             * Using the EJB descriptor file name passed from the <code>ejbjar</code>
574:             * task, this method returns the "basename" which will be used to name the
575:             * completed JAR file.
576:             *
577:             * @param descriptorFileName String representing the file name of an EJB
578:             *                           descriptor to be processed
579:             * @return                   The "basename" which will be used to name the
580:             *                           completed JAR file
581:             */
582:            protected String getJarBaseName(String descriptorFileName) {
583:
584:                String baseName = "";
585:
586:                // Work out what the base name is
587:                if (config.namingScheme.getValue().equals(
588:                        EjbJar.NamingScheme.BASEJARNAME)) {
589:                    String canonicalDescriptor = descriptorFileName.replace(
590:                            '\\', '/');
591:                    int index = canonicalDescriptor.lastIndexOf('/');
592:                    if (index != -1) {
593:                        baseName = descriptorFileName.substring(0, index + 1);
594:                    }
595:                    baseName += config.baseJarName;
596:                } else if (config.namingScheme.getValue().equals(
597:                        EjbJar.NamingScheme.DESCRIPTOR)) {
598:                    int lastSeparatorIndex = descriptorFileName
599:                            .lastIndexOf(File.separator);
600:                    int endBaseName = -1;
601:                    if (lastSeparatorIndex != -1) {
602:                        endBaseName = descriptorFileName.indexOf(
603:                                config.baseNameTerminator, lastSeparatorIndex);
604:                    } else {
605:                        endBaseName = descriptorFileName
606:                                .indexOf(config.baseNameTerminator);
607:                    }
608:
609:                    if (endBaseName != -1) {
610:                        baseName = descriptorFileName.substring(0, endBaseName);
611:                    } else {
612:                        throw new BuildException(
613:                                "Unable to determine jar name "
614:                                        + "from descriptor \""
615:                                        + descriptorFileName + "\"");
616:                    }
617:                } else if (config.namingScheme.getValue().equals(
618:                        EjbJar.NamingScheme.DIRECTORY)) {
619:                    File descriptorFile = new File(config.descriptorDir,
620:                            descriptorFileName);
621:                    String path = descriptorFile.getAbsolutePath();
622:                    int lastSeparatorIndex = path.lastIndexOf(File.separator);
623:                    if (lastSeparatorIndex == -1) {
624:                        throw new BuildException(
625:                                "Unable to determine directory name holding descriptor");
626:                    }
627:                    String dirName = path.substring(0, lastSeparatorIndex);
628:                    int dirSeparatorIndex = dirName.lastIndexOf(File.separator);
629:                    if (dirSeparatorIndex != -1) {
630:                        dirName = dirName.substring(dirSeparatorIndex + 1);
631:                    }
632:
633:                    baseName = dirName;
634:                } else if (config.namingScheme.getValue().equals(
635:                        EjbJar.NamingScheme.EJB_NAME)) {
636:                    baseName = handler.getEjbName();
637:                }
638:                return baseName;
639:            }
640:
641:            /**
642:             * Get the prefix for vendor deployment descriptors.
643:             *
644:             * This will contain the path and the start of the descriptor name,
645:             * depending on the naming scheme
646:             * @param baseName the base name to use.
647:             * @param descriptorFileName the file name to use.
648:             * @return the prefix.
649:             */
650:            public String getVendorDDPrefix(String baseName,
651:                    String descriptorFileName) {
652:                String ddPrefix = null;
653:
654:                if (config.namingScheme.getValue().equals(
655:                        EjbJar.NamingScheme.DESCRIPTOR)) {
656:                    ddPrefix = baseName + config.baseNameTerminator;
657:                } else if (config.namingScheme.getValue().equals(
658:                        EjbJar.NamingScheme.BASEJARNAME)
659:                        || config.namingScheme.getValue().equals(
660:                                EjbJar.NamingScheme.EJB_NAME)
661:                        || config.namingScheme.getValue().equals(
662:                                EjbJar.NamingScheme.DIRECTORY)) {
663:                    String canonicalDescriptor = descriptorFileName.replace(
664:                            '\\', '/');
665:                    int index = canonicalDescriptor.lastIndexOf('/');
666:                    if (index == -1) {
667:                        ddPrefix = "";
668:                    } else {
669:                        ddPrefix = descriptorFileName.substring(0, index + 1);
670:                    }
671:                }
672:                return ddPrefix;
673:            }
674:
675:            /**
676:             * Add any vendor specific files which should be included in the
677:             * EJB Jar.
678:             * @param ejbFiles a hashtable entryname -> file.
679:             * @param ddPrefix a prefix to use.
680:             */
681:            protected void addVendorFiles(Hashtable ejbFiles, String ddPrefix) {
682:                // nothing to add for generic tool.
683:            }
684:
685:            /**
686:             * Get the vendor specific name of the Jar that will be output. The modification date
687:             * of this jar will be checked against the dependent bean classes.
688:             * @param baseName the basename to use.
689:             */
690:            File getVendorOutputJarFile(String baseName) {
691:                return new File(destDir, baseName + genericJarSuffix);
692:            }
693:
694:            /**
695:             * This method checks the timestamp on each file listed in the <code>
696:             * ejbFiles</code> and compares them to the timestamp on the <code>jarFile
697:             * </code>.  If the <code>jarFile</code>'s timestamp is more recent than
698:             * each EJB file, <code>true</code> is returned.  Otherwise, <code>false
699:             * </code> is returned.
700:             * TODO: find a way to check the manifest-file, that is found by naming convention
701:             *
702:             * @param ejbFiles Hashtable of EJB classes (and other) files that will be
703:             *                 added to the completed JAR file
704:             * @param jarFile  JAR file which will contain all of the EJB classes (and
705:             *                 other) files
706:             * @return         boolean indicating whether or not the <code>jarFile</code>
707:             *                 is up to date
708:             */
709:            protected boolean needToRebuild(Hashtable ejbFiles, File jarFile) {
710:                if (jarFile.exists()) {
711:                    long lastBuild = jarFile.lastModified();
712:
713:                    Iterator fileIter = ejbFiles.values().iterator();
714:
715:                    // Loop through the files seeing if any has been touched
716:                    // more recently than the destination jar.
717:                    while (fileIter.hasNext()) {
718:                        File currentFile = (File) fileIter.next();
719:                        if (lastBuild < currentFile.lastModified()) {
720:                            log("Build needed because " + currentFile.getPath()
721:                                    + " is out of date", Project.MSG_VERBOSE);
722:                            return true;
723:                        }
724:                    }
725:                    return false;
726:                }
727:
728:                return true;
729:            }
730:
731:            /**
732:             * Returns the Public ID of the DTD specified in the EJB descriptor.  Not
733:             * every vendor-specific <code>DeploymentTool</code> will need to reference
734:             * this value or may want to determine this value in a vendor-specific way.
735:             *
736:             * @return Public ID of the DTD specified in the EJB descriptor.
737:             */
738:            protected String getPublicId() {
739:                return handler.getPublicId();
740:            }
741:
742:            /**
743:             * Get the manifets file to use for building the generic jar.
744:             *
745:             * If the file does not exist the global manifest from the config is used
746:             * otherwise the default Ant manifest will be used.
747:             *
748:             * @param prefix the prefix where to llook for the manifest file based on
749:             *        the naming convention.
750:             *
751:             * @return the manifest file or null if the manifest file does not exist
752:             */
753:            protected File getManifestFile(String prefix) {
754:                File manifestFile = new File(getConfig().descriptorDir, prefix
755:                        + "manifest.mf");
756:                if (manifestFile.exists()) {
757:                    return manifestFile;
758:                }
759:
760:                if (config.manifest != null) {
761:                    return config.manifest;
762:                }
763:                return null;
764:            }
765:
766:            /**
767:             * Method used to encapsulate the writing of the JAR file. Iterates over the
768:             * filenames/java.io.Files in the Hashtable stored on the instance variable
769:             * ejbFiles.
770:             * @param baseName the base name to use.
771:             * @param jarfile  the jar file to write to.
772:             * @param files    the files to write to the jar.
773:             * @param publicId the id to use.
774:             * @throws BuildException if there is a problem.
775:             */
776:            protected void writeJar(String baseName, File jarfile,
777:                    Hashtable files, String publicId) throws BuildException {
778:
779:                JarOutputStream jarStream = null;
780:                try {
781:                    // clean the addedfiles set
782:                    if (addedfiles == null) {
783:                        addedfiles = new HashSet();
784:                    } else {
785:                        addedfiles.clear();
786:                    }
787:
788:                    /* If the jarfile already exists then whack it and recreate it.
789:                     * Should probably think of a more elegant way to handle this
790:                     * so that in case of errors we don't leave people worse off
791:                     * than when we started =)
792:                     */
793:                    if (jarfile.exists()) {
794:                        jarfile.delete();
795:                    }
796:                    jarfile.getParentFile().mkdirs();
797:                    jarfile.createNewFile();
798:
799:                    InputStream in = null;
800:                    Manifest manifest = null;
801:                    try {
802:                        File manifestFile = (File) files.get(MANIFEST);
803:                        if (manifestFile != null && manifestFile.exists()) {
804:                            in = new FileInputStream(manifestFile);
805:                        } else {
806:                            String defaultManifest = "/org/apache/tools/ant/defaultManifest.mf";
807:                            in = this .getClass().getResourceAsStream(
808:                                    defaultManifest);
809:                            if (in == null) {
810:                                throw new BuildException("Could not find "
811:                                        + "default manifest: "
812:                                        + defaultManifest);
813:                            }
814:                        }
815:
816:                        manifest = new Manifest(in);
817:                    } catch (IOException e) {
818:                        throw new BuildException("Unable to read manifest", e,
819:                                getLocation());
820:                    } finally {
821:                        if (in != null) {
822:                            in.close();
823:                        }
824:                    }
825:
826:                    // Create the streams necessary to write the jarfile
827:
828:                    jarStream = new JarOutputStream(new FileOutputStream(
829:                            jarfile), manifest);
830:                    jarStream.setMethod(JarOutputStream.DEFLATED);
831:
832:                    // Loop through all the class files found and add them to the jar
833:                    for (Iterator entryIterator = files.keySet().iterator(); entryIterator
834:                            .hasNext();) {
835:                        String entryName = (String) entryIterator.next();
836:                        if (entryName.equals(MANIFEST)) {
837:                            continue;
838:                        }
839:
840:                        File entryFile = (File) files.get(entryName);
841:
842:                        log("adding file '" + entryName + "'",
843:                                Project.MSG_VERBOSE);
844:
845:                        addFileToJar(jarStream, entryFile, entryName);
846:
847:                        // See if there are any inner classes for this class and add them in if there are
848:                        InnerClassFilenameFilter flt = new InnerClassFilenameFilter(
849:                                entryFile.getName());
850:                        File entryDir = entryFile.getParentFile();
851:                        String[] innerfiles = entryDir.list(flt);
852:                        if (innerfiles != null) {
853:                            for (int i = 0, n = innerfiles.length; i < n; i++) {
854:
855:                                //get and clean up innerclass name
856:                                int entryIndex = entryName
857:                                        .lastIndexOf(entryFile.getName()) - 1;
858:                                if (entryIndex < 0) {
859:                                    entryName = innerfiles[i];
860:                                } else {
861:                                    entryName = entryName.substring(0,
862:                                            entryIndex)
863:                                            + File.separatorChar
864:                                            + innerfiles[i];
865:                                }
866:                                // link the file
867:                                entryFile = new File(config.srcDir, entryName);
868:
869:                                log("adding innerclass file '" + entryName
870:                                        + "'", Project.MSG_VERBOSE);
871:
872:                                addFileToJar(jarStream, entryFile, entryName);
873:
874:                            }
875:                        }
876:                    }
877:                } catch (IOException ioe) {
878:                    String msg = "IOException while processing ejb-jar file '"
879:                            + jarfile.toString() + "'. Details: "
880:                            + ioe.getMessage();
881:                    throw new BuildException(msg, ioe);
882:                } finally {
883:                    if (jarStream != null) {
884:                        try {
885:                            jarStream.close();
886:                        } catch (IOException closeException) {
887:                            // ignore
888:                        }
889:                    }
890:                }
891:            } // end of writeJar
892:
893:            /**
894:             * Add all available classes, that depend on Remote, Home, Bean, PK
895:             * @param checkEntries files, that are extracted from the deployment descriptor
896:             * @throws BuildException if there is a problem.
897:             */
898:            protected void checkAndAddDependants(Hashtable checkEntries)
899:                    throws BuildException {
900:
901:                if (dependencyAnalyzer == null) {
902:                    return;
903:                }
904:
905:                dependencyAnalyzer.reset();
906:
907:                Iterator i = checkEntries.keySet().iterator();
908:                while (i.hasNext()) {
909:                    String entryName = (String) i.next();
910:                    if (entryName.endsWith(".class")) {
911:                        String className = entryName.substring(0, entryName
912:                                .length()
913:                                - ".class".length());
914:                        className = className.replace(File.separatorChar, '/');
915:                        className = className.replace('/', '.');
916:
917:                        dependencyAnalyzer.addRootClass(className);
918:                    }
919:                }
920:
921:                Enumeration e = dependencyAnalyzer.getClassDependencies();
922:
923:                while (e.hasMoreElements()) {
924:                    String classname = (String) e.nextElement();
925:                    String location = classname
926:                            .replace('.', File.separatorChar)
927:                            + ".class";
928:                    File classFile = new File(config.srcDir, location);
929:                    if (classFile.exists()) {
930:                        checkEntries.put(location, classFile);
931:                        log(
932:                                "dependent class: " + classname + " - "
933:                                        + classFile, Project.MSG_VERBOSE);
934:                    }
935:                }
936:            }
937:
938:            /**
939:             * Returns a Classloader object which parses the passed in generic EjbJar classpath.
940:             * The loader is used to dynamically load classes from javax.ejb.* and the classes
941:             * being added to the jar.
942:             * @return a classloader.
943:             */
944:            protected ClassLoader getClassLoaderForBuild() {
945:                if (classpathLoader != null) {
946:                    return classpathLoader;
947:                }
948:
949:                Path combinedClasspath = getCombinedClasspath();
950:
951:                // only generate a new ClassLoader if we have a classpath
952:                if (combinedClasspath == null) {
953:                    classpathLoader = getClass().getClassLoader();
954:                } else {
955:                    classpathLoader = getTask().getProject().createClassLoader(
956:                            combinedClasspath);
957:                }
958:
959:                return classpathLoader;
960:            }
961:
962:            /**
963:             * Called to validate that the tool parameters have been configured.
964:             *
965:             * @throws BuildException If the Deployment Tool's configuration isn't
966:             *                        valid
967:             */
968:            public void validateConfigured() throws BuildException {
969:                if ((destDir == null) || (!destDir.isDirectory())) {
970:                    String msg = "A valid destination directory must be specified "
971:                            + "using the \"destdir\" attribute.";
972:                    throw new BuildException(msg, getLocation());
973:                }
974:            }
975:        }
ww___w_._j___a__v___a2__s._c_om___ | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.