KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jonas_ejb > genic > GenIC


1 /**
2  * JOnAS: Java(TM) Open Application Server
3  * Copyright (C) 1999-2005 Bull S.A.
4  * Contact: jonas-team@objectweb.org
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * USA
19  *
20  * --------------------------------------------------------------------------
21  * $Id: GenIC.java,v 1.78 2005/07/27 13:36:18 pelletib Exp $
22  * --------------------------------------------------------------------------
23  */

24
25 package org.objectweb.jonas_ejb.genic;
26
27 import java.io.BufferedReader JavaDoc;
28 import java.io.BufferedWriter JavaDoc;
29 import java.io.File JavaDoc;
30 import java.io.FileInputStream JavaDoc;
31 import java.io.FileOutputStream JavaDoc;
32 import java.io.IOException JavaDoc;
33 import java.io.InputStream JavaDoc;
34 import java.io.InputStreamReader JavaDoc;
35 import java.io.OutputStreamWriter JavaDoc;
36 import java.io.PrintStream JavaDoc;
37 import java.lang.reflect.InvocationTargetException JavaDoc;
38 import java.lang.reflect.Method JavaDoc;
39 import java.net.MalformedURLException JavaDoc;
40 import java.net.URL JavaDoc;
41 import java.util.ArrayList JavaDoc;
42 import java.util.Collection JavaDoc;
43 import java.util.Enumeration JavaDoc;
44 import java.util.Hashtable JavaDoc;
45 import java.util.Iterator JavaDoc;
46 import java.util.List JavaDoc;
47 import java.util.Properties JavaDoc;
48 import java.util.StringTokenizer JavaDoc;
49 import java.util.TreeSet JavaDoc;
50 import java.util.jar.JarEntry JavaDoc;
51 import java.util.jar.JarFile JavaDoc;
52 import java.util.jar.JarOutputStream JavaDoc;
53
54 import org.apache.velocity.app.VelocityEngine;
55 import org.apache.velocity.runtime.RuntimeConstants;
56
57 import org.objectweb.common.Cmd;
58 import org.objectweb.common.Env;
59
60 import org.objectweb.jonas_ejb.deployment.api.BeanDesc;
61 import org.objectweb.jonas_ejb.deployment.api.DeploymentDesc;
62 import org.objectweb.jonas_ejb.deployment.api.DeploymentDescEjb2;
63 import org.objectweb.jonas_ejb.deployment.api.EntityCmp2Desc;
64 import org.objectweb.jonas_ejb.deployment.api.MessageDrivenDesc;
65 import org.objectweb.jonas_ejb.deployment.lib.EjbDeploymentDescManager;
66 import org.objectweb.jonas_ejb.lib.BeanNaming;
67
68 import org.objectweb.jonas_lib.deployment.api.DeploymentDescException;
69 import org.objectweb.jonas_lib.files.FileUtils;
70 import org.objectweb.jonas_lib.files.FileUtilsException;
71 import org.objectweb.jonas_lib.version.Version;
72
73 import org.objectweb.jonas.common.Log;
74 import org.objectweb.jonas.server.JClassLoader;
75
76 import org.objectweb.jorm.api.PException;
77 import org.objectweb.jorm.compiler.api.JormCompilerConfigurator;
78 import org.objectweb.jorm.compiler.lib.JormCompiler;
79 import org.objectweb.jorm.metainfo.api.Manager;
80
81 import org.objectweb.medor.api.MedorException;
82
83 import org.objectweb.util.monolog.api.BasicLevel;
84 import org.objectweb.util.monolog.api.Logger;
85 import org.objectweb.util.monolog.wrapper.velocity.VelocityLogger;
86
87 /**
88  * This class allows to generate:
89  * <ul>
90  * <li>the classes that implements the Enterprise bean's remote interface,
91  * <li>the classes that implements the Enterprise bean's home interface,
92  * <li>the classes that implements the Handles of the Entity beans,
93  * <li>the classes that implements the persistence of the Entity beans with
94  * CMP,
95  * </ul>
96  * of all the Enterprise Java Beans defined in the given Deployment Descriptor.
97  *
98  * @author Helene Joanin : Initial developer
99  * @author Christophe Ney (Lutris Technologies) : Fix to handle arguments containing white spaces.
100  * @author Guillaume Riviere : Fix the addClassesInJar() method (on David, the Stub/Skel classes names are different).
101  * @author Dean Jennings : Remove System Exit (called now from server)
102  * @author Sami Lehtinen : use of java.util.jar api instead of jar command
103  */

