GenIC.java

00001 
00026 package org.objectweb.jonas_ejb.genic;
00027 
00028 import java.io.File;
00029 import java.io.FileInputStream;
00030 import java.io.FileOutputStream;
00031 import java.io.IOException;
00032 import java.io.InputStream;
00033 import java.io.PrintStream;
00034 import java.lang.reflect.InvocationTargetException;
00035 import java.lang.reflect.Method;
00036 import java.net.MalformedURLException;
00037 import java.net.URL;
00038 import java.util.ArrayList;
00039 import java.util.Enumeration;
00040 import java.util.Iterator;
00041 import java.util.List;
00042 import java.util.StringTokenizer;
00043 import java.util.Properties;
00044 import java.util.TreeSet;
00045 import java.util.jar.JarEntry;
00046 import java.util.jar.JarFile;
00047 import java.util.jar.JarOutputStream;
00048 
00049 import org.objectweb.common.Cmd;
00050 import org.objectweb.common.Env;
00051 
00052 import org.objectweb.jonas_ejb.deployment.api.BeanDesc;
00053 import org.objectweb.jonas_ejb.deployment.api.DeploymentDesc;
00054 import org.objectweb.jonas_ejb.deployment.api.DeploymentDescEjb2;
00055 import org.objectweb.jonas_ejb.deployment.api.EntityCmp2Desc;
00056 import org.objectweb.jonas_ejb.deployment.api.MessageDrivenDesc;
00057 import org.objectweb.jonas_ejb.deployment.lib.EjbDeploymentDescManager;
00058 import org.objectweb.jonas_ejb.lib.BeanNaming;
00059 
00060 import org.objectweb.jonas_lib.deployment.api.DeploymentDescException;
00061 import org.objectweb.jonas_lib.version.Version;
00062 
00063 import org.objectweb.jonas.common.Log;
00064 import org.objectweb.jonas.server.JClassLoader;
00065 
00066 import org.objectweb.jorm.api.PException;
00067 import org.objectweb.jorm.compiler.api.JormCompilerConfigurator;
00068 import org.objectweb.jorm.compiler.lib.JormCompiler;
00069 import org.objectweb.jorm.metainfo.api.Manager;
00070 
00071 import org.objectweb.medor.api.MedorException;
00072 
00073 import org.objectweb.util.monolog.api.BasicLevel;
00074 import org.objectweb.util.monolog.api.Logger;
00075 import org.objectweb.util.monolog.wrapper.velocity.VelocityLogger;
00076 
00077 import org.apache.velocity.app.VelocityEngine;
00078 import org.apache.velocity.runtime.RuntimeConstants;
00079 
00097 public class GenIC {
00098 
00102     public static final String RMI_JRMP = "jrmp";
00103 
00107     public static final String RMI_IIOP = "iiop";
00108 
00112     public static final String JEREMIE = "jeremie";
00113 
00117     public static final String CMI_RMI = "cmi";
00118 
00122     private static final String INSTALL_ROOT_PROPERTY = "install.root";
00123 
00127     private static String javaHomeBin = null;
00128 
00132     private boolean verbose = false;
00133 
00137     private String outputdir = null;
00138 
00142     private boolean generatedIC;
00143 
00147     private ArrayList filesToDelete = null;
00148 
00152     private ArrayList remoteJavas = null;
00153 
00157     private ArrayList noRemoteJavas = null;
00158 
00162     private ArrayList remoteClasses = null;
00163 
00167     private ArrayList clusterConfs = null;
00168 
00172     private ArrayList clusteredClasses = null;
00173 
00177     private static Logger logger = null;
00178 
00182     private static final int BUFFER_SIZE = 1024;
00183 
00220     public static void main(String[] args) {
00221         boolean error = false;
00222 
00223         boolean isHelp = false;
00224         boolean isVerbose = false;
00225         boolean isKeepGenerated = false;
00226         boolean isCompil = true;
00227         boolean isAddInJar = true;
00228         boolean parseWithValidation = true;
00229         boolean invokeCmd = false;
00230 
00231         String fileInputName = null;
00232         String dirOutputName = null;
00233         String nameJavac = null;
00234         ArrayList optionsJavaC = new ArrayList();
00235         ArrayList optionsRmiC = new ArrayList();
00236         String protocols = RMI_JRMP; // Default: generate for jrmp
00237         ProtocolNames protocolsNames = null;
00238         String classpathParam = null;
00239 
00240         // Init logger
00241         Log.configure("trace");
00242         logger = Log.getLogger(Log.JONAS_GENIC_PREFIX);
00243 
00244         // Get args
00245         for (int argn = 0; argn < args.length; argn++) {
00246             String arg = args[argn];
00247             if (arg.equals("-help") || arg.equals("-?")) {
00248                 isHelp = true;
00249                 continue;
00250             }
00251             if (arg.equals("-verbose")) {
00252                 isVerbose = true;
00253                 continue;
00254             }
00255             if (arg.equals("-debug")) {
00256                 // deprecated
00257                 continue;
00258             }
00259             if (arg.equals("-mappernames")) {
00260                 argn++;
00261                 // deprecated
00262                 warning("The -mappernames option is ignored (deprecated)");
00263             }
00264             if (arg.equals("-protocols")) {
00265                 argn++;
00266                 if (argn < args.length) {
00267                     protocols = args[argn];
00268                     continue;
00269                 } else {
00270                     error = true;
00271                 }
00272 
00273             }
00274             if (arg.equals("-keepgenerated")) {
00275                 isKeepGenerated = true;
00276                 optionsRmiC.add(args[argn]);
00277                 continue;
00278             }
00279             if (arg.equals("-nocompil")) {
00280                 isCompil = false;
00281                 isKeepGenerated = true;
00282                 continue;
00283             }
00284             if (arg.equals("-noaddinjar")) {
00285                 isAddInJar = false;
00286                 continue;
00287             }
00288             if (arg.equals("-novalidation")) {
00289                 parseWithValidation = false;
00290                 continue;
00291             }
00292             if (arg.equals("-classpath")) {
00293                 classpathParam = args[++argn];
00294                 continue;
00295             }
00296             if (arg.equals("-javac")) {
00297                 argn++;
00298                 if (argn < args.length) {
00299                     nameJavac = args[argn];
00300                 } else {
00301                     error = true;
00302                 }
00303                 continue;
00304             }
00305             if (arg.equals("-javacopts")) {
00306                 argn++;
00307                 if (argn < args.length) {
00308                     StringTokenizer st = new StringTokenizer(args[argn]);
00309                     while (st.hasMoreTokens()) {
00310                         optionsJavaC.add(st.nextToken());
00311                     }
00312                 } else {
00313                     error = true;
00314                 }
00315                 continue;
00316             }
00317             if (arg.equals("-rmicopts")) {
00318                 argn++;
00319                 if (argn < args.length) {
00320                     StringTokenizer st = new StringTokenizer(args[argn]);
00321                     while (st.hasMoreTokens()) {
00322                         optionsRmiC.add(st.nextToken());
00323                     }
00324                 } else {
00325                     error = true;
00326                 }
00327                 continue;
00328             }
00329             if (arg.equals("-d")) {
00330                 argn++;
00331                 if (argn < args.length) {
00332                     dirOutputName = args[argn];
00333                 } else {
00334                     error = true;
00335                 }
00336                 continue;
00337             }
00338             if (arg.equals("-invokecmd")) {
00339                 invokeCmd = true;
00340                 continue;
00341             }
00342             fileInputName = args[argn];
00343         }
00344 
00345         // Usage ?
00346         if (isHelp) {
00347             usage();
00348             return;
00349         }
00350 
00351         // Check args
00352         if (error || (fileInputName == null)) {
00353             usage();
00354             throw new RuntimeException();
00355         }
00356         // The -d option is deprecated since JOnAS 3.0.7 when the file input is an ejb-jar
00357         // Instead, the output directory must be a temporary directory to make easier
00358         // the ejb-jar updated.
00359         if ((dirOutputName != null) && isAddInJar && fileInputName.endsWith(".jar")) {
00360             warning("The -d '" + dirOutputName + "' option is ignored" + " (deprecated with an ejb-jar as input file)");
00361         }
00362 
00363         if (dirOutputName == null) {
00364             dirOutputName = new String("");
00365         }
00366 
00367         // Build the array of protocols name
00368         protocolsNames = new ProtocolNames(protocols);
00369 
00370         // In case of ejb-jar file, the dirOutputName must be initialized with a
00371         // tempo. directory.
00372         if (fileInputName.endsWith(".jar") && isAddInJar) {
00373             try {
00374                 dirOutputName = GenIC.createTempDir();
00375             } catch (IOException ioe) {
00376                 GenIC.fatalError(ioe);
00377             }
00378         }
00379 
00380         // Init the classpath used for javac, rmic, JRMICompiler
00381         JClassLoader pcl = (JClassLoader) Thread.currentThread().getContextClassLoader();
00382 
00383         String classpath = pcl.getClassPath();
00384         if (fileInputName.endsWith(".jar")) {
00385             classpath = fileInputName + File.pathSeparator + classpath;
00386         }
00387         if (!"".equals(dirOutputName)) {
00388             classpath = dirOutputName + File.pathSeparator + classpath;
00389         }
00390         // add -classpath value
00391         if (classpathParam != null) {
00392             classpath = classpathParam + File.pathSeparator + classpath;
00393         }
00394 
00395         // Set the parsing mode (with or without validation)
00396         if (!parseWithValidation) {
00397             EjbDeploymentDescManager.setParsingWithValidation(false);
00398         }
00399 
00400         // Generates the classes for the set of the beans
00401         try {
00402             DeploymentDesc ejbJarDD = null;
00403             if (fileInputName.endsWith(".jar")) {
00404                 // ejb-jar file
00405                 URL[] url = new URL[1];
00406                 url[0] = (new File(fileInputName)).toURL();
00407                 JClassLoader cl = new JClassLoader("GenIC-" + fileInputName, url, pcl);
00408                 if (classpathParam != null) {
00409                     // add -classpath value inside ClassLoader
00410                     addClasspath(cl, classpathParam);
00411                 }
00412                 ejbJarDD = EjbDeploymentDescManager.getDeploymentDesc(fileInputName, cl);
00413             } else {
00414                 // xml file
00415                 ejbJarDD = EjbDeploymentDescManager.getDeploymentDesc(fileInputName, BeanNaming
00416                         .getJonasXmlName(fileInputName), BeanNaming.getParentName(fileInputName));
00417             }
00418 
00419             GenIC gwc = new GenIC(ejbJarDD, dirOutputName, isVerbose);
00420 
00421             // Reset the beans deployment descriptors to unload the beans
00422             // classes
00423             // (loaded from the ejb-jar when creating the
00424             // jonas_ejb.deployment.api.BeanDesc),
00425             // to be able to update the ejb-jar file on Windows.
00426             // See Bug #270
00427             ejbJarDD = null;
00428             System.gc();
00429 
00430             if (isCompil) {
00431                 gwc.compilClasses(nameJavac, optionsJavaC, optionsRmiC, classpath, protocolsNames, isKeepGenerated,
00432                         invokeCmd);
00433                 if (protocolsNames.isSupported(CMI_RMI)) {
00434                     gwc.genClusterFiles(classpath, isKeepGenerated, invokeCmd);
00435                 }
00436                 if (fileInputName.endsWith(".jar") && isAddInJar) {
00437                     gwc.addClassesInJar(fileInputName, isKeepGenerated);
00438                 }
00439                 if (!isKeepGenerated) {
00440                     gwc.clean();
00441                 }
00442             }
00443 
00444         } catch (MalformedURLException e) {
00445             GenIC.fatalError("Invalid ejb-jar file name : ", e);
00446         } catch (GenICException e) {
00447             GenIC.fatalError(e);
00448         } catch (DeploymentDescException e) {
00449             GenIC.fatalError("Cannot read the Deployment Descriptors from " + fileInputName + ": ", e);
00450         }
00451         // End
00452     }
00453 
00460     private static void addClasspath(JClassLoader cl, String classpath) throws GenICException {
00461         String[] elems = classpath.split(File.pathSeparator);
00462         for (int i = 0; i < elems.length; i++) {
00463             try {
00464                 cl.addURL(new File(elems[i]).toURL());
00465             } catch (MalformedURLException e) {
00466                 throw new GenICException("Cannot create URL from '" + elems[i] + "'", e);
00467             }
00468         }
00469     }
00470 
00480     public GenIC(DeploymentDesc ejbJarDesc, String dirOutputName, boolean isVerbose) throws GenICException {
00481 
00482         // A BeanSources for each bean
00483         ArrayList beanList = null;
00484 
00485         verbose = isVerbose;
00486 
00487         if (javaHomeBin == null) {
00488             javaHomeBin = System.getProperty("java.home", "");
00489             if (!("".equals(javaHomeBin))) {
00490                 if (Env.isOsMacOsX()) {
00491                     javaHomeBin = javaHomeBin + File.separator + "bin" + File.separator;
00492                 } else {
00493                     javaHomeBin = javaHomeBin + File.separator + ".." + File.separator + "bin" + File.separator;
00494                 }
00495             }
00496         }
00497         outputdir = dirOutputName;
00498         filesToDelete = new ArrayList();
00499         remoteJavas = new ArrayList();
00500         noRemoteJavas = new ArrayList();
00501         remoteClasses = new ArrayList();
00502         clusterConfs = new ArrayList();
00503         clusteredClasses = new ArrayList();
00504         beanList = new ArrayList();
00505         BeanDesc[] beansDD = ejbJarDesc.getBeanDesc();
00506         JormCompiler jormCompiler = null;
00507         VelocityEngine ve = allocateVelocityEngine();
00508         // Display the bean's names
00509         StringBuffer message = new StringBuffer();
00510         message.append("GenIC for JOnAS " + Version.NUMBER + ": ");
00511         String sep = "";
00512         for (int i = 0; i < beansDD.length; i++) {
00513             BeanSources bs = null;
00514             if ((beansDD[i] instanceof MessageDrivenDesc)) {
00515                 //Nothing to generate in case of MessageDriven Bean
00516                 continue;
00517             }
00518             if (beansDD[i] instanceof EntityCmp2Desc) {
00519                 if (jormCompiler == null) {
00520                     // Load the jorm meta information of the class
00521                     try {
00522                         jormCompiler = allocateJormCompiler(((DeploymentDescEjb2) ejbJarDesc).getJormManager());
00523                     } catch (DeploymentDescException e) {
00524                         throw new GenICException("Impossible to load jorm meta information", e);
00525                     }
00526                 }
00527                 bs = new BeanSources(beansDD[i], outputdir, ve, jormCompiler);
00528             } else {
00529                 bs = new BeanSources(beansDD[i], outputdir, ve);
00530             }
00531             beanList.add(bs);
00532             //compute message
00533             message.append(sep);
00534             sep = ", ";
00535             message.append("'");
00536             message.append(bs.getEjbName());
00537             message.append("'");
00538         }
00539         generatedIC = !beanList.isEmpty();
00540         if (generatedIC) {
00541             message.append(" generation ...");
00542         } else {
00543             message.append("No generation to do (only message driven beans)");
00544         }
00545         GenIC.info(message.toString());
00546 
00547         // Generates the sources of the container classes of the beans
00548         // and Init the lists of the remote/non-remote java sources and the
00549         // remote classes
00550         for (Iterator it = beanList.iterator(); it.hasNext();) {
00551             BeanSources ics = (BeanSources) it.next();
00552             ics.generate();
00553             String ccfn = ics.getWrpHomeClusterConfFileName();
00554             if (ccfn != null) {
00555                 filesToDelete.add(ccfn);
00556             }
00557             trace("Sources classes successfully generated" + " for '" + ics.getEjbName() + "'");
00558             noRemoteJavas.addAll(ics.getNoRemoteJavas());
00559             if (ics.getWrpHomeFileName() != null) {
00560                 remoteJavas.add(ics.getWrpHomeFileName());
00561                 remoteClasses.add(ics.getWrpHomeClassName());
00562             }
00563             if (ics.getWrpRemoteFileName() != null) {
00564                 remoteJavas.add(ics.getWrpRemoteFileName());
00565                 remoteClasses.add(ics.getWrpRemoteClassName());
00566             }
00567             if (ics.getWrpServiceEndpointFileName() != null) {
00568                 remoteJavas.add(ics.getWrpServiceEndpointFileName());
00569                 remoteClasses.add(ics.getWrpServiceEndpointClassName());
00570             }
00571             if (ics.getWrpHomeClusterConfFileName() != null) {
00572                 clusterConfs.add(ics.getWrpHomeClusterConfFileName());
00573                 clusteredClasses.add(ics.getWrpHomeClassName());
00574             }
00575         }
00576         jormCompiler = null;
00577 
00578     }
00579 
00585     private JormCompiler allocateJormCompiler(Manager miManager) {
00586         // Allocate and configure a Jorm Compiler
00587         JormCompiler jormCompiler = new JormCompiler();
00588         JormCompilerConfigurator jcc = jormCompiler.getCompilerConfigurator();
00589         Properties prop = new Properties();
00590         prop.put("jorm.generator", "org.objectweb.jorm.generator.lib.JormGenerator");
00591         prop.put("jorm.mimanager", "org.objectweb.jorm.metainfo.lib.JormManager");
00592         prop.put("jorm.writer", "org.objectweb.jorm.mi2xml.lib.BasicDomWriter");
00593         prop.put("jorm.mapper.list", "rdb");
00594         prop.put("jorm.mapper.mifactory.rdb", "org.objectweb.jorm.mapper.rdb.metainfo.RdbMappingFactory");
00595         prop.put("jorm.mapper.mopfactory.rdb", "org.objectweb.jorm.mapper.rdb.generator.RdbMOPFactory");
00596         prop.put("jorm.mapper.gcmapping.rdb", "org.objectweb.jorm.mapper.rdb.genclass.RdbGenClassMapping");
00597         prop.put("jorm.mapper.schmgr.rdb", "org.objectweb.jorm.mapper.rdb.lib.RdbPMappingStructuresManager");
00598         prop.put("jorm.mapper.writer.rdb", "org.objectweb.jorm.mapper.rdb.mi2xml.RdbDomtreeBuilder");
00599         prop.put("use.context.classloader", "true");
00600         prop.put("jorm.mapper.submappers.rdb", "generic");
00601         jcc.configure(prop);
00602         jcc.setLoggerFactory(Log.getLoggerFactory());
00603         jormCompiler.setMIManager(miManager);
00604         return jormCompiler;
00605     }
00606 
00612     private VelocityEngine allocateVelocityEngine() throws GenICException {
00613         VelocityEngine ve = new VelocityEngine();
00614         ve.setProperty(RuntimeConstants.VM_LIBRARY, "GenICMacros.vm");
00615         ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "file");
00616 
00617         String jonasRoot = System.getProperty(INSTALL_ROOT_PROPERTY);
00618         if (jonasRoot == null) {
00619             throw new GenICException("System property '" + INSTALL_ROOT_PROPERTY + "' not set");
00620         }
00621         String path2Tmpl = new String(jonasRoot + File.separatorChar + "templates" + File.separatorChar + "genic");
00622         ve.setProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, path2Tmpl);
00623         // Velocity logs
00624         Logger vLogger = Log.getLogger(Log.JONAS_GENIC_VELOCITY_PREFIX);
00625         if (vLogger.isLoggable(BasicLevel.DEBUG)) {
00626             // No more velocity logs to avoid the creation of an empty file
00627             // "velocity.log"
00628             ve.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, "org.apache.velocity.runtime.log.NullLogSystem");
00629         } else {
00630             // Connect the velocity log system to monolog
00631             ve.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM, new VelocityLogger(vLogger));
00632         }
00633         try {
00634             ve.init();
00635         } catch (Exception e) {
00636             throw new GenICException("Cannot initialize the Velocity engine", e);
00637         }
00638         return ve;
00639     }
00640 
00659     public void compilClasses(String nameJavac, List optionsJavaC, List optionsRmiC, String classpath,
00660             ProtocolNames protocols, boolean keepGenerated, boolean invkCmd) throws GenICException {
00661 
00662         Cmd jrmpCmd;
00663         Cmd iiopCmd;
00664         Cmd jeremieCmd;
00665         Cmd cmd;
00666 
00667         String cmdJava;
00668         String cmdJavac;
00669         String cmdRmic;
00670 
00671         if (!generatedIC) {
00672             return;
00673         }
00674 
00675         /*
00676          * Init the command names
00677          */
00678         cmdJava = javaHomeBin + "java";
00679         if (nameJavac == null) {
00680             cmdJavac = javaHomeBin + "javac";
00681         } else {
00682             cmdJavac = nameJavac;
00683         }
00684         cmdRmic = javaHomeBin + "rmic";
00685 
00686         /*
00687          * Compile the generated sources
00688          */
00689         if (!new File(cmdJavac).exists()) {
00690             // Maybe this is on windows
00691             if (!new File(cmdJavac + ".exe").exists()) {
00692                 logger.log(BasicLevel.INFO, "No javac command was found at '" + cmdJavac
00693                     + "'. Check that you are using a JDK and not a JRE.");
00694             }
00695         }
00696         cmd = new Cmd(cmdJavac, invkCmd);
00697         cmd.addArgument("-classpath");
00698         cmd.addArgument(classpath);
00699         cmd.addArgument("-d");
00700         if ((outputdir.length() == 0)) {
00701             cmd.addArgument(".");
00702         } else {
00703             cmd.addArgument(outputdir);
00704         }
00705         cmd.addArguments(optionsJavaC);
00706 
00707         for (Iterator it = remoteJavas.iterator(); it.hasNext();) {
00708             String srcName = (String) it.next();
00709             cmd.addArgument(srcName);
00710             filesToDelete.add(srcName);
00711         }
00712         for (Iterator it = noRemoteJavas.iterator(); it.hasNext();) {
00713             String srcName = (String) it.next();
00714             cmd.addArgument(srcName);
00715             filesToDelete.add(srcName);
00716         }
00717 
00718         trace("Running '" + cmd.toString() + "'");
00719         if (cmd.run()) {
00720             trace("Sources classes successfully compiled via java compiler.");
00721         } else {
00722             throw new GenICException("Failed when compiling the generated classes via java compiler");
00723         }
00724 
00725         if (remoteJavas.size() == 0) {
00726             return;
00727         }
00728 
00729         /*
00730          * Generate the stub and skeletons of the home and remote implementations
00731          */
00732 
00733         if (!new File(cmdRmic).exists()) {
00734             // Maybe this is on windows
00735             if (!new File(cmdRmic + ".exe").exists()) {
00736                 logger.log(BasicLevel.INFO, "No rmic command was found at '" + cmdRmic
00737                     + "'. Check that you are using a JDK and not a JRE.");
00738             }
00739         }
00740         jrmpCmd = new Cmd(cmdRmic);
00741         jrmpCmd.addArgument("-classpath");
00742         jrmpCmd.addArgument(classpath);
00743 
00744         iiopCmd = new Cmd(cmdRmic);
00745         iiopCmd.addArgument("-classpath");
00746         iiopCmd.addArgument(classpath);
00747         iiopCmd.addArgument("-iiop");
00748         iiopCmd.addArgument("-poa");
00749         iiopCmd.addArgument("-always");
00750 
00751         jeremieCmd = new Cmd(cmdJava);
00752         jeremieCmd.addArgument("-classpath");
00753         jeremieCmd.addArgument(classpath);
00754         jeremieCmd.addArgument("org.objectweb.jeremie.tools.jrmic.JRMICompiler");
00755         jeremieCmd.addArgument("-opt");
00756         jeremieCmd.addArgument("-owext");
00757         if (nameJavac != null) {
00758             jeremieCmd.addArgument("-c");
00759             jeremieCmd.addArgument(nameJavac);
00760         }
00761 
00762         if (!"".equals(outputdir)) {
00763             jrmpCmd.addArgument("-d");
00764             jrmpCmd.addArgument(outputdir);
00765             iiopCmd.addArgument("-d");
00766             iiopCmd.addArgument(outputdir);
00767             jeremieCmd.addArgument("-d");
00768             jeremieCmd.addArgument(outputdir);
00769         }
00770 
00771         jrmpCmd.addArguments(optionsRmiC);
00772         iiopCmd.addArguments(optionsRmiC);
00773         jeremieCmd.addArguments(optionsRmiC);
00774 
00775         for (Iterator it = remoteClasses.iterator(); it.hasNext();) {
00776             String className = (String) it.next();
00777             jrmpCmd.addArgument(className);
00778             iiopCmd.addArgument(className);
00779             jeremieCmd.addArgument(className);
00780         }
00781 
00782         if (protocols.isSupported(RMI_JRMP)) {
00783             trace("Running '" + jrmpCmd.toString() + "'");
00784             if (jrmpCmd.run()) {
00785                 info("Stubs and Skels successfully generated for rmi/jrmp");
00786             } else {
00787                 throw new GenICException("Failed when generating the Stubs and Skels with rmic jrmp");
00788             }
00789         }
00790 
00791         if (protocols.isSupported(RMI_IIOP)) {
00792             trace("Running '" + iiopCmd.toString() + "'");
00793             if (iiopCmd.run()) {
00794                 info("Stubs and Skels successfully generated for rmi/iiop");
00795             } else {
00796                 throw new GenICException("Failed when generating the Stubs and Skels with rmic iiop");
00797             }
00798 
00799         }
00800 
00801         if (protocols.isSupported(JEREMIE)) {
00802             trace("Running '" + jeremieCmd.toString() + "'");
00803             if (jeremieCmd.run()) {
00804                 info("Stubs and Skels successfully generated with rmi/jeremie");
00805             } else {
00806                 throw new GenICException("Failed when generating the Stubs and Skels with jeremie jrmic");
00807             }
00808         }
00809     }
00810 
00814     private static Class clusterCompilerClass = null;
00815 
00819     private static Method clusterCompilerGenerateMethod = null;
00820 
00832     public static void callClusterCompiler(String[] args) throws ClassNotFoundException, InstantiationException,
00833             SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException,
00834             InvocationTargetException {
00835         if (clusterCompilerClass == null) {
00836             clusterCompilerClass = Class.forName("org.objectweb.carol.cmi.compiler.Compiler");
00837             clusterCompilerGenerateMethod = clusterCompilerClass.getMethod("generate", new Class[] {String[].class});
00838         }
00839         Object cc = clusterCompilerClass.newInstance();
00840         clusterCompilerGenerateMethod.invoke(cc, new Object[] {args});
00841     }
00842 
00850     public void genClusterFiles(String classpath, boolean isKeepGenerated, boolean isInvokeCmd) throws GenICException {
00851         Iterator cf = clusterConfs.iterator();
00852         Iterator cl = clusteredClasses.iterator();
00853         while (cf.hasNext()) {
00854             String ccfn = (String) cf.next();
00855             String cn = (String) cl.next();
00856 
00857             try {
00858                 ArrayList args = new ArrayList();
00859                 if (isKeepGenerated) {
00860                     args.add("-keep");
00861                 }
00862                 if (isInvokeCmd) {
00863                     args.add("-invokecmd");
00864                 }
00865                 args.add("-conf");
00866                 args.add(ccfn);
00867                 args.add("-classpath");
00868                 args.add(classpath);
00869                 if (!"".equals(outputdir)) {
00870                     args.add("-d");
00871                     args.add(outputdir);
00872                 }
00873                 args.add(cn);
00874 
00875                 String[] c = new String[args.size()];
00876                 c = (String[]) args.toArray(c);
00877                 callClusterCompiler(c);
00878 
00879             } catch (Exception ex) {
00880                 throw new GenICException("Failed when generating the cluster stubs", ex);
00881             }
00882         }
00883         info("Cluster stubs successfully generated");
00884     }
00885 
00892     public void addClassesInJar(String jarFileName, boolean keepGenerated) throws GenICException {
00893 
00894         if (!generatedIC) {
00895             return;
00896         }
00897 
00898         filesToDelete.add(outputdir);
00899 
00900         ArrayList lf = new ArrayList();
00901         getFilesList(outputdir, lf, !keepGenerated);
00902 
00903         updateJar(jarFileName, outputdir, lf);
00904 
00905     }
00906 
00912     protected String convertName(String name) {
00913         return name.replace('\\', '/');
00914     }
00915 
00923     private void updateJar(String jfn, String od, List lfn)
00924         throws GenICException {
00925 
00926         File jarFile = null;
00927         File tempJarFile = null;
00928         JarFile jarArchive = null;
00929         JarOutputStream tempJarArchive = null;
00930 
00931         try {
00932             jarFile = new File(jfn);
00933             tempJarFile = new File(jfn + ".tmp");
00934 
00935             // open existing jar file
00936             jarArchive = new JarFile(jarFile);
00937 
00938             // create temporary jar
00939             tempJarArchive = new JarOutputStream(
00940                     new FileOutputStream(tempJarFile));
00941 
00942             byte[] buffer = new byte[BUFFER_SIZE];
00943             int read = 0;
00944 
00945             // Add all generated files to temporary jar
00946             FileInputStream file = null;
00947             int is = od.length() + 1;
00948             Iterator iterFiles = lfn.iterator();
00949             while (iterFiles.hasNext()) {
00950                 try {
00951                     String fileName = (String) iterFiles.next();
00952 
00953                     file = new FileInputStream(fileName);
00954                     JarEntry entry = new JarEntry(convertName(fileName.substring(is)));
00955                     tempJarArchive.putNextEntry(entry);
00956                     // contents
00957                     while ((read = file.read(buffer)) != -1) {
00958                         tempJarArchive.write(buffer, 0, read);
00959                     }
00960                 } finally {
00961                     file.close();
00962                 }
00963             }
00964 
00965             // Add the rest of files (except if already included)
00966             Enumeration ents = jarArchive.entries();
00967             while (ents.hasMoreElements()) {
00968                 JarEntry entry = (JarEntry) ents.nextElement();
00969                 // add only if there is not a newer version
00970                 // already included
00971                 if (!lfn.contains(od + File.separator + entry.getName())) {
00972                     InputStream enStream = jarArchive.getInputStream(
00973                             entry);
00974                     tempJarArchive.putNextEntry(entry);
00975                     // contents
00976                     while ((read = enStream.read(buffer)) != -1) {
00977                         tempJarArchive.write(buffer, 0, read);
00978                     }
00979                 }
00980             }
00981 
00982         } catch (Exception e) {
00983             throw new GenICException("Failed when adding the generated classes " + "in the given ejb-jar file '" + jfn
00984                     + "': " + e);
00985         } finally {
00986             // close jar archives
00987             try {
00988                 jarArchive.close();
00989             } catch (IOException e1) {
00990                 warning("Failed to close jar archive file '"
00991                         + jarArchive.getName());
00992             }
00993             try {
00994                 tempJarArchive.close();
00995             } catch (IOException e1) {
00996                 warning("Failed to close temporary jar archive file '"
00997                         + jarArchive.getName() + "'");
00998             }
00999         }
01000 
01001         // Copy temporary jar file -> original jar
01002         boolean deleted = jarFile.delete();
01003         boolean rename = tempJarFile.renameTo(jarFile);
01004         if (!deleted || !rename) {
01005             error("Failed to update jar archive file '"
01006                     + jarArchive.getName() + "'");
01007         }
01008     }
01009 
01013     public void clean() {
01014         trace("Deleting " + filesToDelete.toString());
01015         for (Iterator it = filesToDelete.iterator(); it.hasNext();) {
01016             String name = (String) it.next();
01017             File f = new File(name);
01018             f.delete();
01019         }
01020     }
01021 
01025     static void usage() {
01026         StringBuffer msg = new StringBuffer();
01027         msg.append("Usage: java org.objectweb.jonas_ejb.genic.GenIC -help \n");
01028         msg.append("         to print this help message \n");
01029         msg.append(" or    java org.objectweb.jonas_ejb.genic.GenIC <Options> <Input_File> \n");
01030         msg.append("         to generate the container-specific classes for given EJB(s). \n");
01031         msg.append(" \n");
01032         msg.append("Options include: \n");
01033         msg.append("       -d <output_dir>  specify where to place the generated files \n");
01034         msg.append("       -noaddinjar      do not add the generated classes in the given \n");
01035         msg.append("                        ejb-jar file \n");
01036         msg.append("       -nocompil        do not compile the generated source files via \n");
01037         msg.append("                        the java and rmi compilers \n");
01038         msg.append("       -novalidation    parse the XML deployment descriptors without \n");
01039         msg.append("                        validation \n");
01040         msg.append("       -classpath <path> define the classpath to be used to compile classes \n");
01041         msg.append("       -javac     <opt> specify the java compiler to use \n");
01042         msg.append("       -javacopts <opt> specify the options to pass to the java compiler \n");
01043         msg.append("       -rmicopts  <opt> specify the options to pass to the rmi compiler \n");
01044         msg.append("       -protocols       list of protocol, separated by comma \n");
01045         msg.append("                        (default is jrmp) \n");
01046         msg.append("       -invokecmd       invoke, in some case, directly the method of the java class\n");
01047         msg.append("                        corresponding to the command \n");
01048         msg.append("       -keepgenerated   do not delete intermediate generated source files \n");
01049         msg.append("       -verbose \n");
01050         msg.append("       -debug           deprecated (use the JOnAS trace properties file)\n");
01051         msg.append(" \n");
01052         msg.append("       Input_File       standard deployment descriptor file's name or \n");
01053         msg.append("                        ejb-jar file's name \n");
01054         GenIC.info(msg.toString());
01055     }
01056 
01061     void trace(String msg) {
01062         int level = BasicLevel.DEBUG;
01063         if (verbose) {
01064             level = BasicLevel.INFO;
01065         }
01066         logger.log(level, msg);
01067     }
01068 
01073     static void info(String msg) {
01074         logger.log(BasicLevel.INFO, msg);
01075     }
01076 
01081     static void warning(String msg) {
01082         logger.log(BasicLevel.WARN, msg);
01083     }
01084 
01089     static void error(String msg) {
01090         logger.log(BasicLevel.ERROR, msg);
01091     }
01092 
01099     static void fatalError(String msg, Exception e) {
01100         error("GenIC fatal error: " + msg + e.getMessage());
01101         throw new RuntimeException(msg);
01102     }
01103 
01109     static void fatalError(Exception e) {
01110         System.err.println("GenIC fatal error: ");
01111         printException(e, System.err);
01112         throw new RuntimeException(e.getMessage());
01113     }
01114 
01121     static void printException(Exception e, PrintStream out) {
01122         Exception inner = null;
01123         if (e instanceof GenICException && (inner = ((GenICException) e).inner) != null) {
01124             out.println(e.getMessage());
01125             printException(inner, out);
01126         } else if (e instanceof PException && (inner = ((PException) e).getNestedException()) != null) {
01127             out.println(e.getMessage());
01128             printException(inner, out);
01129         } else if (e instanceof MedorException && (inner = ((MedorException) e).getNestedException()) != null) {
01130             out.println(e.getMessage());
01131             printException(inner, out);
01132         } else {
01133             e.printStackTrace();
01134         }
01135     }
01136 
01142     static String createTempDir() throws IOException {
01143         File tmpDir = File.createTempFile("genic", null, null);
01144         tmpDir.delete();
01145         if (!tmpDir.mkdir()) {
01146             throw new IOException("Cannot create the temporary directory '" + tmpDir + "'.");
01147         }
01148         return tmpDir.getAbsolutePath();
01149     }
01150 
01157     static void getFilesList(String dir, ArrayList list, boolean onlyClass) {
01158         File df = new File(dir);
01159         if (df.exists() && df.isDirectory()) {
01160             File[] ls = df.listFiles();
01161             for (int i = 0; i < ls.length; i++) {
01162                 File f = ls[i];
01163                 String fn = f.getAbsolutePath();
01164                 if (f.isDirectory()) {
01165                     getFilesList(fn, list, onlyClass);
01166                 } else {
01167                     if (!onlyClass || fn.endsWith(".class")) {
01168                         if (!fn.endsWith(".save")) {
01169                             list.add(fn);
01170                         }
01171                     }
01172                 }
01173             }
01174         }
01175     }
01176 }
01177 
01182 class ProtocolNames {
01183 
01187     private TreeSet protocolNames = new TreeSet();
01188 
01193     ProtocolNames(String pns) {
01194         if (pns != null && pns.length() > 0) {
01195             StringTokenizer st = new StringTokenizer(pns, ",", false);
01196             while (st.hasMoreTokens()) {
01197                 protocolNames.add(st.nextToken().trim());
01198             }
01199         } else {
01200             protocolNames.add("jrmp");
01201             protocolNames.add("jeremie");
01202         }
01203         if (protocolNames.contains(GenIC.CMI_RMI)) {
01204             protocolNames.add(GenIC.RMI_JRMP);
01205         }
01206     }
01207 
01213     boolean isSupported(String pn) {
01214         return protocolNames.contains(pn);
01215     }
01216 }
01217 

Generated on Tue Feb 15 15:05:48 2005 for JOnAS by  doxygen 1.3.9.1