Source Code Cross Referenced for GenIC.java in  » J2EE » JOnAS-4.8.6 » org » objectweb » jonas_ejb » genic » 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 » J2EE » JOnAS 4.8.6 » org.objectweb.jonas_ejb.genic 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /**
0002:         * JOnAS: Java(TM) Open Application Server
0003:         * Copyright (C) 1999-2005 Bull S.A.
0004:         * Contact: jonas-team@objectweb.org
0005:         *
0006:         * This library is free software; you can redistribute it and/or
0007:         * modify it under the terms of the GNU Lesser General Public
0008:         * License as published by the Free Software Foundation; either
0009:         * version 2.1 of the License, or any later version.
0010:         *
0011:         * This library is distributed in the hope that it will be useful,
0012:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0014:         * Lesser General Public License for more details.
0015:         *
0016:         * You should have received a copy of the GNU Lesser General Public
0017:         * License along with this library; if not, write to the Free Software
0018:         * USA
0019:         *
0020:         * --------------------------------------------------------------------------
0021:         * $Id: GenIC.java 9721 2006-10-11 11:37:32Z benoitf $
0022:         * --------------------------------------------------------------------------
0023:         */package org.objectweb.jonas_ejb.genic;
0024:
0025:        import java.io.File;
0026:        import java.io.FileInputStream;
0027:        import java.io.FileOutputStream;
0028:        import java.io.IOException;
0029:        import java.io.InputStream;
0030:        import java.io.OutputStream;
0031:        import java.io.PrintStream;
0032:        import java.lang.reflect.InvocationTargetException;
0033:        import java.lang.reflect.Method;
0034:        import java.net.MalformedURLException;
0035:        import java.net.URL;
0036:        import java.util.ArrayList;
0037:        import java.util.Enumeration;
0038:        import java.util.Iterator;
0039:        import java.util.List;
0040:        import java.util.Properties;
0041:        import java.util.StringTokenizer;
0042:        import java.util.jar.Attributes;
0043:        import java.util.jar.JarEntry;
0044:        import java.util.jar.JarFile;
0045:        import java.util.jar.JarOutputStream;
0046:        import java.util.jar.Manifest;
0047:
0048:        import org.apache.velocity.app.VelocityEngine;
0049:        import org.apache.velocity.runtime.RuntimeConstants;
0050:        import org.objectweb.common.Cmd;
0051:        import org.objectweb.common.Env;
0052:        import org.objectweb.jonas.common.Log;
0053:        import org.objectweb.jonas.container.Protocols;
0054:        import org.objectweb.jonas.server.JClassLoader;
0055:        import org.objectweb.jonas_ejb.deployment.api.BeanDesc;
0056:        import org.objectweb.jonas_ejb.deployment.api.DeploymentDesc;
0057:        import org.objectweb.jonas_ejb.deployment.api.DeploymentDescEjb2;
0058:        import org.objectweb.jonas_ejb.deployment.api.EntityCmp2Desc;
0059:        import org.objectweb.jonas_ejb.deployment.api.MessageDrivenDesc;
0060:        import org.objectweb.jonas_ejb.deployment.lib.EjbDeploymentDescManager;
0061:        import org.objectweb.jonas_ejb.lib.BeanNaming;
0062:        import org.objectweb.jonas_lib.deployment.api.DeploymentDescException;
0063:        import org.objectweb.jonas_lib.files.FileUtils;
0064:        import org.objectweb.jonas_lib.files.FileUtilsException;
0065:        import org.objectweb.jonas_lib.version.Version;
0066:        import org.objectweb.jorm.api.PException;
0067:        import org.objectweb.jorm.compiler.api.JormCompilerConfigurator;
0068:        import org.objectweb.jorm.compiler.lib.JormCompiler;
0069:        import org.objectweb.jorm.metainfo.api.Manager;
0070:        import org.objectweb.medor.api.MedorException;
0071:        import org.objectweb.util.monolog.api.BasicLevel;
0072:        import org.objectweb.util.monolog.api.Logger;
0073:        import org.objectweb.util.monolog.wrapper.velocity.VelocityLogger;
0074:
0075:        /**
0076:         * This class allows to generate:
0077:         * <ul>
0078:         * <li>the classes that implements the Enterprise bean's remote interface,
0079:         * <li>the classes that implements the Enterprise bean's home interface,
0080:         * <li>the classes that implements the Handles of the Entity beans,
0081:         * <li>the classes that implements the persistence of the Entity beans with
0082:         * CMP,
0083:         * </ul>
0084:         * of all the Enterprise Java Beans defined in the given Deployment Descriptor.
0085:         *
0086:         * @author Helene Joanin : Initial developer
0087:         * @author Christophe Ney (Lutris Technologies) : Fix to handle arguments containing white spaces.
0088:         * @author Guillaume Riviere : Fix the addClassesInJar() method (on David, the Stub/Skel classes names are different).
0089:         * @author Dean Jennings : Remove System Exit (called now from server)
0090:         * @author Sami Lehtinen : use of java.util.jar api instead of jar command
0091:         */
0092:        public class GenIC {
0093:
0094:            /**
0095:             * install.root property name
0096:             */
0097:            private static final String INSTALL_ROOT_PROPERTY = "install.root";
0098:
0099:            /**
0100:             * java.home property value (ended with '/')
0101:             */
0102:            private static String javaHomeBin = null;
0103:
0104:            /**
0105:             * Is the command is verbose ?
0106:             */
0107:            private boolean verbose = false;
0108:
0109:            /**
0110:             * Name of the directory where to place the generated file
0111:             */
0112:            private String outputdir = null;
0113:
0114:            /**
0115:             * Are some container classes generated ?
0116:             */
0117:            private boolean generatedIC;
0118:
0119:            /**
0120:             * Path names of the generated files to delete
0121:             */
0122:            private ArrayList filesToDelete = null;
0123:
0124:            /**
0125:             * Path names of the java generated sources (remote)
0126:             */
0127:            private ArrayList remoteJavas = null;
0128:
0129:            /**
0130:             * Path names of the java generated sources (no remote)
0131:             */
0132:            private ArrayList noRemoteJavas = null;
0133:
0134:            /**
0135:             * Names of the remote classes (package name included)
0136:             */
0137:            private ArrayList remoteClasses = null;
0138:
0139:            /**
0140:             * GenIC Parameters
0141:             */
0142:            private GenICParameters gp = null;
0143:
0144:            /**
0145:             * Logger used by GenIC
0146:             */
0147:            private static Logger logger = null;
0148:
0149:            /**
0150:             * Buffer size
0151:             */
0152:            private static final int BUFFER_SIZE = 1024;
0153:
0154:            /** META dir */
0155:            private static final String META_DIR = "META-INF";
0156:
0157:            /** The jar entry for the MANIFEST file */
0158:            private static final String MANIFEST_JAR_ENTRY = META_DIR
0159:                    + "/MANIFEST.MF";
0160:
0161:            /** The path to the MANIFEST file */
0162:            private static final String MANIFEST_PATH = META_DIR
0163:                    + File.separator + "MANIFEST.MF";
0164:
0165:            /**
0166:             * GenIC allows to generate the container classes for JOnAS for the given
0167:             * Enterprise Java Beans.
0168:             * <p>
0169:             * Usage: java org.objectweb.jonas_ejb.genic.GenIC -help <br>
0170:             * to print this help message
0171:             * <p>
0172:             * or java org.objectweb.jonas_ejb.genic.GenIC <Options><Input_File><br>
0173:             * to generate the container classes for the given EJBs.
0174:             * <p>
0175:             * Options include:
0176:             * <ul>
0177:             * <li>-d <output_dir>specify where to place the generated files</li>
0178:             * <li>-noaddinjar do not add the generated classes in the given ejb-jar
0179:             * file</li>
0180:             * <li>-classpath <path> define the classpath to be used to compile classes</li>
0181:             * <li>-nocompil do not compile the generated source files via the java and
0182:             * rmi compilers</li>
0183:             * <li>-novalidation parse the XML deployment descriptors without
0184:             * validation</li>
0185:             * <li>-javac <opt>specify the name of the java compiler to use</li>
0186:             * <li>-javacopts <opt>specify the options to pass to the java compiler
0187:             * </li>
0188:             * <li>-rmicopts <opt>specify the options to pass to the rmi compiler</li>
0189:             * <li>-protocols list of protocol, separated by comma</li>
0190:             * <li>-keepgenerated do not delete intermediate generated source files
0191:             * </li>
0192:             * <li>-verbose</li>
0193:             * <li>-invokecmd invoke, in some case, directly the method of the java
0194:             * class corresponding to the command</li>
0195:             * </ul>
0196:             * <p>
0197:             * Input_File file name of the standard deployment descriptor (.xml ended),
0198:             * or file name of the EJB-jar (.jar ended).
0199:             * @param args arguments for GenIC
0200:             */
0201:            public static void main(String[] args) {
0202:                boolean error = false;
0203:
0204:                // don't use the fastrmic compiler by default
0205:                //boolean nofastrmic = false;
0206:
0207:                String protocolNames = Protocols.RMI_JRMP; // Default to jrmp
0208:
0209:                // Holder for GenIC params
0210:                GenICParameters gp = new GenICParameters();
0211:
0212:                // Init logger
0213:                Log.configure("trace");
0214:                logger = Log.getLogger(Log.JONAS_GENIC_PREFIX);
0215:
0216:                // If no arg at all: print help message.
0217:                if (args.length == 0) {
0218:                    usage();
0219:                    return;
0220:                }
0221:                // Get args
0222:                for (int argn = 0; argn < args.length; argn++) {
0223:                    String arg = args[argn];
0224:                    if (arg.equals("-help") || arg.equals("-?")) {
0225:                        gp.setHelp(true);
0226:                        continue;
0227:                    }
0228:                    if (arg.equals("-verbose")) {
0229:                        gp.setVerbose(true);
0230:                        continue;
0231:                    }
0232:                    if (arg.equals("-debug")) {
0233:                        // deprecated
0234:                        continue;
0235:                    }
0236:                    if (arg.equals("-mappernames")) {
0237:                        argn++;
0238:                        // deprecated
0239:                        warning("The -mappernames option is ignored (deprecated)");
0240:                    }
0241:                    if (arg.equals("-protocols")) {
0242:                        argn++;
0243:                        if (argn < args.length) {
0244:                            protocolNames = args[argn];
0245:                            continue;
0246:                        } else {
0247:                            error = true;
0248:                        }
0249:                    }
0250:                    if (arg.equals("-keepgenerated")) {
0251:                        gp.setKeepGenerated(true);
0252:                        gp.getRmicOptions().add(args[argn]);
0253:                        continue;
0254:                    }
0255:                    if (arg.equals("-nocompil")) {
0256:                        gp.setCompil(false);
0257:                        gp.setKeepGenerated(true);
0258:                        continue;
0259:                    }
0260:                    if (arg.equals("-noaddinjar")) {
0261:                        gp.setAddInJar(false);
0262:                        continue;
0263:                    }
0264:                    if (arg.equals("-novalidation")) {
0265:                        gp.setParseWithValidation(false);
0266:                        continue;
0267:                    }
0268:                    if (arg.equals("-classpath")) {
0269:                        gp.setClasspathParam(args[++argn]);
0270:                        continue;
0271:                    }
0272:                    if (arg.equals("-javac")) {
0273:                        argn++;
0274:                        if (argn < args.length) {
0275:                            gp.setJavacName(args[argn]);
0276:                        } else {
0277:                            error = true;
0278:                        }
0279:                        continue;
0280:                    }
0281:                    if (arg.equals("-javacopts")) {
0282:                        argn++;
0283:                        if (argn < args.length) {
0284:                            StringTokenizer st = new StringTokenizer(args[argn]);
0285:                            while (st.hasMoreTokens()) {
0286:                                gp.getJavacOptions().add(st.nextToken());
0287:                            }
0288:                        } else {
0289:                            error = true;
0290:                        }
0291:                        continue;
0292:                    }
0293:                    if (arg.equals("-rmicopts")) {
0294:                        argn++;
0295:                        if (argn < args.length) {
0296:                            StringTokenizer st = new StringTokenizer(args[argn]);
0297:                            while (st.hasMoreTokens()) {
0298:                                gp.getRmicOptions().add(st.nextToken());
0299:                            }
0300:                        } else {
0301:                            error = true;
0302:                        }
0303:                        continue;
0304:                    }
0305:                    if (arg.equals("-d")) {
0306:                        argn++;
0307:                        if (argn < args.length) {
0308:                            gp.setOutputDirectory(args[argn]);
0309:                        } else {
0310:                            error = true;
0311:                        }
0312:                        continue;
0313:                    }
0314:                    if (arg.equals("-invokecmd")) {
0315:                        gp.setInvokeCmd(true);
0316:                        continue;
0317:                    }
0318:                    if (arg.equals("-fastrmic")) {
0319:                        argn++;
0320:                        // deprecated
0321:                        warning("The -fastrmic option is ignored as it is the default value. Use -nofastrmic to disable it.");
0322:                        continue;
0323:                    }
0324:
0325:                    if (arg.equals("-nofastrmic")) {
0326:                        argn++;
0327:                        gp.setFastRmicEnabled(false);
0328:                        continue;
0329:                    }
0330:
0331:                    gp.setInputFilename(args[argn]);
0332:                }
0333:
0334:                // Usage ?
0335:                if (gp.isHelp()) {
0336:                    usage();
0337:                    return;
0338:                }
0339:
0340:                // Check args
0341:                if (error || (gp.getInputFilename() == null)) {
0342:                    usage();
0343:                    throw new RuntimeException();
0344:                }
0345:                // The -d option is deprecated since JOnAS 3.0.7 when the file input is an ejb-jar
0346:                // Instead, the output directory must be a temporary directory to make easier
0347:                // the ejb-jar updated.
0348:                if ((gp.getOutputDirectory() != null) && gp.isAddInJar()
0349:                        && gp.getInputFilename().endsWith(".jar")) {
0350:                    warning("The -d '" + gp.getOutputDirectory()
0351:                            + "' option is ignored"
0352:                            + " (deprecated with an ejb-jar as input file)");
0353:                }
0354:
0355:                if (gp.getOutputDirectory() == null) {
0356:                    gp.setOutputDirectory("");
0357:                }
0358:
0359:                // Build the array of protocols name
0360:                gp.setProtocols(new Protocols(protocolNames, true));
0361:
0362:                // In case of ejb-jar file, the dirOutputName must be initialized with a
0363:                // tempo. directory.
0364:                if (gp.getInputFilename().endsWith(".jar") && gp.isAddInJar()) {
0365:                    try {
0366:                        gp.setOutputDirectory(GenIC.createTempDir());
0367:                    } catch (IOException ioe) {
0368:                        GenIC.fatalError(ioe);
0369:                    }
0370:                }
0371:
0372:                // Init the classpath used for javac, rmic, JRMICompiler
0373:                JClassLoader pcl = (JClassLoader) Thread.currentThread()
0374:                        .getContextClassLoader();
0375:
0376:                String classpath = pcl.getClassPath();
0377:                if (gp.getInputFilename().endsWith(".jar")) {
0378:                    classpath = gp.getInputFilename() + File.pathSeparator
0379:                            + classpath;
0380:                }
0381:                if (!"".equals(gp.getOutputDirectory())) {
0382:                    classpath = gp.getOutputDirectory() + File.pathSeparator
0383:                            + classpath;
0384:                }
0385:                // add -classpath value
0386:                if (gp.getClasspathParam() != null) {
0387:                    classpath = gp.getClasspathParam() + File.pathSeparator
0388:                            + classpath;
0389:                }
0390:
0391:                // Set the parsing mode (with or without validation)
0392:                if (!gp.isParseWithValidation()) {
0393:                    EjbDeploymentDescManager.setParsingWithValidation(false);
0394:                }
0395:
0396:                // Generates the classes for the set of the beans
0397:                try {
0398:                    DeploymentDesc ejbJarDD = null;
0399:                    if (gp.getInputFilename().endsWith(".jar")) {
0400:                        // ejb-jar file
0401:                        URL[] url = new URL[1];
0402:                        url[0] = (new File(gp.getInputFilename())).toURL();
0403:                        JClassLoader cl = new JClassLoader("GenIC-"
0404:                                + gp.getInputFilename(), url, pcl);
0405:                        if (gp.getClasspathParam() != null) {
0406:                            // add -classpath value inside ClassLoader
0407:                            addClasspath(cl, gp.getClasspathParam());
0408:                        }
0409:                        ejbJarDD = EjbDeploymentDescManager.getDeploymentDesc(
0410:                                gp.getInputFilename(), cl);
0411:                    } else {
0412:                        // xml file
0413:                        ejbJarDD = EjbDeploymentDescManager.getDeploymentDesc(
0414:                                gp.getInputFilename(),
0415:                                BeanNaming.getJonasXmlName(gp
0416:                                        .getInputFilename()), BeanNaming
0417:                                        .getParentName(gp.getInputFilename()));
0418:                    }
0419:
0420:                    GenIC gwc = new GenIC(ejbJarDD, gp);
0421:
0422:                    // Reset the beans deployment descriptors to unload the beans
0423:                    // classes
0424:                    // (loaded from the ejb-jar when creating the
0425:                    // jonas_ejb.deployment.api.BeanDesc),
0426:                    // to be able to update the ejb-jar file on Windows.
0427:                    // See Bug #270
0428:                    ejbJarDD = null;
0429:                    System.gc();
0430:
0431:                    if (gp.isCompil()) {
0432:                        gwc.compilClasses(classpath);
0433:                        if (gp.getInputFilename().endsWith(".jar")
0434:                                && gp.isAddInJar()) {
0435:                            gwc.addClassesInJar();
0436:                        }
0437:                        if (!gp.isKeepGenerated()) {
0438:                            gwc.clean();
0439:                        }
0440:                    }
0441:
0442:                    // Add into META_INF/MANIFEST jonas information for autogeneration functionnality
0443:                    if (gp.getInputFilename() != null
0444:                            && gp.getInputFilename().endsWith(".jar")
0445:                            && gp.isAddInJar()) {
0446:                        try {
0447:                            updateAttributeInManifest(gp.getInputFilename(),
0448:                                    "Genic-Jonas-Version", Version.getNumber());
0449:                            updateAttributeInManifest(gp.getInputFilename(),
0450:                                    "Genic-Jonas-protocols", gp.getProtocols()
0451:                                            .list());
0452:                        } catch (FileUtilsException e) {
0453:                            if (logger.isLoggable(BasicLevel.WARN)) {
0454:                                logger.log(BasicLevel.WARN,
0455:                                        "Cannot update the Genic attributes (version/protocols) of the application '"
0456:                                                + gp.getInputFilename() + "'.",
0457:                                        e);
0458:                            }
0459:                        }
0460:                    } else if (gp.getOutputDirectory() != null
0461:                            && !gp.isAddInJar()) {
0462:                        // case of Genic call by ant task
0463:                        // noaddinjar = true && -d specified we must add manifest into the directory output
0464:                        Manifest mf = new Manifest();
0465:                        Attributes attributes = mf.getMainAttributes();
0466:                        attributes.putValue("Genic-Jonas-Version", Version
0467:                                .getNumber());
0468:                        attributes.putValue("Genic-Jonas-protocols", gp
0469:                                .getProtocols().list());
0470:                        createManifest(gp.getOutputDirectory(), mf);
0471:                    }
0472:                } catch (MalformedURLException e) {
0473:                    GenIC.fatalError("Invalid ejb-jar file name : ", e);
0474:                } catch (GenICException e) {
0475:                    GenIC.fatalError(e);
0476:                } catch (DeploymentDescException e) {
0477:                    GenIC.fatalError(
0478:                            "Cannot read the Deployment Descriptors from "
0479:                                    + gp.getInputFilename() + ": ", e);
0480:                }
0481:                // End
0482:            }
0483:
0484:            /**
0485:             * Change the attribute value in a jar file (and update file if required)
0486:             * @param jarName : output jar file
0487:             * @param attributeName :  Name of attribute to update
0488:             * @param attributeValue : Value of attribute
0489:             * @throws FileUtilsException if update fails (replacing file with the updated file)
0490:             */
0491:            private static void updateAttributeInManifest(String jarName,
0492:                    String attributeName, String attributeValue)
0493:                    throws FileUtilsException {
0494:
0495:                // Initialize a flag that will indicate that the jar was updated.
0496:                boolean jarUpdated = false;
0497:                JarFile jar = null;
0498:                File tempJarFile = null;
0499:
0500:                File jarFile = new File(jarName);
0501:                try {
0502:                    jar = new JarFile(jarFile);
0503:
0504:                    // Create a temp jar file with no manifest. (The manifest will
0505:                    // be copied when the entries are copied.)
0506:                    tempJarFile = File.createTempFile("filetoadd", ".jar");
0507:
0508:                    JarOutputStream tempJar = new JarOutputStream(
0509:                            new FileOutputStream(tempJarFile));
0510:
0511:                    // Allocate a buffer for reading entry data.
0512:
0513:                    byte[] buffer = new byte[BUFFER_SIZE];
0514:                    int bytesRead;
0515:
0516:                    // Loop through the jar entries and add them to the temp jar,
0517:                    // skipping the entry that was added to the temp jar already.
0518:
0519:                    for (Enumeration entries = jar.entries(); entries
0520:                            .hasMoreElements();) {
0521:                        // Get the next entry.
0522:
0523:                        JarEntry entry = (JarEntry) entries.nextElement();
0524:                        String entryName = entry.getName();
0525:                        // If the entry has not been added already, add it.
0526:                        // If the entry is not the META-INF/MANIFEST.MF and it skipManifest is true
0527:                        if (!entryName.equalsIgnoreCase(MANIFEST_JAR_ENTRY)) {
0528:                            // Get an input stream for the entry.
0529:                            InputStream entryStream = jar.getInputStream(entry);
0530:                            // Read the entry and write it to the temp jar.
0531:
0532:                            tempJar.putNextEntry(entry);
0533:
0534:                            while ((bytesRead = entryStream.read(buffer)) != -1) {
0535:                                tempJar.write(buffer, 0, bytesRead);
0536:                            }
0537:                        } else {
0538:                            File tempManifestFile = File.createTempFile(
0539:                                    "MANIFEST", ".MF");
0540:                            FileOutputStream fileOutputStream = new FileOutputStream(
0541:                                    tempManifestFile);
0542:                            InputStream entryStream = jar.getInputStream(entry);
0543:
0544:                            Manifest mf = new Manifest(entryStream);
0545:
0546:                            // try to see if attribute name is present
0547:                            Attributes mainAttributes = mf.getMainAttributes();
0548:                            String existingValueAttribute = mainAttributes
0549:                                    .getValue(attributeName);
0550:
0551:                            // No value or previous entry not matching the value
0552:                            if (attributeValue != null
0553:                                    && !attributeValue
0554:                                            .equals(existingValueAttribute)) {
0555:                                // set the value
0556:                                mainAttributes.putValue(attributeName,
0557:                                        attributeValue);
0558:
0559:                                // Jar is updated
0560:                                jarUpdated = true;
0561:                            }
0562:
0563:                            // Write new Manifest
0564:                            mf.write(fileOutputStream);
0565:                            fileOutputStream.close();
0566:
0567:                            // Add the new MANIFEST
0568:                            FileInputStream fileInputManifest = new FileInputStream(
0569:                                    tempManifestFile);
0570:                            try {
0571:                                // Create a jar entry and add it to the temp jar.
0572:                                JarEntry newEntry = new JarEntry(
0573:                                        MANIFEST_JAR_ENTRY);
0574:                                tempJar.putNextEntry(newEntry);
0575:
0576:                                // Read the file and write it to the jar.
0577:
0578:                                while ((bytesRead = fileInputManifest
0579:                                        .read(buffer)) != -1) {
0580:                                    tempJar.write(buffer, 0, bytesRead);
0581:                                }
0582:                            } catch (Exception ex) {
0583:                                logger.log(BasicLevel.WARN,
0584:                                        "Can't update manifest", ex);
0585:                            } finally {
0586:                                fileInputManifest.close();
0587:                                tempManifestFile.delete();
0588:                            }
0589:                        }
0590:                    }
0591:                    jar.close();
0592:                    tempJar.close();
0593:                } catch (Exception ex) {
0594:                    logger.log(BasicLevel.ERROR, ex);
0595:                }
0596:
0597:                // Attribute has changed, need to update the file (with the updated copy)
0598:                if (jarUpdated) {
0599:                    FileUtils.copyFile(tempJarFile, jarFile);
0600:                }
0601:
0602:                // delete temp file
0603:                tempJarFile.delete();
0604:            }
0605:
0606:            /**
0607:             * Create Manifest file with name/value
0608:             * @param dirOutputName : output file
0609:             * @param manifest : The manifest file to write
0610:             * @return false if problem during file creation
0611:             */
0612:            private static boolean createManifest(String dirOutputName,
0613:                    Manifest manifest) {
0614:
0615:                // Ensure that there is the MANIFEST_VERSION
0616:                Attributes mainAttributes = manifest.getMainAttributes();
0617:                mainAttributes.putValue("Manifest-Version", "1.0");
0618:
0619:                try {
0620:                    File fileOutput = new File(dirOutputName + File.separator
0621:                            + META_DIR);
0622:
0623:                    if (!fileOutput.exists()) {
0624:                        fileOutput.mkdirs();
0625:                    }
0626:                    if (!fileOutput.exists()) {
0627:                        GenIC
0628:                                .warning("Can't create META-INF directory into temp dir : "
0629:                                        + dirOutputName + "/META-INF");
0630:                        return false;
0631:                    }
0632:
0633:                    fileOutput = new File(dirOutputName + File.separator
0634:                            + MANIFEST_PATH);
0635:                    if (!fileOutput.exists()) {
0636:                        fileOutput.createNewFile();
0637:                    }
0638:                    if (!fileOutput.exists()) {
0639:                        GenIC.warning("Can't create manifest.mf file into "
0640:                                + dirOutputName + File.separator + "META-INF");
0641:                        return false;
0642:                    }
0643:                    OutputStream os = new FileOutputStream(fileOutput);
0644:                    manifest.write(os);
0645:                    os.close();
0646:                    return true;
0647:                } catch (Exception e) {
0648:                    GenIC
0649:                            .warning("Problem during creation of META-INF/manifest.mf file into tempdir : "
0650:                                    + e.getMessage());
0651:                    e.printStackTrace();
0652:                    return false;
0653:                }
0654:            }
0655:
0656:            /**
0657:             * Add To the given ClassLoader the given classpath
0658:             * @param cl ClassLoader to be updated
0659:             * @param classpath the classpath to add inside the ClassLoader
0660:             * @throws GenICException When classpath contains invalid URL
0661:             */
0662:            private static void addClasspath(JClassLoader cl, String classpath)
0663:                    throws GenICException {
0664:                String[] elems = classpath.split(File.pathSeparator);
0665:                for (int i = 0; i < elems.length; i++) {
0666:                    try {
0667:                        cl.addURL(new File(elems[i]).toURL());
0668:                    } catch (MalformedURLException e) {
0669:                        throw new GenICException("Cannot create URL from '"
0670:                                + elems[i] + "'", e);
0671:                    }
0672:                }
0673:            }
0674:
0675:            /**
0676:             * GenIC Constructor: generates the container classes sources of each beans
0677:             * @param ejbJarDesc deployment descriptors of the beans
0678:             * @param gp GenIC parameters
0679:             * @throws GenICException In error case
0680:             */
0681:            public GenIC(DeploymentDesc ejbJarDesc, GenICParameters gp)
0682:                    throws GenICException {
0683:
0684:                // A BeanSources for each bean
0685:                ArrayList beanList = null;
0686:                this .gp = gp;
0687:
0688:                verbose = gp.isVerbose();
0689:
0690:                if (javaHomeBin == null) {
0691:                    javaHomeBin = System.getProperty("java.home", "");
0692:                    if (!("".equals(javaHomeBin))) {
0693:                        if (Env.isOsMacOsX()) {
0694:                            javaHomeBin = javaHomeBin + File.separator + "bin"
0695:                                    + File.separator;
0696:                        } else {
0697:                            javaHomeBin = javaHomeBin + File.separator + ".."
0698:                                    + File.separator + "bin" + File.separator;
0699:                        }
0700:                    }
0701:                }
0702:                outputdir = gp.getOutputDirectory();
0703:                filesToDelete = new ArrayList();
0704:                remoteJavas = new ArrayList();
0705:                noRemoteJavas = new ArrayList();
0706:                remoteClasses = new ArrayList();
0707:                beanList = new ArrayList();
0708:                BeanDesc[] beansDD = ejbJarDesc.getBeanDesc();
0709:                JormCompiler jormCompiler = null;
0710:                VelocityEngine ve = allocateVelocityEngine();
0711:                // Display the bean's names
0712:                StringBuffer message = new StringBuffer();
0713:                message.append("GenIC for JOnAS " + Version.getNumber() + ": ");
0714:                String sep = "";
0715:                for (int i = 0; i < beansDD.length; i++) {
0716:
0717:                    // If CMI is not supported, the cluster replicated parameter is set to disabled
0718:                    if (!gp.getProtocols().isSupported("cmi")) {
0719:                        if (beansDD[i].isClusterReplicated()) {
0720:                            GenIC
0721:                                    .warning("CMI protocol is not supported -> force 'cluster-replicated' to false for the bean "
0722:                                            + beansDD[i].getEjbName());
0723:                            beansDD[i].setClusterReplicated(false);
0724:                        }
0725:                    }
0726:
0727:                    BeanSources bs = null;
0728:                    if ((beansDD[i] instanceof  MessageDrivenDesc)) {
0729:                        //Nothing to generate in case of MessageDriven Bean
0730:                        continue;
0731:                    }
0732:                    if (beansDD[i] instanceof  EntityCmp2Desc) {
0733:                        if (jormCompiler == null) {
0734:                            // Load the jorm meta information of the class
0735:                            try {
0736:                                jormCompiler = allocateJormCompiler(((DeploymentDescEjb2) ejbJarDesc)
0737:                                        .getJormManager());
0738:                            } catch (DeploymentDescException e) {
0739:                                throw new GenICException(
0740:                                        "Impossible to load jorm meta information",
0741:                                        e);
0742:                            }
0743:                        }
0744:                        bs = new BeanSources(beansDD[i], gp, ve, jormCompiler);
0745:                    } else {
0746:                        bs = new BeanSources(beansDD[i], gp, ve);
0747:                    }
0748:                    beanList.add(bs);
0749:                    //compute message
0750:                    message.append(sep);
0751:                    sep = ", ";
0752:                    message.append("'");
0753:                    message.append(bs.getEjbName());
0754:                    message.append("'");
0755:                }
0756:                generatedIC = !beanList.isEmpty();
0757:                if (generatedIC) {
0758:                    message.append(" generation ...");
0759:                } else {
0760:                    message
0761:                            .append("No generation to do (only message driven beans)");
0762:                }
0763:                GenIC.info(message.toString());
0764:
0765:                // Generates the sources of the container classes of the beans
0766:                // and Init the lists of the remote/non-remote java sources and the
0767:                // remote classes
0768:                for (Iterator it = beanList.iterator(); it.hasNext();) {
0769:                    BeanSources ics = (BeanSources) it.next();
0770:                    ics.generate();
0771:                    String cchfn = ics.getWrpHomeClusterFileName();
0772:                    if (cchfn != null) {
0773:                        filesToDelete.add(cchfn);
0774:                    }
0775:                    String ccrfn = ics.getWrpRemoteClusterFileName();
0776:                    if (ccrfn != null) {
0777:                        filesToDelete.add(ccrfn);
0778:                    }
0779:                    trace("Sources classes successfully generated" + " for '"
0780:                            + ics.getEjbName() + "'");
0781:                    noRemoteJavas.addAll(ics.getNoRemoteJavas());
0782:                    if (ics.getWrpHomeFileName() != null) {
0783:                        remoteJavas.add(ics.getWrpHomeFileName());
0784:                        remoteClasses.add(ics.getWrpHomeClassName());
0785:                    }
0786:                    if (ics.getWrpRemoteFileName() != null) {
0787:                        remoteJavas.add(ics.getWrpRemoteFileName());
0788:                        remoteClasses.add(ics.getWrpRemoteClassName());
0789:                    }
0790:                    if (ics.getWrpServiceEndpointFileName() != null) {
0791:                        remoteJavas.add(ics.getWrpServiceEndpointFileName());
0792:                        remoteClasses.add(ics.getWrpServiceEndpointClassName());
0793:                    }
0794:                }
0795:                jormCompiler = null;
0796:
0797:            }
0798:
0799:            /**
0800:             * Allocate and configure a JORM compiler
0801:             * @param miManager the JORM Meta-Information manager
0802:             * @return a JORM compiler
0803:             */
0804:            private JormCompiler allocateJormCompiler(Manager miManager) {
0805:                // Allocate and configure a Jorm Compiler
0806:                JormCompiler jormCompiler = new JormCompiler();
0807:                JormCompilerConfigurator jcc = jormCompiler
0808:                        .getCompilerConfigurator();
0809:                Properties prop = new Properties();
0810:                prop.put("jorm.generator",
0811:                        "org.objectweb.jorm.generator.lib.JormGenerator");
0812:                prop.put("jorm.mimanager",
0813:                        "org.objectweb.jorm.metainfo.lib.JormManager");
0814:                prop.put("jorm.writer",
0815:                        "org.objectweb.jorm.mi2xml.lib.BasicDomWriter");
0816:                prop.put("jorm.mapper.list", "rdb");
0817:                prop
0818:                        .put("jorm.mapper.mifactory.rdb",
0819:                                "org.objectweb.jorm.mapper.rdb.metainfo.RdbMappingFactory");
0820:                prop
0821:                        .put("jorm.mapper.mopfactory.rdb",
0822:                                "org.objectweb.jorm.mapper.rdb.generator.RdbMOPFactory");
0823:                prop
0824:                        .put("jorm.mapper.gcmapping.rdb",
0825:                                "org.objectweb.jorm.mapper.rdb.genclass.RdbGenClassMapping");
0826:                prop
0827:                        .put("jorm.mapper.schmgr.rdb",
0828:                                "org.objectweb.jorm.mapper.rdb.lib.RdbPMappingStructuresManager");
0829:                prop
0830:                        .put("jorm.mapper.writer.rdb",
0831:                                "org.objectweb.jorm.mapper.rdb.mi2xml.RdbDomtreeBuilder");
0832:                prop.put("use.context.classloader", "true");
0833:                prop.put("jorm.mapper.submappers.rdb", "generic");
0834:                jcc.configure(prop);
0835:                jcc.setLoggerFactory(Log.getLoggerFactory());
0836:                jormCompiler.setMIManager(miManager);
0837:                return jormCompiler;
0838:            }
0839:
0840:            /**
0841:             * Allocate and configure a Velocity Engine
0842:             * @return the Velocity Engine
0843:             * @throws GenICException in error case
0844:             */
0845:            private VelocityEngine allocateVelocityEngine()
0846:                    throws GenICException {
0847:                VelocityEngine ve = new VelocityEngine();
0848:                ve.setProperty(RuntimeConstants.VM_LIBRARY, "GenICMacros.vm");
0849:                ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "file");
0850:
0851:                String jonasRoot = System.getProperty(INSTALL_ROOT_PROPERTY);
0852:                if (jonasRoot == null) {
0853:                    throw new GenICException("System property '"
0854:                            + INSTALL_ROOT_PROPERTY + "' not set");
0855:                }
0856:                String path2Tmpl = new String(jonasRoot + File.separatorChar
0857:                        + "templates" + File.separatorChar + "genic");
0858:                ve.setProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH,
0859:                        path2Tmpl);
0860:                // Velocity logs
0861:                Logger vLogger = Log.getLogger(Log.JONAS_GENIC_VELOCITY_PREFIX);
0862:                if (vLogger.isLoggable(BasicLevel.DEBUG)) {
0863:                    // No more velocity logs to avoid the creation of an empty file
0864:                    // "velocity.log"
0865:                    ve.setProperty(
0866:                            RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS,
0867:                            "org.apache.velocity.runtime.log.NullLogSystem");
0868:                } else {
0869:                    // Connect the velocity log system to monolog
0870:                    ve.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM,
0871:                            new VelocityLogger(vLogger));
0872:                }
0873:                try {
0874:                    ve.init();
0875:                } catch (Exception e) {
0876:                    throw new GenICException(
0877:                            "Cannot initialize the Velocity engine", e);
0878:                }
0879:                return ve;
0880:            }
0881:
0882:            /**
0883:             * Compiles the java sources generated by the constructor I.e. :
0884:             * <ul>
0885:             * <li>compile the classes via javac,
0886:             * <li>create the stubs and skeletons for the protocols supported(RMI/JRMP,
0887:             * RMI/IIOP,JEREMIE) via rmic/jrmic
0888:             * </ul>
0889:             * @param classpath classpath value
0890:             * @exception GenICException In error case
0891:             */
0892:            public void compilClasses(String classpath) throws GenICException {
0893:
0894:                Cmd jrmpCmd;
0895:                Cmd iiopCmd;
0896:                Cmd jeremieCmd;
0897:                Cmd cmd;
0898:
0899:                String cmdJava;
0900:                String cmdJavac;
0901:                String cmdRmic;
0902:
0903:                if (!generatedIC) {
0904:                    return;
0905:                }
0906:
0907:                /*
0908:                 * Init the command names
0909:                 */
0910:                cmdJava = javaHomeBin + "java";
0911:                if (gp.getJavacName() == null) {
0912:                    cmdJavac = javaHomeBin + "javac";
0913:                } else {
0914:                    cmdJavac = gp.getJavacName();
0915:                }
0916:                cmdRmic = javaHomeBin + "rmic";
0917:
0918:                /*
0919:                 * Compile the generated sources
0920:                 */
0921:                if (!new File(cmdJavac).exists()) {
0922:                    // Maybe this is on windows
0923:                    if (!new File(cmdJavac + ".exe").exists()) {
0924:                        logger
0925:                                .log(
0926:                                        BasicLevel.INFO,
0927:                                        "No javac command was found at '"
0928:                                                + cmdJavac
0929:                                                + "'. Check that you are using a JDK and not a JRE.");
0930:                    }
0931:                }
0932:                cmd = new Cmd(cmdJavac, gp.isInvokeCmd());
0933:                cmd.addArgument("-classpath");
0934:                cmd.addArgument(classpath);
0935:                cmd.addArgument("-d");
0936:                if ((outputdir.length() == 0)) {
0937:                    cmd.addArgument(".");
0938:                } else {
0939:                    cmd.addArgument(outputdir);
0940:                }
0941:                cmd.addArguments(gp.getJavacOptions());
0942:
0943:                for (Iterator it = remoteJavas.iterator(); it.hasNext();) {
0944:                    String srcName = (String) it.next();
0945:                    cmd.addArgument(srcName);
0946:                    filesToDelete.add(srcName);
0947:                }
0948:                for (Iterator it = noRemoteJavas.iterator(); it.hasNext();) {
0949:                    String srcName = (String) it.next();
0950:                    cmd.addArgument(srcName);
0951:                    filesToDelete.add(srcName);
0952:                }
0953:
0954:                trace("Running '" + cmd.toString() + "'");
0955:                if (cmd.run()) {
0956:                    trace("Sources classes successfully compiled via java compiler.");
0957:                } else {
0958:                    throw new GenICException(
0959:                            "Failed when compiling the generated classes via java compiler");
0960:                }
0961:
0962:                if (remoteJavas.size() == 0) {
0963:                    return;
0964:                }
0965:
0966:                /*
0967:                 * Generate the stub and skeletons of the home and remote implementations
0968:                 */
0969:
0970:                if (!new File(cmdRmic).exists()) {
0971:                    // Maybe this is on windows
0972:                    if (!new File(cmdRmic + ".exe").exists()) {
0973:                        logger
0974:                                .log(
0975:                                        BasicLevel.INFO,
0976:                                        "No rmic command was found at '"
0977:                                                + cmdRmic
0978:                                                + "'. Check that you are using a JDK and not a JRE.");
0979:                    }
0980:                }
0981:                jrmpCmd = new Cmd(cmdRmic);
0982:                jrmpCmd.addArgument("-classpath");
0983:                jrmpCmd.addArgument(classpath);
0984:
0985:                iiopCmd = new Cmd(cmdRmic);
0986:                iiopCmd.addArgument("-classpath");
0987:                iiopCmd.addArgument(classpath);
0988:                iiopCmd.addArgument("-iiop");
0989:                iiopCmd.addArgument("-poa");
0990:                iiopCmd.addArgument("-always");
0991:
0992:                jeremieCmd = new Cmd(cmdJava);
0993:                jeremieCmd.addArgument("-classpath");
0994:                jeremieCmd.addArgument(classpath);
0995:                jeremieCmd
0996:                        .addArgument("org.objectweb.jeremie.tools.jrmic.JRMICompiler");
0997:                jeremieCmd.addArgument("-opt");
0998:                jeremieCmd.addArgument("-owext");
0999:                if (gp.getJavacName() != null) {
1000:                    jeremieCmd.addArgument("-c");
1001:                    jeremieCmd.addArgument(gp.getJavacName());
1002:                }
1003:
1004:                if (!"".equals(outputdir)) {
1005:                    jrmpCmd.addArgument("-d");
1006:                    jrmpCmd.addArgument(outputdir);
1007:                    iiopCmd.addArgument("-d");
1008:                    iiopCmd.addArgument(outputdir);
1009:                    jeremieCmd.addArgument("-d");
1010:                    jeremieCmd.addArgument(outputdir);
1011:                }
1012:
1013:                jrmpCmd.addArguments(gp.getRmicOptions());
1014:                iiopCmd.addArguments(gp.getRmicOptions());
1015:                jeremieCmd.addArguments(gp.getRmicOptions());
1016:
1017:                for (Iterator it = remoteClasses.iterator(); it.hasNext();) {
1018:                    String className = (String) it.next();
1019:                    jrmpCmd.addArgument(className);
1020:                    iiopCmd.addArgument(className);
1021:                    jeremieCmd.addArgument(className);
1022:                }
1023:
1024:                // Use fast rmic, if there are failures, fallback to rmic
1025:                if (gp.getProtocols().isSupported(Protocols.RMI_JRMP)
1026:                        && gp.isFastRmicEnabled()) {
1027:                    trace("Running fastrmic for '" + jrmpCmd.toString() + "'");
1028:                    ArrayList args = new ArrayList();
1029:                    boolean skip = true;
1030:                    for (Iterator it = jrmpCmd.getCommandLine(); it.hasNext();) {
1031:                        Object o = it.next();
1032:                        if (skip) {
1033:                            skip = false;
1034:                            continue;
1035:                        }
1036:                        args.add(o);
1037:                    }
1038:
1039:                    String[] a = (String[]) args.toArray(new String[] {});
1040:                    Method m = null;
1041:                    try {
1042:                        Class c = Class.forName("org.objectweb.fastrmic.RMIC");
1043:                        m = c.getMethod("main", new Class[] { String[].class });
1044:                    } catch (ClassNotFoundException cnfe) {
1045:                        logger.log(BasicLevel.ERROR,
1046:                                "continuing after class not found ", cnfe);
1047:                        gp.setFastRmicEnabled(false);
1048:                    } catch (NoSuchMethodException nsme) {
1049:                        logger.log(BasicLevel.ERROR,
1050:                                "continuing after no such method ", nsme);
1051:                        gp.setFastRmicEnabled(false);
1052:                    }
1053:
1054:                    if (m != null) {
1055:                        try {
1056:                            m.invoke(null, new Object[] { a });
1057:                            // Call to the GC for bug (#303750)
1058:                            // fastRMIC load classes of the jar, then there is a lock on the file until the GC is called.
1059:                            System.gc();
1060:                        } catch (IllegalAccessException iae) {
1061:                            logger.log(BasicLevel.ERROR,
1062:                                    "continuing after illegal access", iae);
1063:                            gp.setFastRmicEnabled(false);
1064:                        } catch (InvocationTargetException ite) {
1065:                            throw new GenICException("error in fastrmic", ite);
1066:                        }
1067:                        info("Stubs and Skels successfully generated with fastrmic for rmi/jrmp");
1068:                    }
1069:                }
1070:
1071:                if (gp.getProtocols().isSupported(Protocols.RMI_JRMP)
1072:                        && !gp.isFastRmicEnabled()) {
1073:                    trace("Running '" + jrmpCmd.toString() + "'");
1074:                    if (jrmpCmd.run()) {
1075:                        info("Stubs and Skels successfully generated for rmi/jrmp");
1076:                    } else {
1077:                        throw new GenICException(
1078:                                "Failed when generating the Stubs and Skels with rmic jrmp");
1079:                    }
1080:                }
1081:
1082:                if (gp.getProtocols().isSupported(Protocols.RMI_IIOP)) {
1083:                    trace("Running '" + iiopCmd.toString() + "'");
1084:                    if (iiopCmd.run()) {
1085:                        info("Stubs and Skels successfully generated for rmi/iiop");
1086:                    } else {
1087:                        throw new GenICException(
1088:                                "Failed when generating the Stubs and Skels with rmic iiop");
1089:                    }
1090:
1091:                }
1092:
1093:                if (gp.getProtocols().isSupported(Protocols.JEREMIE)) {
1094:                    trace("Running '" + jeremieCmd.toString() + "'");
1095:                    if (jeremieCmd.run()) {
1096:                        info("Stubs and Skels successfully generated with rmi/jeremie");
1097:                    } else {
1098:                        throw new GenICException(
1099:                                "Failed when generating the Stubs and Skels with jeremie jrmic");
1100:                    }
1101:                }
1102:            }
1103:
1104:            /**
1105:             * Add the generated classes in the given ejb-jar file.
1106:             * @throws GenICException if the classes cannot be added in the jar file
1107:             */
1108:            public void addClassesInJar() throws GenICException {
1109:
1110:                if (!generatedIC) {
1111:                    return;
1112:                }
1113:
1114:                filesToDelete.add(outputdir);
1115:
1116:                ArrayList lf = new ArrayList();
1117:                getFilesList(outputdir, lf, !gp.isKeepGenerated());
1118:
1119:                updateJar(gp.getInputFilename(), outputdir, lf);
1120:
1121:            }
1122:
1123:            /**
1124:             * Convert a name from any format in Jar filename format
1125:             * @param name filename to be converted
1126:             * @return converted filename
1127:             */
1128:            protected String convertName(String name) {
1129:                return name.replace('\\', '/');
1130:            }
1131:
1132:            /**
1133:             * Add some classes in an existing jar file via the java.util.jar api.
1134:             * @param jfn jar filename
1135:             * @param od base directory of generated files
1136:             * @param lfn list of filenames to add
1137:             * @throws GenICException if the classes cannot be added
1138:             */
1139:            private void updateJar(String jfn, String od, List lfn)
1140:                    throws GenICException {
1141:
1142:                File jarFile = null;
1143:                File tempJarFile = null;
1144:                JarFile jarArchive = null;
1145:                JarOutputStream tempJarArchive = null;
1146:
1147:                try {
1148:                    jarFile = new File(jfn);
1149:                    tempJarFile = new File(jfn + ".tmp");
1150:
1151:                    // open existing jar file
1152:                    jarArchive = new JarFile(jarFile);
1153:
1154:                    // create temporary jar
1155:                    tempJarArchive = new JarOutputStream(new FileOutputStream(
1156:                            tempJarFile));
1157:
1158:                    byte[] buffer = new byte[BUFFER_SIZE];
1159:                    int read = 0;
1160:
1161:                    // Add all generated files to temporary jar
1162:                    FileInputStream file = null;
1163:                    int is = od.length() + 1;
1164:                    Iterator iterFiles = lfn.iterator();
1165:                    while (iterFiles.hasNext()) {
1166:                        try {
1167:                            String fileName = (String) iterFiles.next();
1168:
1169:                            file = new FileInputStream(fileName);
1170:                            JarEntry entry = new JarEntry(convertName(fileName
1171:                                    .substring(is)));
1172:                            tempJarArchive.putNextEntry(entry);
1173:                            // contents
1174:                            while ((read = file.read(buffer)) != -1) {
1175:                                tempJarArchive.write(buffer, 0, read);
1176:                            }
1177:                        } finally {
1178:                            file.close();
1179:                        }
1180:                    }
1181:
1182:                    // Add the rest of files (except if already included)
1183:                    Enumeration ents = jarArchive.entries();
1184:                    while (ents.hasMoreElements()) {
1185:                        JarEntry entry = (JarEntry) ents.nextElement();
1186:                        // add only if there is not a newer version
1187:                        // already included
1188:                        // In a windows plateform we must replace / by \ for a correct path
1189:                        if (!lfn.contains(od
1190:                                + File.separator
1191:                                + entry.getName().replace('/',
1192:                                        File.separatorChar))) {
1193:                            InputStream enStream = jarArchive
1194:                                    .getInputStream(entry);
1195:                            tempJarArchive.putNextEntry(entry);
1196:                            // contents
1197:                            while ((read = enStream.read(buffer)) != -1) {
1198:                                tempJarArchive.write(buffer, 0, read);
1199:                            }
1200:                        }
1201:                    }
1202:
1203:                } catch (Exception e) {
1204:                    throw new GenICException(
1205:                            "Failed when adding the generated classes "
1206:                                    + "in the given ejb-jar file '" + jfn
1207:                                    + "': " + e);
1208:                } finally {
1209:                    // close jar archives
1210:                    try {
1211:                        jarArchive.close();
1212:                    } catch (IOException e1) {
1213:                        warning("Failed to close jar archive file '"
1214:                                + jarArchive.getName());
1215:                    }
1216:                    try {
1217:                        tempJarArchive.close();
1218:                    } catch (IOException e1) {
1219:                        warning("Failed to close temporary jar archive file '"
1220:                                + jarArchive.getName() + "'");
1221:                    }
1222:                }
1223:
1224:                // Copy temporary jar file -> original jar
1225:                boolean deleted = jarFile.delete();
1226:                boolean rename = tempJarFile.renameTo(jarFile);
1227:                if (!deleted || !rename) {
1228:                    error("Failed to update jar archive file '"
1229:                            + jarArchive.getName() + "'");
1230:                }
1231:            }
1232:
1233:            /**
1234:             * Clean the intermediate generated files.
1235:             */
1236:            public void clean() {
1237:                trace("Deleting " + filesToDelete.toString());
1238:                for (Iterator it = filesToDelete.iterator(); it.hasNext();) {
1239:                    String name = (String) it.next();
1240:                    File f = new File(name);
1241:                    delete(f);
1242:                }
1243:            }
1244:
1245:            /**
1246:             * Delete a file or directory recursively
1247:             * @param f file or directory to be deleted
1248:             * @return true if deletion ok, false otherwise.
1249:             */
1250:            private boolean delete(File f) {
1251:                if (f.isFile()) {
1252:                    return f.delete();
1253:                } else {
1254:                    File[] childs = f.listFiles();
1255:                    if (childs == null) {
1256:                        // no childs
1257:                        return f.delete();
1258:                    } else {
1259:                        // childs
1260:                        boolean result = true;
1261:                        for (int i = 0; i < childs.length; i++) {
1262:                            result &= delete(childs[i]);
1263:                        }
1264:                        return result && f.delete();
1265:                    }
1266:                }
1267:            }
1268:
1269:            /**
1270:             * Display the usage
1271:             */
1272:            static void usage() {
1273:                StringBuffer msg = new StringBuffer();
1274:                msg
1275:                        .append("Usage: java org.objectweb.jonas_ejb.genic.GenIC -help \n");
1276:                msg.append("         to print this help message \n");
1277:                msg
1278:                        .append(" or    java org.objectweb.jonas_ejb.genic.GenIC <Options> <Input_File> \n");
1279:                msg
1280:                        .append("         to generate the container-specific classes for given EJB(s). \n");
1281:                msg.append(" \n");
1282:                msg.append("Options include: \n");
1283:                msg
1284:                        .append("       -d <output_dir>  specify where to place the generated files \n");
1285:                msg
1286:                        .append("       -noaddinjar      do not add the generated classes in the given \n");
1287:                msg.append("                        ejb-jar file \n");
1288:                msg
1289:                        .append("       -nocompil        do not compile the generated source files via \n");
1290:                msg
1291:                        .append("                        the java and rmi compilers \n");
1292:                msg
1293:                        .append("       -novalidation    parse the XML deployment descriptors without \n");
1294:                msg.append("                        validation \n");
1295:                msg
1296:                        .append("       -classpath <path> define the classpath to be used to compile classes \n");
1297:                msg
1298:                        .append("       -javac     <opt> specify the java compiler to use \n");
1299:                msg
1300:                        .append("       -javacopts <opt> specify the options to pass to the java compiler \n");
1301:                msg
1302:                        .append("       -rmicopts  <opt> specify the options to pass to the rmi compiler \n");
1303:                msg
1304:                        .append("       -protocols       list of protocol, separated by comma \n");
1305:                msg.append("                        (default is jrmp) \n");
1306:                msg
1307:                        .append("       -invokecmd       invoke, in some case, directly the method of the java class\n");
1308:                msg
1309:                        .append("                        corresponding to the command \n");
1310:                msg
1311:                        .append("       -keepgenerated   do not delete intermediate generated source files \n");
1312:                msg.append("       -verbose \n");
1313:                msg
1314:                        .append("       -debug           deprecated (use the JOnAS trace properties file)\n");
1315:                msg.append(" \n");
1316:                msg
1317:                        .append("       Input_File       standard deployment descriptor file's name or \n");
1318:                msg.append("                        ejb-jar file's name \n");
1319:                GenIC.info(msg.toString());
1320:            }
1321:
1322:            /**
1323:             * Display the specified message only if verbose.
1324:             * @param msg the message to display
1325:             */
1326:            void trace(String msg) {
1327:                int level = BasicLevel.DEBUG;
1328:                if (verbose) {
1329:                    level = BasicLevel.INFO;
1330:                }
1331:                logger.log(level, msg);
1332:            }
1333:
1334:            /**
1335:             * Display the specified message.
1336:             * @param msg the message to display
1337:             */
1338:            static void info(String msg) {
1339:                logger.log(BasicLevel.INFO, msg);
1340:            }
1341:
1342:            /**
1343:             * Display the specified warning message.
1344:             * @param msg the warning message to display
1345:             */
1346:            static void warning(String msg) {
1347:                logger.log(BasicLevel.WARN, msg);
1348:            }
1349:
1350:            /**
1351:             * Display the specified error message.
1352:             * @param msg the error message to display
1353:             */
1354:            static void error(String msg) {
1355:                logger.log(BasicLevel.ERROR, msg);
1356:            }
1357:
1358:            /**
1359:             * Display the specified error message and exits with an EXIT_FAILURE
1360:             * status.
1361:             * @param msg the error message to display
1362:             * @param e the exception raised
1363:             */
1364:            static void fatalError(String msg, Exception e) {
1365:                error("GenIC fatal error: " + msg + e.getMessage());
1366:                throw new RuntimeException(msg);
1367:            }
1368:
1369:            /**
1370:             * Display the specified error message and exits with an EXIT_FAILURE
1371:             * status.
1372:             * @param e the error to display
1373:             */
1374:            static void fatalError(Exception e) {
1375:                System.err.println("GenIC fatal error: ");
1376:                printException(e, System.err);
1377:                throw new RuntimeException(e.getMessage());
1378:            }
1379:
1380:            /**
1381:             * Display the exception and its nested exception if exists, on the given
1382:             * printstream.
1383:             * @param e the exception to display
1384:             * @param out the PrintStream on which the exception has to displayed
1385:             */
1386:            static void printException(Exception e, PrintStream out) {
1387:                Exception inner = null;
1388:                if (e instanceof  GenICException
1389:                        && (inner = ((GenICException) e).inner) != null) {
1390:                    out.println(e.getMessage());
1391:                    printException(inner, out);
1392:                } else if (e instanceof  PException
1393:                        && (inner = ((PException) e).getNestedException()) != null) {
1394:                    out.println(e.getMessage());
1395:                    printException(inner, out);
1396:                } else if (e instanceof  MedorException
1397:                        && (inner = ((MedorException) e).getNestedException()) != null) {
1398:                    out.println(e.getMessage());
1399:                    printException(inner, out);
1400:                } else {
1401:                    e.printStackTrace();
1402:                }
1403:            }
1404:
1405:            /**
1406:             * Create a cleaned temporary directory.
1407:             * @return the temp directory file name
1408:             * @throws IOException if a temp directory cannot be created.
1409:             */
1410:            static String createTempDir() throws IOException {
1411:                File tmpDir = File.createTempFile("genic", null, null);
1412:                tmpDir.delete();
1413:                if (!tmpDir.mkdir()) {
1414:                    throw new IOException(
1415:                            "Cannot create the temporary directory '" + tmpDir
1416:                                    + "'.");
1417:                }
1418:                return tmpDir.getAbsolutePath();
1419:            }
1420:
1421:            /**
1422:             * Get the list file names recursively of the given directory
1423:             * @param dir the directory used to list files
1424:             * @param list list to store filenames
1425:             * @param onlyClass stores only class or not ?
1426:             */
1427:            static void getFilesList(String dir, ArrayList list,
1428:                    boolean onlyClass) {
1429:                File df = new File(dir);
1430:                if (df.exists() && df.isDirectory()) {
1431:                    File[] ls = df.listFiles();
1432:                    for (int i = 0; i < ls.length; i++) {
1433:                        File f = ls[i];
1434:                        String fn = f.getAbsolutePath();
1435:                        if (f.isDirectory()) {
1436:                            getFilesList(fn, list, onlyClass);
1437:                        } else {
1438:                            if (!onlyClass || fn.endsWith(".class")) {
1439:                                if (!fn.endsWith(".save")) {
1440:                                    list.add(fn);
1441:                                }
1442:                            }
1443:                        }
1444:                    }
1445:                }
1446:            }
1447:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.