104 public class GenIC {
105
106     /**
107      * JRMP protocol
108      */

109     public static final String JavaDoc RMI_JRMP = "jrmp";
110
111     /**
112      * IIOP protocol
113      */

114     public static final String JavaDoc RMI_IIOP = "iiop";
115
116     /**
117      * JEREMIE protocol
118      */

119     public static final String JavaDoc JEREMIE = "jeremie";
120
121     /**
122      * CMI protocol
123      */

124     public static final String JavaDoc CMI_RMI = "cmi";
125
126     /**
127      * install.root property name
128      */

129     private static final String JavaDoc INSTALL_ROOT_PROPERTY = "install.root";
130
131     /**
132      * java.home property value (ended with '/')
133      */

134     private static String JavaDoc javaHomeBin = null;
135
136     /**
137      * Is the command is verbose ?
138      */

139     private boolean verbose = false;
140
141     /**
142      * Name of the directory where to place the generated file
143      */

144     private String JavaDoc outputdir = null;
145
146     /**
147      * Are some container classes generated ?
148      */

149     private boolean generatedIC;
150
151     /**
152      * Path names of the generated files to delete
153      */

154     private ArrayList JavaDoc filesToDelete = null;
155
156     /**
157      * Path names of the java generated sources (remote)
158      */

159     private ArrayList JavaDoc remoteJavas = null;
160
161     /**
162      * Path names of the java generated sources (no remote)
163      */

164     private ArrayList JavaDoc noRemoteJavas = null;
165
166     /**
167      * Names of the remote classes (package name included)
168      */

169     private ArrayList JavaDoc remoteClasses = null;
170
171     /**
172      * Logger used by GenIC
173      */

174     private static Logger logger = null;
175
176     /**
177      * Buffer size
178      */

179     private static final int BUFFER_SIZE = 1024;
180
181     /** META dir */
182     private static final String JavaDoc META_DIR = "META-INF";
183
184     /** The jar entry for the MANIFEST file */
185     private static final String JavaDoc MANIFEST_JAR_ENTRY = META_DIR + "/MANIFEST.MF";
186
187     /** The path to the MANIFEST file */
188     private static final String JavaDoc MANIFEST_PATH = META_DIR + File.separator + "MANIFEST.MF";
189
190     /**
191      * GenIC allows to generate the container classes for JOnAS for the given
192      * Enterprise Java Beans.
193      * <p>
194      * Usage: java org.objectweb.jonas_ejb.genic.GenIC -help <br>
195      * to print this help message
196      * <p>
197      * or java org.objectweb.jonas_ejb.genic.GenIC <Options><Input_File><br>
198      * to generate the container classes for the given EJBs.
199      * <p>
200      * Options include:
201      * <ul>
202      * <li>-d <output_dir>specify where to place the generated files</li>
203      * <li>-noaddinjar do not add the generated classes in the given ejb-jar
204      * file</li>
205      * <li>-classpath <path> define the classpath to be used to compile classes</li>
206      * <li>-nocompil do not compile the generated source files via the java and
207      * rmi compilers</li>
208      * <li>-novalidation parse the XML deployment descriptors without
209      * validation</li>
210      * <li>-javac <opt>specify the name of the java compiler to use</li>
211      * <li>-javacopts <opt>specify the options to pass to the java compiler
212      * </li>
213      * <li>-rmicopts <opt>specify the options to pass to the rmi compiler</li>
214      * <li>-protocols list of protocol, separated by comma</li>
215      * <li>-keepgenerated do not delete intermediate generated source files
216      * </li>
217      * <li>-verbose</li>
218      * <li>-invokecmd invoke, in some case, directly the method of the java
219      * class corresponding to the command</li>
220      * </ul>
221      * <p>
222      * Input_File file name of the standard deployment descriptor (.xml ended),
223      * or file name of the EJB-jar (.jar ended).
224      * @param args arguments for GenIC
225      */

226     public static void main(String JavaDoc[] args) {
227         boolean error = false;
228
229         boolean isHelp = false;
230         boolean isVerbose = false;
231         boolean isKeepGenerated = false;
232         boolean isCompil = true;
233         boolean isAddInJar = true;
234         boolean parseWithValidation = true;
235         boolean invokeCmd = false;
236
237         // don't use the fastrmic compiler by default
238
boolean nofastrmic = false;
239
240         String JavaDoc fileInputName = null;
241         String JavaDoc dirOutputName = null;
242         String JavaDoc nameJavac = null;
243         ArrayList JavaDoc optionsJavaC = new ArrayList JavaDoc();
244         ArrayList JavaDoc optionsRmiC = new ArrayList JavaDoc();
245         String JavaDoc protocols = RMI_JRMP; // Default: generate for jrmp
246
ProtocolNames protocolsNames = null;
247         String JavaDoc classpathParam = null;
248
249         // Init logger
250
Log.configure("trace");
251         logger = Log.getLogger(Log.JONAS_GENIC_PREFIX);
252
253         // Get args
254
for (int argn = 0; argn < args.length; argn++) {
255             String JavaDoc arg = args[argn];
256             if (arg.equals("-help") || arg.equals("-?")) {
257                 isHelp = true;
258                 continue;
259             }
260             if (arg.equals("-verbose")) {
261                 isVerbose = true;
262                 continue;
263             }
264             if (arg.equals("-debug")) {
265                 // deprecated
266
continue;
267             }
268             if (arg.equals("-mappernames")) {
269                 argn++;
270                 // deprecated
271
warning("The -mappernames option is ignored (deprecated)");
272             }
273             if (arg.equals("-protocols")) {
274                 argn++;
275                 if (argn < args.length) {
276                     protocols = args[argn];
277                     continue;
278                 } else {
279                     error = true;
280                 }
281             }
282             if (arg.equals("-keepgenerated")) {
283                 isKeepGenerated = true;
284                 optionsRmiC.add(args[argn]);
285                 continue;
286             }
287             if (arg.equals("-nocompil")) {
288                 isCompil = false;
289                 isKeepGenerated = true;
290                 continue;
291             }
292             if (arg.equals("-noaddinjar")) {
293                 isAddInJar = false;
294                 continue;
295             }
296             if (arg.equals("-novalidation")) {
297                 parseWithValidation = false;
298                 continue;
299             }
300             if (arg.equals("-classpath")) {
301                 classpathParam = args[++argn];
302                 continue;
303             }
304             if (arg.equals("-javac")) {
305                 argn++;
306                 if (argn < args.length) {
307                     nameJavac = args[argn];
308                 } else {
309                     error = true;
310                 }
311                 continue;
312             }
313             if (arg.equals("-javacopts")) {
314                 argn++;
315                 if (argn < args.length) {
316                     StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(args[argn]);
317                     while (st.hasMoreTokens()) {
318                         optionsJavaC.add(st.nextToken());
319                     }
320                 } else {
321                     error = true;
322                 }
323                 continue;
324             }
325             if (arg.equals("-rmicopts")) {
326                 argn++;
327                 if (argn < args.length) {
328                     StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(args[argn]);
329                     while (st.hasMoreTokens()) {
330                         optionsRmiC.add(st.nextToken());
331                     }
332                 } else {
333                     error = true;
334                 }
335                 continue;
336             }
337             if (arg.equals("-d")) {
338                 argn++;
339                 if (argn < args.length) {
340                     dirOutputName = args[argn];
341                 } else {
342                     error = true;
343                 }
344                 continue;
345             }
346             if (arg.equals("-invokecmd")) {
347                 invokeCmd = true;
348                 continue;
349             }
350             if (arg.equals("-fastrmic")) {
351                 argn++;
352                 // deprecated
353
warning("The -fastrmic option is ignored as it is the default value. Use -nofastrmic to disable it.");
354                 continue;
355             }
356
357             if (arg.equals("-nofastrmic")) {
358                 argn++;
359                 nofastrmic = true;
360                 continue;
361             }
362
363             fileInputName = args[argn];
364         }
365
366         // Usage ?
367
if (isHelp) {
368             usage();
369             return;
370         }
371
372         // Check args
373
if (error || (fileInputName == null)) {
374             usage();
375             throw new RuntimeException JavaDoc();
376         }
377         // The -d option is deprecated since JOnAS 3.0.7 when the file input is an ejb-jar
378
// Instead, the output directory must be a temporary directory to make easier
379
// the ejb-jar updated.
380
if ((dirOutputName != null) && isAddInJar && fileInputName.endsWith(".jar")) {
381             warning("The -d '" + dirOutputName + "' option is ignored" + " (deprecated with an ejb-jar as input file)");
382         }
383
384         if (dirOutputName == null) {
385             dirOutputName = new String JavaDoc("");
386         }
387
388         // Build the array of protocols name
389
protocolsNames = new ProtocolNames(protocols);
390
391         // In case of ejb-jar file, the dirOutputName must be initialized with a
392
// tempo. directory.
393
if (fileInputName.endsWith(".jar") && isAddInJar) {
394             try {
395                 dirOutputName = GenIC.createTempDir();
396             } catch (IOException JavaDoc ioe) {
397                 GenIC.fatalError(ioe);
398             }
399         }
400
401         // Init the classpath used for javac, rmic, JRMICompiler
402
JClassLoader pcl = (JClassLoader) Thread.currentThread().getContextClassLoader();
403
404         String JavaDoc classpath = pcl.getClassPath();
405         if (fileInputName.endsWith(".jar")) {
406             classpath = fileInputName + File.pathSeparator + classpath;
407         }
408         if (!"".equals(dirOutputName)) {
409             classpath = dirOutputName + File.pathSeparator + classpath;
410         }
411         // add -classpath value
412
if (classpathParam != null) {
413             classpath = classpathParam + File.pathSeparator + classpath;
414         }
415
416         // Set the parsing mode (with or without validation)
417
if (!parseWithValidation) {
418             EjbDeploymentDescManager.setParsingWithValidation(false);
419         }
420
421         // Generates the classes for the set of the beans
422
try {
423             DeploymentDesc ejbJarDD = null;
424             if (fileInputName.endsWith(".jar")) {
425                 // ejb-jar file
426
URL JavaDoc[] url = new URL JavaDoc[1];
427                 url[0] = (new File JavaDoc(fileInputName)).toURL();
428                 JClassLoader cl = new JClassLoader("GenIC-" + fileInputName, url, pcl);
429                 if (classpathParam != null) {
430                     // add -classpath value inside ClassLoader
431
addClasspath(cl, classpathParam);
432                 }
433                 ejbJarDD = EjbDeploymentDescManager.getDeploymentDesc(fileInputName, cl);
434             } else {
435                 // xml file
436
ejbJarDD = EjbDeploymentDescManager.getDeploymentDesc(fileInputName, BeanNaming
437                         .getJonasXmlName(fileInputName), BeanNaming.getParentName(fileInputName));
438             }
439
440             GenIC gwc = new GenIC(ejbJarDD, dirOutputName, isVerbose);
441
442             // Reset the beans deployment descriptors to unload the beans
443
// classes
444
// (loaded from the ejb-jar when creating the
445
// jonas_ejb.deployment.api.BeanDesc),
446
// to be able to update the ejb-jar file on Windows.
447
// See Bug #270
448
ejbJarDD = null;
449             System.gc();
450
451             if (isCompil) {
452                 gwc.compilClasses(nameJavac, optionsJavaC, optionsRmiC, classpath, protocolsNames, isKeepGenerated,
453                         invokeCmd, nofastrmic);
454                 if (fileInputName.endsWith(".jar") && isAddInJar) {
455                     gwc.addClassesInJar(fileInputName, isKeepGenerated);
456                 }
457                 if (!isKeepGenerated) {
458                     gwc.clean();
459                 }
460             }
461
462             // Add into META_INF/MANIFEST jonas information for autogeneration functionnality
463
if (fileInputName != null && fileInputName.endsWith(".jar") && isAddInJar) {
464                 try {
465                     updateAttributInManifest(fileInputName, "Genic-Jonas-Version", Version.NUMBER);
466                     updateAttributInManifest(fileInputName, "Genic-Jonas-protocols", protocols);
467                 } catch (FileUtilsException e) {
468                     if (logger.isLoggable(BasicLevel.WARN)) {
469                         logger.log(BasicLevel.WARN, "Can't update the Genic-Jonas-Version of this application :" + fileInputName, e);
470                     }
471                 }
472             } else if (dirOutputName != null && !isAddInJar) {
473                 // case of Genic call by ant task
474
// noaddinjar = true && -d specified we must add manifest into the directory output
475
Hashtable JavaDoc atts = new Hashtable JavaDoc();
476                 atts.put("Manifest-Version", "1.0");
477                 atts.put("Genic-Jonas-Version", Version.NUMBER);
478                 atts.put("Genic-Jonas-protocols", protocols);
479                 createManifest(dirOutputName, atts);
480             }
481         } catch (MalformedURLException JavaDoc e) {
482             GenIC.fatalError("Invalid ejb-jar file name : ", e);
483         } catch (GenICException e) {
484             GenIC.fatalError(e);
485         } catch (DeploymentDescException e) {
486             GenIC.fatalError("Cannot read the Deployment Descriptors from " + fileInputName + ": ", e);
487         }
488         // End
489
}
490
491     /**
492      * Change the attribute value in a jar file (and update file if required)
493      * @param jarName : output jar file
494      * @param attributName : Name of attribute to update
495      * @param attributValue : Value of attribute
496      * @throws FileUtilsException if update fails (replacing file with the updated file)
497      */

498     private static void updateAttributInManifest(String JavaDoc jarName, String JavaDoc attributName, String JavaDoc attributValue) throws FileUtilsException {
499
500         // Initialize a flag that will indicate that the jar was updated.
501
boolean jarUpdated = false;
502         JarFile JavaDoc jar = null;
503         File JavaDoc tempJarFile = null;
504
505         File JavaDoc jarFile = new File JavaDoc(jarName);
506         try {
507             jar = new JarFile JavaDoc(jarFile);
508
509             // Create a temp jar file with no manifest. (The manifest will
510
// be copied when the entries are copied.)
511
tempJarFile = File.createTempFile("filetoadd" , ".jar");
512
513             JarOutputStream JavaDoc tempJar =
514                 new JarOutputStream JavaDoc(new FileOutputStream JavaDoc(tempJarFile));
515
516             // Allocate a buffer for reading entry data.
517

518             byte[] buffer = new byte[BUFFER_SIZE];
519             int bytesRead;
520             String JavaDoc ligneRead;
521
522             // Loop through the jar entries and add them to the temp jar,
523
// skipping the entry that was added to the temp jar already.
524

525             for (Enumeration JavaDoc entries = jar.entries(); entries.hasMoreElements();) {
526                 // Get the next entry.
527

528                 JarEntry JavaDoc entry = (JarEntry JavaDoc) entries.nextElement();
529                 String JavaDoc entryName = entry.getName();
530                 // If the entry has not been added already, add it.
531
// If the entry is not the META-INF/MANIFEST.MF and it skipManifest is true
532
if (!entryName.equalsIgnoreCase(MANIFEST_JAR_ENTRY)) {
533                     // Get an input stream for the entry.
534
InputStream JavaDoc entryStream = jar.getInputStream(entry);
535                     // Read the entry and write it to the temp jar.
536

537                     tempJar.putNextEntry(entry);
538
539                     while ((bytesRead = entryStream.read(buffer)) != -1) {
540                         tempJar.write(buffer, 0, bytesRead);
541                     }
542                 } else {
543                     File JavaDoc tempManifestFile = File.createTempFile("MANIFEST", ".MF");
544                     BufferedWriter JavaDoc tempManifestWriter = new BufferedWriter JavaDoc(new OutputStreamWriter JavaDoc(new FileOutputStream JavaDoc(tempManifestFile)));
545                     InputStream JavaDoc entryStream = jar.getInputStream(entry);
546                     InputStreamReader JavaDoc entryStreamReader = new InputStreamReader JavaDoc(entryStream);
547                     BufferedReader JavaDoc entryBufferedReader = new BufferedReader JavaDoc(entryStreamReader);
548
549                     // Read the MANIFEST and change Genic-Jonas-Version with current JOnAS version
550
boolean findJonasVersion = false;
551                     String JavaDoc ligneToWrite = attributName + ": " + attributValue;
552                     while ((ligneRead = entryBufferedReader.readLine()) != null) {
553                         if (ligneRead.equalsIgnoreCase(ligneToWrite)) {
554                             tempManifestWriter.write(ligneRead);
555                             tempManifestWriter.newLine();
556                             findJonasVersion = true;
557                         } else if (ligneRead.startsWith(attributName)) {
558                             tempManifestWriter.write(ligneToWrite);
559                             tempManifestWriter.newLine();
560                             jarUpdated = true;
561                             findJonasVersion = true;
562                         } else if (!ligneRead.equals("")) {
563                             tempManifestWriter.write(ligneRead);
564                             tempManifestWriter.newLine();
565                         }
566                     }
567                     if (!findJonasVersion) {
568                         tempManifestWriter.write(ligneToWrite);
569                         tempManifestWriter.newLine();
570                         jarUpdated = true;
571                     }
572                     tempManifestWriter.close();
573
574                     // Add the new MANIFEST
575
FileInputStream JavaDoc fileInputManifest = new FileInputStream JavaDoc(tempManifestFile);
576                     try {
577                         // Create a jar entry and add it to the temp jar.
578
JarEntry JavaDoc newEntry = new JarEntry JavaDoc(MANIFEST_JAR_ENTRY);
579                         tempJar.putNextEntry(newEntry);
580
581                         // Read the file and write it to the jar.
582

583                         while ((bytesRead = fileInputManifest.read(buffer)) != -1) {
584                             tempJar.write(buffer, 0, bytesRead);
585                         }
586                     } catch (Exception JavaDoc ex) {
587                         logger.log(BasicLevel.WARN, "Can't update manifest", ex);
588                     } finally {
589                         fileInputManifest.close();
590                         tempManifestFile.delete();
591                     }
592                 }
593             }
594             jar.close();
595             tempJar.close();
596         } catch (Exception JavaDoc ex) {
597             logger.log(BasicLevel.ERROR, ex);
598         }
599
600         // Attribute has changed, need to update the file (with the updated copy)
601
if (jarUpdated) {
602             FileUtils.copyFile(tempJarFile, jarFile);
603         }
604
605         // delete temp file
606
tempJarFile.delete();
607     }
608
609     /**
610      * Create Manifest file with name/value
611      * @param dirOutputName : output file
612      * @param atts : list of name/value to write into manifest
613      * @return false if problem during file creation
614      */

615     private static boolean createManifest(String JavaDoc dirOutputName, Hashtable JavaDoc atts) {
616         try {
617             File JavaDoc fileOutput = new File JavaDoc (dirOutputName + File.separator + META_DIR);
618
619             if (!fileOutput.exists()) {
620                fileOutput.mkdirs();
621             }
622             if (!fileOutput.exists()) {
623                 GenIC.warning("Can't create META-INF directory into temp dir : " + dirOutputName + "/META-INF");
624                 return false;
625             }
626
627             fileOutput = new File JavaDoc (dirOutputName + File.separator + MANIFEST_PATH);
628             if (!fileOutput.exists()) {
629                fileOutput.createNewFile();
630             }
631             if (!fileOutput.exists()) {
632                 GenIC.warning("Can't create manifest.mf file into " + dirOutputName + File.separator + "META-INF");
633                 return false;
634             }
635             BufferedWriter JavaDoc tempManifestWriter = new BufferedWriter JavaDoc(new OutputStreamWriter JavaDoc(new FileOutputStream JavaDoc(fileOutput)));
636             Collection JavaDoc names = atts.keySet();
637             Iterator JavaDoc namesIt = names.iterator();
638             String JavaDoc name;
639             String JavaDoc value;
640             while (namesIt.hasNext()) {
641                 name = (String JavaDoc) namesIt.next();
642                 value = (String JavaDoc) atts.get(name);
643                 tempManifestWriter.write(name + ": " + value);
644                 tempManifestWriter.newLine();
645             }
646             tempManifestWriter.close();
647             return true;
648         } catch (Exception JavaDoc e) {
649             GenIC.warning("Problem during creation of META-INF/manifest.mf file into tempdir : " + e.getMessage());
650             return false;
651         }
652     }
653
654     /**
655      * Add To the given ClassLoader the given classpath
656      * @param cl ClassLoader to be updated
657      * @param classpath the classpath to add inside the ClassLoader
658      * @throws GenICException When classpath contains invalid URL
659      */

660     private static void addClasspath(JClassLoader cl, String JavaDoc classpath) throws GenICException {
661         String JavaDoc[] elems = classpath.split(File.pathSeparator);
662         for (int i = 0; i < elems.length; i++) {
663             try {
664                 cl.addURL(new File JavaDoc(elems[i]).toURL());
665             } catch (MalformedURLException JavaDoc e) {
666                 throw new GenICException("Cannot create URL from '" + elems[i] + "'", e);
667             }
668         }
669     }
670
671     /**
672      * GenIC Constructor: generates the container classes sources of each beans
673      * @param ejbJarDesc deployment descriptors of the beans
674      * @param dirOutputName path of the directory where to place the generated
675      * files (empty string "" if the output directory is the current
676      * directory)
677      * @param isVerbose if true, some traces are print
678      * @throws GenICException In error case
679      */

680     public GenIC(DeploymentDesc ejbJarDesc, String JavaDoc dirOutputName, boolean isVerbose) throws GenICException {
681
682         // A BeanSources for each bean
683
ArrayList JavaDoc beanList = null;
684
685         verbose = isVerbose;
686
687         if (javaHomeBin == null) {
688             javaHomeBin = System.getProperty("java.home", "");
689             if (!("".equals(javaHomeBin))) {
690                 if (Env.isOsMacOsX()) {
691                     javaHomeBin = javaHomeBin + File.separator + "bin" + File.separator;
692                 } else {
693                     javaHomeBin = javaHomeBin + File.separator + ".." + File.separator + "bin" + File.separator;
694                 }
695             }
696         }
697         outputdir = dirOutputName;
698         filesToDelete = new ArrayList JavaDoc();
699         remoteJavas = new ArrayList JavaDoc();
700         noRemoteJavas = new ArrayList JavaDoc();
701         remoteClasses = new ArrayList JavaDoc();
702         beanList = new ArrayList JavaDoc();
703         BeanDesc[] beansDD = ejbJarDesc.getBeanDesc();
704         JormCompiler jormCompiler = null;
705         VelocityEngine ve = allocateVelocityEngine();
706         // Display the bean's names
707
StringBuffer JavaDoc message = new StringBuffer JavaDoc();
708         message.append("GenIC for JOnAS " + Version.NUMBER + ": ");
709         String JavaDoc sep = "";
710         for (int i = 0; i < beansDD.length; i++) {
711             BeanSources bs = null;
712             if ((beansDD[i] instanceof MessageDrivenDesc)) {
713                 //Nothing to generate in case of MessageDriven Bean
714
continue;
715             }
716             if (beansDD[i] instanceof EntityCmp2Desc) {
717                 if (jormCompiler == null) {
718                     // Load the jorm meta information of the class
719
try {
720                         jormCompiler = allocateJormCompiler(((DeploymentDescEjb2) ejbJarDesc).getJormManager());
721                     } catch (DeploymentDescException e) {
722                         throw new GenICException("Impossible to load jorm meta information", e);
723                     }
724                 }
725                 bs = new BeanSources(beansDD[i], outputdir, ve, jormCompiler);
726             } else {
727                 bs = new BeanSources(beansDD[i], outputdir, ve);
728             }
729             beanList.add(bs);
730             //compute message
731
message.append(sep);
732             sep = ", ";
733             message.append("'");
734             message.append(bs.getEjbName());
735             message.append("'");
736         }
737         generatedIC = !beanList.isEmpty();
738         if (generatedIC) {
739             message.append(" generation ...");
740         } else {
741             message.append("No generation to do (only message driven beans)");
742         }
743         GenIC.info(message.toString());
744
745         // Generates the sources of the container classes of the beans
746
// and Init the lists of the remote/non-remote java sources and the
747
// remote classes
748
for (Iterator JavaDoc it = beanList.iterator(); it.hasNext();) {
749             BeanSources ics = (BeanSources) it.next();
750             ics.generate();
751             String JavaDoc ccfn = ics.getWrpHomeClusterFileName();
752             if (ccfn != null) {
753                 filesToDelete.add(ccfn);
754             }
755             trace("Sources classes successfully generated" + " for '" + ics.getEjbName() + "'");
756             noRemoteJavas.addAll(ics.getNoRemoteJavas());
757             if (ics.getWrpHomeFileName() != null) {
758                 remoteJavas.add(ics.getWrpHomeFileName());
759                 remoteClasses.add(ics.getWrpHomeClassName());
760             }
761             if (ics.getWrpRemoteFileName() != null) {
762                 remoteJavas.add(ics.getWrpRemoteFileName());
763                 remoteClasses.add(ics.getWrpRemoteClassName());
764             }
765             if (ics.getWrpServiceEndpointFileName() != null) {
766                 remoteJavas.add(ics.getWrpServiceEndpointFileName());
767                 remoteClasses.add(ics.getWrpServiceEndpointClassName());
768             }
769         }
770         jormCompiler = null;
771
772     }
773
774     /**
775      * Allocate and configure a JORM compiler
776      * @param miManager the JORM Meta-Information manager
777      * @return a JORM compiler
778      */

779     private JormCompiler allocateJormCompiler(Manager miManager) {
780         // Allocate and configure a Jorm Compiler
781
JormCompiler jormCompiler = new JormCompiler();
782         JormCompilerConfigurator jcc = jormCompiler.getCompilerConfigurator();
783         Properties JavaDoc prop = new Properties JavaDoc();
784         prop.put("jorm.generator", "org.objectweb.jorm.generator.lib.JormGenerator");
785         prop.put("jorm.mimanager", "org.objectweb.jorm.metainfo.lib.JormManager");
786         prop.put("jorm.writer", "org.objectweb.jorm.mi2xml.lib.BasicDomWriter");
787         prop.put("jorm.mapper.list", "rdb");
788         prop.put("jorm.mapper.mifactory.rdb", "org.objectweb.jorm.mapper.rdb.metainfo.RdbMappingFactory");
789         prop.put("jorm.mapper.mopfactory.rdb", "org.objectweb.jorm.mapper.rdb.generator.RdbMOPFactory");
790         prop.put("jorm.mapper.gcmapping.rdb", "org.objectweb.jorm.mapper.rdb.genclass.RdbGenClassMapping");
791         prop.put("jorm.mapper.schmgr.rdb", "org.objectweb.jorm.mapper.rdb.lib.RdbPMappingStructuresManager");
792         prop.put("jorm.mapper.writer.rdb", "org.objectweb.jorm.mapper.rdb.mi2xml.RdbDomtreeBuilder");
793         prop.put("use.context.classloader", "true");
794         prop.put("jorm.mapper.submappers.rdb", "generic");
795         jcc.configure(prop);
796         jcc.setLoggerFactory(Log.getLoggerFactory());
797         jormCompiler.setMIManager(miManager);
798         return jormCompiler;
799     }
800
801     /**
802      * Allocate and configure a Velocity Engine
803      * @return the Velocity Engine
804      * @throws GenICException in error case
805      */

806     private VelocityEngine allocateVelocityEngine() throws GenICException {
807         VelocityEngine ve = new VelocityEngine();
808         ve.setProperty(RuntimeConstants.VM_LIBRARY, "GenICMacros.vm");
809         ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "file");
810
811         String JavaDoc jonasRoot = System.getProperty(INSTALL_ROOT_PROPERTY);
812         if (jonasRoot == null) {
813             throw new GenICException("System property '" + INSTALL_ROOT_PROPERTY + "' not set");
814         }
815         String JavaDoc path2Tmpl = new String JavaDoc(jonasRoot + File.separatorChar + "templates" + File.separatorChar + "genic");
816         ve.setProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, path2Tmpl);
817         // Velocity logs
818
Logger vLogger = Log.getLogger(Log.JONAS_GENIC_VELOCITY_PREFIX);
819         if (vLogger.isLoggable(BasicLevel.DEBUG)) {
820             // No more velocity logs to avoid the creation of an empty file
821
// "velocity.log"
822
ve.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, "org.apache.velocity.runtime.log.NullLogSystem");
823         } else {
824             // Connect the velocity log system to monolog
825
ve.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM, new VelocityLogger(vLogger));
826         }
827         try {
828             ve.init();
829         } catch (Exception JavaDoc e) {
830             throw new GenICException("Cannot initialize the Velocity engine", e);
831         }
832         return ve;
833     }
834
835     /**
836      * Compiles the java sources generated by the constructor I.e. :
837      * <ul>
838      * <li>compile the classes via javac,
839      * <li>create the stubs and skeletons for the protocols supported(RMI/JRMP,
840      * RMI/IIOP,JEREMIE) via rmic/jrmic
841      * </ul>
842      * @param nameJavac name the javac tool to use (if null, take the standard
843      * tool)
844      * @param optionsJavaC options for the javac tool
845      * @param optionsRmiC options for the rmic tool
846      * @param classpath classpath value
847      * @param protocols names of protocols
848      * @param keepGenerated keep the generatef files or not
849      * @param invkCmd run the javac command directly by invoking the compile
850      * method of the javac compiler
851      * @param nofastrmic don't use Fast rmic to generate Stubs/Tie
852      * @exception GenICException In error case
853      */

854     public void compilClasses(String JavaDoc nameJavac, List JavaDoc optionsJavaC, List JavaDoc optionsRmiC, String JavaDoc classpath,
855             ProtocolNames protocols, boolean keepGenerated, boolean invkCmd,
856             boolean nofastrmic) throws GenICException {
857
858         Cmd jrmpCmd;
859         Cmd iiopCmd;
860         Cmd jeremieCmd;
861         Cmd cmd;
862
863         String JavaDoc cmdJava;
864         String JavaDoc cmdJavac;
865         String JavaDoc cmdRmic;
866
867         if (!generatedIC) {
868             return;
869         }
870
871         /*
872          * Init the command names
873          */

874         cmdJava = javaHomeBin + "java";
875         if (nameJavac == null) {
876             cmdJavac = javaHomeBin + "javac";
877         } else {
878             cmdJavac = nameJavac;
879         }
880         cmdRmic = javaHomeBin + "rmic";
881
882         /*
883          * Compile the generated sources
884          */

885         if (!new File JavaDoc(cmdJavac).exists()) {
886             // Maybe this is on windows
887
if (!new File JavaDoc(cmdJavac + ".exe").exists()) {
888                 logger.log(BasicLevel.INFO, "No javac command was found at '" + cmdJavac
889                     + "'. Check that you are using a JDK and not a JRE.");
890             }
891         }
892         cmd = new Cmd(cmdJavac, invkCmd);
893         cmd.addArgument("-classpath");
894         cmd.addArgument(classpath);
895         cmd.addArgument("-d");
896         if ((outputdir.length() == 0)) {
897             cmd.addArgument(".");
898         } else {
899             cmd.addArgument(outputdir);
900         }
901         cmd.addArguments(optionsJavaC);
902
903         for (Iterator JavaDoc it = remoteJavas.iterator(); it.hasNext();) {
904             String JavaDoc srcName = (String JavaDoc) it.next();
905             cmd.addArgument(srcName);
906             filesToDelete.add(srcName);
907         }
908         for (Iterator JavaDoc it = noRemoteJavas.iterator(); it.hasNext();) {
909             String JavaDoc srcName = (String JavaDoc) it.next();
910             cmd.addArgument(srcName);
911             filesToDelete.add(srcName);
912         }
913
914         trace("Running '" + cmd.toString() + "'");
915         if (cmd.run()) {
916             trace("Sources classes successfully compiled via java compiler.");
917         } else {
918             throw new GenICException("Failed when compiling the generated classes via java compiler");
919         }
920
921         if (remoteJavas.size() == 0) {
922             return;
923         }
924
925         /*
926          * Generate the stub and skeletons of the home and remote implementations
927          */

928
929         if (!new File JavaDoc(cmdRmic).exists()) {
930             // Maybe this is on windows
931
if (!new File JavaDoc(cmdRmic + ".exe").exists()) {
932                 logger.log(BasicLevel.INFO, "No rmic command was found at '" + cmdRmic
933                     + "'. Check that you are using a JDK and not a JRE.");
934             }
935         }
936         jrmpCmd = new Cmd(cmdRmic);
937         jrmpCmd.addArgument("-classpath");
938         jrmpCmd.addArgument(classpath);
939
940         iiopCmd = new Cmd(cmdRmic);
941         iiopCmd.addArgument("-classpath");
942         iiopCmd.addArgument(classpath);
943         iiopCmd.addArgument("-iiop");
944         iiopCmd.addArgument("-poa");
945         iiopCmd.addArgument("-always");
946
947         jeremieCmd = new Cmd(cmdJava);
948         jeremieCmd.addArgument("-classpath");
949         jeremieCmd.addArgument(classpath);
950         jeremieCmd.addArgument("org.objectweb.jeremie.tools.jrmic.JRMICompiler");
951         jeremieCmd.addArgument("-opt");
952         jeremieCmd.addArgument("-owext");
953         if (nameJavac != null) {
954             jeremieCmd.addArgument("-c");
955             jeremieCmd.addArgument(nameJavac);
956         }
957
958         if (!"".equals(outputdir)) {
959             jrmpCmd.addArgument("-d");
960             jrmpCmd.addArgument(outputdir);
961             iiopCmd.addArgument("-d");
962             iiopCmd.addArgument(outputdir);
963             jeremieCmd.addArgument("-d");
964             jeremieCmd.addArgument(outputdir);
965         }
966
967         jrmpCmd.addArguments(optionsRmiC);
968         iiopCmd.addArguments(optionsRmiC);
969         jeremieCmd.addArguments(optionsRmiC);
970
971         for (Iterator JavaDoc it = remoteClasses.iterator(); it.hasNext();) {
972             String JavaDoc className = (String JavaDoc) it.next();
973             jrmpCmd.addArgument(className);
974             iiopCmd.addArgument(className);
975             jeremieCmd.addArgument(className);
976         }
977
978         // Use fast rmic, if there are failures, fallback to rmic
979
if (protocols.isSupported(RMI_JRMP) && !nofastrmic) {
980             trace("Running fastrmic for '" + jrmpCmd.toString() + "'");
981             ArrayList JavaDoc args = new ArrayList JavaDoc();
982             boolean skip = true;
983             for (Iterator JavaDoc it = jrmpCmd.getCommandLine(); it.hasNext();) {
984                 Object JavaDoc o = it.next();
985                 if (skip) {
986                     skip = false;
987                     continue;
988                 }
989                 args.add(o);
990             }
991
992             String JavaDoc[] a = (String JavaDoc[]) args.toArray(new String JavaDoc[] {});
993             Method JavaDoc m = null;
994             try {
995                 Class JavaDoc c = Class.forName("org.objectweb.fastrmic.RMIC");
996                 m = c.getMethod("main", new Class JavaDoc[] {String JavaDoc[].class});
997             } catch (ClassNotFoundException JavaDoc cnfe) {
998                 logger.log(BasicLevel.ERROR,
999                            "continuing after class not found ", cnfe);
1000                nofastrmic = true;
1001            } catch (NoSuchMethodException JavaDoc nsme) {
1002                logger.log(BasicLevel.ERROR,
1003                           "continuing after no such method ", nsme);
1004                nofastrmic = true;
1005            }
1006
1007            if (m != null) {
1008                try {
1009                    m.invoke(null, new Object JavaDoc[] {a});
1010                    // Call to the GC for bug (#303750)
1011
// fastRMIC load classes of the jar, then there is a lock on the file until the GC is called.
1012
System.gc();
1013                } catch (IllegalAccessException JavaDoc iae) {
1014                    logger.log(BasicLevel.ERROR,
1015                               "continuing after illegal access", iae);
1016                    nofastrmic = true;
1017                } catch (InvocationTargetException JavaDoc ite) {
1018                    throw new GenICException("error in fastrmic", ite);
1019                }
1020                info("Stubs and Skels successfully generated with fastrmic for rmi/jrmp");
1021            }
1022        }
1023
1024        if (protocols.isSupported(RMI_JRMP) && nofastrmic) {
1025            trace("Running '" + jrmpCmd.toString() + "'");
1026            if (jrmpCmd.run()) {
1027                info("Stubs and Skels successfully generated for rmi/jrmp");
1028            } else {
1029                throw new GenICException("Failed when generating the Stubs and Skels with rmic jrmp");
1030            }
1031        }
1032
1033        if (protocols.isSupported(RMI_IIOP)) {
1034            trace("Running '" + iiopCmd.toString() + "'");
1035            if (iiopCmd.run()) {
1036                info("Stubs and Skels successfully generated for rmi/iiop");
1037            } else {
1038                throw new GenICException("Failed when generating the Stubs and Skels with rmic iiop");
1039            }
1040
1041        }
1042
1043        if (protocols.isSupported(JEREMIE)) {
1044            trace("Running '" + jeremieCmd.toString() + "'");
1045            if (jeremieCmd.run()) {
1046                info("Stubs and Skels successfully generated with rmi/jeremie");
1047            } else {
1048                throw new GenICException("Failed when generating the Stubs and Skels with jeremie jrmic");
1049            }
1050        }
1051    }
1052
1053    /**
1054     * Current class compiler for cluster
1055     */

1056    private static Class JavaDoc clusterCompilerClass = null;
1057
1058    /**
1059     * Current Method for cluster compiler
1060     */

1061    private static Method JavaDoc clusterCompilerGenerateMethod = null;
1062
1063    /**
1064     * Add the generated classes in the given ejb-jar file.
1065     * @param jarFileName name of the jar
1066     * @param keepGenerated keep the generated files or not ?
1067     * @throws GenICException if the classes cannot be added in the jar file
1068     */

1069    public void addClassesInJar(String JavaDoc jarFileName, boolean keepGenerated) throws GenICException {
1070
1071        if (!generatedIC) {
1072            return;
1073        }
1074
1075        filesToDelete.add(outputdir);
1076
1077        ArrayList JavaDoc lf = new ArrayList JavaDoc();
1078        getFilesList(outputdir, lf, !keepGenerated);
1079
1080        updateJar(jarFileName, outputdir, lf);
1081
1082    }
1083
1084    /**
1085     * Convert a name from any format in Jar filename format
1086     * @param name filename to be converted
1087     * @return converted filename
1088     */

1089    protected String JavaDoc convertName(String JavaDoc name) {
1090        return name.replace('\\', '/');
1091    }
1092
1093    /**
1094     * Add some classes in an existing jar file via the java.util.jar api.
1095     * @param jfn jar filename
1096     * @param od base directory of generated files
1097     * @param lfn list of filenames to add
1098     * @throws GenICException if the classes cannot be added
1099     */

1100    private void updateJar(String JavaDoc jfn, String JavaDoc od, List JavaDoc lfn)
1101        throws GenICException {
1102
1103        File JavaDoc jarFile = null;
1104        File JavaDoc tempJarFile = null;
1105        JarFile JavaDoc jarArchive = null;
1106        JarOutputStream JavaDoc tempJarArchive = null;
1107
1108        try {
1109            jarFile = new File JavaDoc(jfn);
1110            tempJarFile = new File JavaDoc(jfn + ".tmp");
1111
1112            // open existing jar file
1113
jarArchive = new JarFile JavaDoc(jarFile);
1114
1115            // create temporary jar
1116
tempJarArchive = new JarOutputStream JavaDoc(
1117                    new FileOutputStream JavaDoc(tempJarFile));
1118
1119            byte[] buffer = new byte[BUFFER_SIZE];
1120            int read = 0;
1121
1122            // Add all generated files to temporary jar
1123
FileInputStream JavaDoc file = null;
1124            int is = od.length() + 1;
1125            Iterator JavaDoc iterFiles = lfn.iterator();
1126            while (iterFiles.hasNext()) {
1127                try {
1128                    String JavaDoc fileName = (String JavaDoc) iterFiles.next();
1129
1130                    file = new FileInputStream JavaDoc(fileName);
1131                    JarEntry JavaDoc entry = new JarEntry JavaDoc(convertName(fileName.substring(is)));
1132                    tempJarArchive.putNextEntry(entry);
1133                    // contents
1134
while ((read = file.read(buffer)) != -1) {
1135                        tempJarArchive.write(buffer, 0, read);
1136                    }
1137                } finally {
1138                    file.close();
1139                }
1140            }
1141
1142            // Add the rest of files (except if already included)
1143
Enumeration JavaDoc ents = jarArchive.entries();
1144            while (ents.hasMoreElements()) {
1145                JarEntry JavaDoc entry = (JarEntry JavaDoc) ents.nextElement();
1146                // add only if there is not a newer version
1147
// already included
1148
// In a windows plateform we must replace / by \ for a correct path
1149
if (!lfn.contains(od + File.separator + entry.getName().replace('/', File.separatorChar))) {
1150                    InputStream JavaDoc enStream = jarArchive.getInputStream(
1151                            entry);
1152                    tempJarArchive.putNextEntry(entry);
1153                    // contents
1154
while ((read = enStream.read(buffer)) != -1) {
1155                        tempJarArchive.write(buffer, 0, read);
1156                    }
1157                }
1158            }
1159
1160        } catch (Exception JavaDoc e) {
1161            throw new GenICException("Failed when adding the generated classes " + "in the given ejb-jar file '" + jfn
1162                    + "': " + e);
1163        } finally {
1164            // close jar archives
1165
try {
1166                jarArchive.close();
1167            } catch (IOException JavaDoc e1) {
1168                warning("Failed to close jar archive file '"
1169                        + jarArchive.getName());
1170            }
1171            try {
1172                tempJarArchive.close();
1173            } catch (IOException JavaDoc e1) {
1174                warning("Failed to close temporary jar archive file '"
1175                        + jarArchive.getName() + "'");
1176            }
1177        }
1178
1179        // Copy temporary jar file -> original jar
1180
boolean deleted = jarFile.delete();
1181        boolean rename = tempJarFile.renameTo(jarFile);
1182        if (!deleted || !rename) {
1183            error("Failed to update jar archive file '"
1184                    + jarArchive.getName() + "'");
1185        }
1186    }
1187
1188    /**
1189     * Clean the intermediate generated files.
1190     */

1191    public void clean() {
1192        trace("Deleting " + filesToDelete.toString());
1193        for (Iterator JavaDoc it = filesToDelete.iterator(); it.hasNext();) {
1194            String JavaDoc name = (String JavaDoc) it.next();
1195            File JavaDoc f = new File JavaDoc(name);
1196            delete(f);
1197        }
1198    }
1199
1200    /**
1201     * Delete a file or directory recursively
1202     * @param f file or directory to be deleted
1203     * @return true if deletion ok, false otherwise.
1204     */

1205    private boolean delete(File JavaDoc f) {
1206        if (f.isFile()) {
1207            return f.delete();
1208        } else {
1209            File JavaDoc[] childs = f.listFiles();
1210            if (childs == null) {
1211                // no childs
1212
return f.delete();
1213            } else {
1214                // childs
1215
boolean result = true;
1216                for (int i = 0; i < childs.length; i++) {
1217                    result &= delete(childs[i]);
1218                }
1219                return result && f.delete();
1220            }
1221        }
1222    }
1223
1224    /**
1225     * Display the usage
1226     */

1227    static void usage() {
1228        StringBuffer JavaDoc msg = new StringBuffer JavaDoc();
1229        msg.append("Usage: java org.objectweb.jonas_ejb.genic.GenIC -help \n");
1230        msg.append(" to print this help message \n");
1231        msg.append(" or java org.objectweb.jonas_ejb.genic.GenIC <Options> <Input_File> \n");
1232        msg.append(" to generate the container-specific classes for given EJB(s). \n");
1233        msg.append(" \n");
1234        msg.append("Options include: \n");
1235        msg.append(" -d <output_dir> specify where to place the generated files \n");
1236        msg.append(" -noaddinjar do not add the generated classes in the given \n");
1237        msg.append(" ejb-jar file \n");
1238        msg.append(" -nocompil do not compile the generated source files via \n");
1239        msg.append(" the java and rmi compilers \n");
1240        msg.append(" -novalidation parse the XML deployment descriptors without \n");
1241        msg.append(" validation \n");
1242        msg.append(" -classpath <path> define the classpath to be used to compile classes \n");
1243        msg.append(" -javac <opt> specify the java compiler to use \n");
1244        msg.append(" -javacopts <opt> specify the options to pass to the java compiler \n");
1245        msg.append(" -rmicopts <opt> specify the options to pass to the rmi compiler \n");
1246        msg.append(" -protocols list of protocol, separated by comma \n");
1247        msg.append(" (default is jrmp) \n");
1248        msg.append(" -invokecmd invoke, in some case, directly the method of the java class\n");
1249        msg.append(" corresponding to the command \n");
1250        msg.append(" -keepgenerated do not delete intermediate generated source files \n");
1251        msg.append(" -verbose \n");
1252        msg.append(" -debug deprecated (use the JOnAS trace properties file)\n");
1253        msg.append(" \n");
1254        msg.append(" Input_File standard deployment descriptor file's name or \n");
1255        msg.append(" ejb-jar file's name \n");
1256        GenIC.info(msg.toString());
1257    }
1258
1259    /**
1260     * Display the specified message only if verbose.
1261     * @param msg the message to display
1262     */

1263    void trace(String JavaDoc msg) {
1264        int level = BasicLevel.DEBUG;
1265        if (verbose) {
1266            level = BasicLevel.INFO;
1267        }
1268        logger.log(level, msg);
1269    }
1270
1271    /**
1272     * Display the specified message.
1273     * @param msg the message to display
1274     */

1275    static void info(String JavaDoc msg) {
1276        logger.log(BasicLevel.INFO, msg);
1277    }
1278
1279    /**
1280     * Display the specified warning message.
1281     * @param msg the warning message to display
1282     */

1283    static void warning(String JavaDoc msg) {
1284        logger.log(BasicLevel.WARN, msg);
1285    }
1286
1287
1288    /**
1289     * Display the specified error message.
1290     * @param msg the error message to display
1291     */

1292    static void error(String JavaDoc msg) {
1293        logger.log(BasicLevel.ERROR, msg);
1294    }
1295
1296    /**
1297     * Display the specified error message and exits with an EXIT_FAILURE
1298     * status.
1299     * @param msg the error message to display
1300     * @param e the exception raised
1301     */

1302    static void fatalError(String JavaDoc msg, Exception JavaDoc e) {
1303        error("GenIC fatal error: " + msg + e.getMessage());
1304        throw new RuntimeException JavaDoc(msg);
1305    }
1306
1307    /**
1308     * Display the specified error message and exits with an EXIT_FAILURE
1309     * status.
1310     * @param e the error to display
1311     */

1312    static void fatalError(Exception JavaDoc e) {
1313        System.err.println("GenIC fatal error: ");
1314        printException(e, System.err);
1315        throw new RuntimeException JavaDoc(e.getMessage());
1316    }
1317
1318    /**
1319     * Display the exception and its nested exception if exists, on the given
1320     * printstream.
1321     * @param e the exception to display
1322     * @param out the PrintStream on which the exception has to displayed
1323     */

1324    static void printException(Exception JavaDoc e, PrintStream JavaDoc out) {
1325        Exception JavaDoc inner = null;
1326        if (e instanceof GenICException && (inner = ((GenICException) e).inner) != null) {
1327            out.println(e.getMessage());
1328            printException(inner, out);
1329        } else if (e instanceof PException && (inner = ((PException) e).getNestedException()) != null) {
1330            out.println(e.getMessage());
1331            printException(inner, out);
1332        } else if (e instanceof MedorException && (inner = ((MedorException) e).getNestedException()) != null) {
1333            out.println(e.getMessage());
1334            printException(inner, out);
1335        } else {
1336            e.printStackTrace();
1337        }
1338    }
1339
1340    /**
1341     * Create a cleaned temporary directory.
1342     * @return the temp directory file name
1343     * @throws IOException if a temp directory cannot be created.
1344     */

1345    static String JavaDoc createTempDir() throws IOException JavaDoc {
1346        File JavaDoc tmpDir = File.createTempFile("genic", null, null);
1347        tmpDir.delete();
1348        if (!tmpDir.mkdir()) {
1349            throw new IOException JavaDoc("Cannot create the temporary directory '" + tmpDir + "'.");
1350        }
1351        return tmpDir.getAbsolutePath();
1352    }
1353
1354    /**
1355     * Get the list file names recursively of the given directory
1356     * @param dir the directory used to list files
1357     * @param list list to store filenames
1358     * @param onlyClass stores only class or not ?
1359     */

1360    static void getFilesList(String JavaDoc dir, ArrayList JavaDoc list, boolean onlyClass) {
1361        File JavaDoc df = new File JavaDoc(dir);
1362        if (df.exists() && df.isDirectory()) {
1363            File JavaDoc[] ls = df.listFiles();
1364            for (int i = 0; i < ls.length; i++) {
1365                File JavaDoc f = ls[i];
1366                String JavaDoc fn = f.getAbsolutePath();
1367                if (f.isDirectory()) {
1368                    getFilesList(fn, list, onlyClass);
1369                } else {
1370                    if (!onlyClass || fn.endsWith(".class")) {
1371                        if (!fn.endsWith(".save")) {
1372                            list.add(fn);
1373                        }
1374                    }
1375                }
1376            }
1377        }
1378    }
1379}
1380
1381/**
1382 * Class used to manage protocol names
1383 */

1384
1385class ProtocolNames {
1386
1387    /**
1388     * List of protocols
1389     */

1390    private TreeSet JavaDoc protocolNames = new TreeSet JavaDoc();
1391
1392    /**
1393     * Build a new object to check protocols
1394     * @param pns names of protocols
1395     */

1396    ProtocolNames(String JavaDoc pns) {
1397        if (pns != null && pns.length() > 0) {
1398            StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(pns, ",", false);
1399            while (st.hasMoreTokens()) {
1400                protocolNames.add(st.nextToken().trim());
1401            }
1402        } else {
1403            protocolNames.add("jrmp");
1404            protocolNames.add("jeremie");
1405        }
1406        if (protocolNames.contains(GenIC.CMI_RMI)) {
1407            protocolNames.add(GenIC.RMI_JRMP);
1408        }
1409    }
1410
1411    /**
1412     * Return true if the given protocol is supported
1413     * @param pn protocol name
1414     * @return true if the given protocol is supported
1415     */

1416    boolean isSupported(String JavaDoc pn) {
1417        return protocolNames.contains(pn);
1418    }
1419}
1420
1421
Popular Tags