KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > ejb > codegen > IASEJBC


1
2 /*
3  * The contents of this file are subject to the terms
4  * of the Common Development and Distribution License
5  * (the License). You may not use this file except in
6  * compliance with the License.
7  *
8  * You can obtain a copy of the license at
9  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
10  * glassfish/bootstrap/legal/CDDLv1.0.txt.
11  * See the License for the specific language governing
12  * permissions and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL
15  * Header Notice in each file and include the License file
16  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
17  * If applicable, add the following below the CDDL Header,
18  * with the fields enclosed by brackets [] replaced by
19  * you own identifying information:
20  * "Portions Copyrighted [year] [name of copyright owner]"
21  *
22  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23  */

24 package com.sun.ejb.codegen;
25
26 import java.lang.reflect.*;
27 import java.net.URL JavaDoc;
28 import java.net.URLConnection JavaDoc;
29 import java.net.MalformedURLException JavaDoc;
30 import java.io.*;
31 import java.util.*;
32 import java.util.jar.*;
33 import java.util.zip.*;
34 import java.util.logging.Logger JavaDoc;
35 import java.util.logging.Level JavaDoc;
36
37 import static com.sun.corba.ee.spi.codegen.Wrapper.*;
38
39 import com.sun.ejb.codegen.*;
40 import com.sun.ejb.EJBUtils;
41 import com.sun.enterprise.deployment.*;
42 import com.sun.enterprise.deployment.backend.DeploymentMode;
43 import com.sun.enterprise.deployment.backend.WebServiceDeployer;
44 import com.sun.enterprise.deployment.deploy.shared.FileArchive;
45 import com.sun.enterprise.deployment.runtime.IASEjbExtraDescriptors;
46 import com.sun.enterprise.log.Log;
47 import com.sun.enterprise.util.*;
48 import com.sun.enterprise.util.i18n.StringManager;
49 import com.sun.enterprise.util.zip.ZipFileException;
50 import com.sun.enterprise.util.zip.ZipItem;
51 import com.sun.enterprise.webservice.codegen.JaxRpcCodegenAdapter;
52 import com.sun.enterprise.webservice.codegen.JaxRpcCodegenFactory;
53 import com.sun.logging.LogDomains;
54
55 /**
56  * Handles all ejb related codegen. Also does webservices code generation.
57  *
58  *
59  * @author Vivek Nagar
60  * @author Danny Coward
61  * @author Nazrul Islam
62  * @author Praveen Joy
63  * @author Kenneth Saks
64  */

65 public final class IASEJBC {
66
67     private static final StringManager localStrings =
68                                 StringManager.getManager(IASEJBC.class);
69     private static final Logger JavaDoc _logger =
70                             LogDomains.getLogger(LogDomains.DPL_LOGGER);
71
72     /**
73      * This class is only instantiated internally.
74      */

75     private IASEJBC() { }
76
77     /**
78      * Get the java file name based on the specified class name.
79      *
80      * @param className the class name.
81      * @param repository repository for this application
82      *
83      * @return the java file name.
84      */

85     private String JavaDoc getFileName(String JavaDoc className, String JavaDoc repository) {
86
87         return (repository + File.separator
88                + className.replace('.', File.separatorChar) + ".java");
89     }
90
91     /**
92      * Get the class name based on the specified file name.
93      *
94      * @param fileName the java file name.
95      * @param repository path to the code generator repository
96      *
97      * @return the class name.
98      */

99     private String JavaDoc getClassName(String JavaDoc fileName, String JavaDoc repository) {
100
101         String JavaDoc className = fileName;
102         if (className.startsWith(repository))
103             className = className.substring(repository.length());
104
105         if (className.indexOf(".java") != -1)
106             className = className.substring(0, className.indexOf(".java"));
107         else if (className.indexOf(".class") != -1)
108             className = className.substring(0, className.indexOf(".class"));
109
110         className = className.replace(File.separatorChar, '.');
111         if (className.charAt(0) == '.')
112             className = className.substring(1);
113
114         return className;
115     }
116
117     /**
118      * Create the FileOutputStream for the specified class.
119      *
120      * @param fileName the name of the file
121      *
122      * @return the output stream.
123      *
124      * @exception IOException.
125      */

126     private OutputStream createOutputStream(String JavaDoc fileName)
127             throws IOException
128     {
129         File file = new File(fileName);
130         File parent = null;
131
132         if ( (parent=file.getParentFile()) != null)
133         {
134             if ( !parent.exists() )
135             {
136                 parent.mkdirs();
137             }
138         }
139
140         FileOutputStream out = new FileOutputStream(fileName);
141         BufferedOutputStream bout = new BufferedOutputStream(out);
142
143         return bout;
144     }
145
146
147     /**
148      * Runs the generator and adds the generated file to files
149      *
150      * @param gen code generator
151      * @param files contans newly generated files
152      * @param rep directory where generator will create new src files
153      *
154      * @return file name of generated file
155      * @throws Exception if an error while generating new src
156      */

157     private String JavaDoc generateCode(Generator gen, Vector files, File rep)
158         throws Exception JavaDoc
159     {
160
161         String JavaDoc genClass = gen.getGeneratedClass();
162         String JavaDoc repository = rep.getCanonicalPath();
163         String JavaDoc genFile = getFileName(genClass, repository);
164         
165         OutputStream out = createOutputStream(genFile);
166         PrintStream ps = new PrintStream(out);
167         ((ClassGeneratorFactory)gen).evaluate();
168         _sourceCode(ps, null);
169         out.close();
170
171         _logger.log(Level.FINE,
172                     "[EJBC] Adding to generated files: " + genFile);
173
174         files.addElement(genFile);
175     
176         return genFile;
177     }
178
179     /**
180      * Compile all the generated .java files, run rmic on them.
181      *
182      * @param classPath class path for javac & rmic
183      * @param rmicOptions options for rmic
184      * @param stubClasses additional classes to be compilled with
185      * the other files
186      * @param destDir destination directory for javac & rmic
187      * @param repository repository for code generator
188      *
189      * @exception GeneratorException if an error during code generation
190      * @exception IOException if an i/o error
191      */

192     private void compileAndRmic(String JavaDoc classPath, List rmicOptions,
193                                 Set stubClasses, File destDir,
194                                 String JavaDoc repository)
195         throws GeneratorException, IOException
196     {
197
198         if( (stubClasses.size() == 0) ) {
199             _logger.log(Level.FINE, "[EJBC] No code generation required");
200             return;
201         }
202
203         progress(localStrings.getStringWithDefault(
204                                          "generator.compiling_rmi_iiop",
205                                          "Compiling RMI-IIOP code."));
206
207         List options = new ArrayList();
208         List fileList = new ArrayList();
209
210         options.addAll(rmicOptions);
211
212         options.add("-classpath");
213         String JavaDoc bigClasspath = System.getProperty("java.class.path")
214                             + File.pathSeparator + classPath
215                             + File.pathSeparator + repository;
216
217         options.add(bigClasspath);
218         options.add("-d");
219         options.add(destDir.toString());
220
221         for(Iterator extraIter = stubClasses.iterator();
222             extraIter.hasNext();) {
223             String JavaDoc next = (String JavaDoc) extraIter.next();
224             _logger.log(Level.FINE,"[EJBC] rmic " + next + "...");
225             fileList.add(next);
226         }
227
228         try {
229             RMICompiler rmic = new RMICompiler(options, fileList);
230             rmic.setClasspath(bigClasspath);
231             rmic.compile();
232
233         } catch(JavaCompilerException e) {
234             _logger.log(Level.FINE,"ejbc.codegen_rmi_fail",e);
235             String JavaDoc msg =
236                 localStrings.getString("generator.rmic_compilation_failed");
237             GeneratorException ge = new GeneratorException(msg);
238             ge.initCause(e);
239             throw ge;
240         }
241
242         if (_logger.isLoggable(Level.FINE)){
243             StringBuffer JavaDoc sbuf = new StringBuffer JavaDoc();
244             for(Iterator it = options.iterator(); it.hasNext(); ) {
245                 sbuf.append("\n\t").append(it.next());
246             }
247             for(Iterator it = fileList.iterator(); it.hasNext(); ) {
248                 sbuf.append("\n\t").append(it.next());
249             }
250             _logger.log(Level.FINE,"[EJBC] RMIC COMMAND: " + sbuf.toString());
251         }
252         return;
253     }
254
255     /**
256      * Compile .java files.
257      *
258      * @param classPath class path to be used during javac
259      * @param files actual source files
260      * @param destDir destination directory for .class files
261      * @param repository repository for code generator
262      * @param javacOptions options for javac (-g or -O)
263      *
264      * @exception GeneratorException if an error while code compilation
265      */

266     public static void compileClasses(String JavaDoc classPath, Vector files,
267            File destDir, String JavaDoc repository, List javacOptions)
268         throws GeneratorException {
269
270         List options = new ArrayList();
271         List fileList = new ArrayList();
272
273         if (files.size() <= 0) {
274             return;
275         }
276
277         // adds the passed in javac options
278

279         options.addAll(javacOptions);
280         options.add("-d");
281         options.add(destDir.toString());
282         options.add("-classpath");
283         options.add(System.getProperty("java.class.path")
284                          + File.pathSeparator + classPath
285                          + File.pathSeparator + repository);
286
287         fileList.addAll(files);
288
289         for(Iterator it = fileList.iterator(); it.hasNext(); )
290         {
291             String JavaDoc file = (String JavaDoc)it.next();
292             _logger.log(Level.FINE,localStrings.getStringWithDefault(
293                                     "generator.compile",
294                                     "Compiling {0} ...", new Object JavaDoc[] {file} ));
295         }
296
297         if (_logger.isLoggable(Level.FINE)) {
298             StringBuffer JavaDoc sbuf = new StringBuffer JavaDoc();
299             for ( Iterator it = options.iterator(); it.hasNext(); ) {
300                 sbuf.append("\n\t").append((String JavaDoc)it.next());
301             }
302             _logger.log(Level.FINE,"[EJBC] JAVAC COMMAND: " + sbuf.toString());
303         }
304
305         long start = System.currentTimeMillis();
306         long end = start;
307
308         try {
309             JavaCompiler jc = new JavaCompiler(options, fileList);
310             jc.compile();
311         } catch(JavaCompilerException jce) {
312             _logger.log(Level.FINE,"ejbc.codegen_compile_failed", jce);
313             String JavaDoc msg =
314                 localStrings.getStringWithDefault(
315                     "generator.java_complilation_failed",
316                     "Compilation failed: {0}",
317                 new Object JavaDoc[] {jce.getMessage()} );
318             GeneratorException ge = new GeneratorException(msg);
319             ge.initCause(jce);
320             throw ge;
321         }
322
323         end = System.currentTimeMillis();
324         _logger.log(Level.FINE,"JAVA compile time (" + fileList.size()
325                 + " files) = " + (end - start));
326     }
327
328     /**
329      * Assembles the name of the client jar files into the given vector.
330      *
331      * @param stubClasses classes that required rmic
332      * @param allClientFiles vector that contains all client jar files
333      * @param stubsDir current stubsnskells dir for the app
334      */

335     private void addGeneratedFiles(Set stubClasses,
336                                    Vector allClientFiles, File stubsDir)
337     {
338         for (Iterator iter = stubClasses.iterator(); iter.hasNext();) {
339             String JavaDoc next = (String JavaDoc) iter.next();
340             String JavaDoc stubFile = stubsDir.toString() + File.separator +
341                                 GeneratedNames.getStubName(next).replace('.',
342                                 File.separatorChar) + ".class";
343             allClientFiles.add(stubFile);
344         }
345
346         _logger.log(Level.FINE,
347                     "[EJBC] Generated client files: " + allClientFiles);
348     }
349      
350     /**
351      * Constructs the client zip entries.
352      *
353      * @param allClientFiles all client stubs
354      * @param stubsDir stubs directory for the current app
355      *
356      * @return the client zip entries or an empty array if no stubs
357      */

358     private ZipItem[] getClientZipEntries(Vector allClientFiles,
359                                           File stubsDir)
360         throws IOException, ZipFileException {
361
362         // number of client stubs
363
final int CLIENT_SZ = allClientFiles.size();
364
365         ZipItem[] zipEntries = new ZipItem[CLIENT_SZ];
366
367         // string representaion of the stubs dir - please note that
368
// toString is used to convert the file object to string earlier.
369
// So, canonical path should not be used here
370
String JavaDoc stubsDirPath = stubsDir.toString();
371
372         for (int i=0; i<CLIENT_SZ; i++) {
373             String JavaDoc longName = (String JavaDoc) allClientFiles.elementAt(i);
374             File file = new File(longName);
375
376             _logger.log(Level.FINE,"[EJBC] stubs - >>"+longName);
377
378             // coverts the file name to a jar entry name
379
String JavaDoc entryName = "";
380             if (longName.startsWith(stubsDirPath)) {
381                 entryName = longName.substring(stubsDirPath.length());
382                 if (entryName.charAt(0) == File.separatorChar) {
383                     entryName = entryName.substring(1);
384                 }
385             } else {
386                 // throw exception
387
String JavaDoc msg =
388                     localStrings.getString("generator.unknown_class_prefix");
389                 throw new RuntimeException JavaDoc(msg);
390             }
391             // zip entry has forward slashes
392
entryName = entryName.replace(File.separatorChar,'/');
393
394             // create the zip entry
395
zipEntries[i] = new ZipItem(file, entryName);
396         }
397
398         // returns the client stubs
399
return zipEntries;
400     }
401
402     private Set getRemoteSuperInterfaces(ClassLoader JavaDoc jcl,
403                                          String JavaDoc homeRemoteIntf)
404         throws ClassNotFoundException JavaDoc {
405  
406         // all super interfaces of home or remote that need to be
407
// processed for stubs.
408
Set allSuperInterfaces =
409             TypeUtil.getSuperInterfaces(jcl, homeRemoteIntf,"java.rmi.Remote");
410
411         Set remoteSuperInterfaces = new HashSet();
412
413         Iterator iter = allSuperInterfaces.iterator();
414         while (iter.hasNext()) {
415             String JavaDoc intfName = (String JavaDoc) iter.next();
416             Class JavaDoc intfClass = jcl.loadClass(intfName);
417             if ( java.rmi.Remote JavaDoc.class.isAssignableFrom(intfClass) &&
418                  !(intfName.equals("javax.ejb.EJBHome")) &&
419                  !(intfName.equals("javax.ejb.EJBObject")) ) {
420                 remoteSuperInterfaces.add(intfName);
421             }
422         }
423
424         return remoteSuperInterfaces;
425     }
426
427 /**
428      * Returns the EJB Remote and Home interfaces that do not correspond
429      * to an ejb *within* this application. These will be used to generate
430      * stubs for ejb clients so that no additional packaging is required by
431      * the deployer in cases where the target ejb lives in another application.
432      *
433      * @param jcl class loader for an app or stand alone module
434      * @param app application to be searched for ejb client classes
435      * @param stubClasses contains any classes that have
436      * already been identified as needing stubs generated for them.
437      *
438      * @exception IOException if an i/o error
439      * @exception ClassNotFoundException if a class is not available in
440      * the class path
441      */

442     private Set getEjbClientStubClasses(ClassLoader JavaDoc jcl,
443                                    Application application, Set stubClasses)
444         throws IOException, ClassNotFoundException JavaDoc
445     {
446
447         Set ejbClientStubClasses = new HashSet();
448         final String JavaDoc BASE_HOME = "javax.ejb.EJBHome";
449         final String JavaDoc BASE_REMOTE = "javax.ejb.EJBObject";
450
451         Vector ejbRefs = application.getEjbReferenceDescriptors();
452
453         for (int i = 0; i < ejbRefs.size(); i++) {
454
455             EjbReferenceDescriptor next =
456                 (EjbReferenceDescriptor) ejbRefs.get(i);
457
458             if( next.isLocal() || next.isEJB30ClientView() ) {
459                 continue;
460             }
461
462             String JavaDoc home = next.getEjbHomeInterface();
463             String JavaDoc remote = next.getEjbInterface();
464            
465             ejbClientStubClasses.add(home);
466             Set homeSuperIntfs = getRemoteSuperInterfaces(jcl, home);
467             ejbClientStubClasses.addAll(homeSuperIntfs);
468                                                    
469             ejbClientStubClasses.add(remote);
470             Set remoteSuperIntfs = getRemoteSuperInterfaces(jcl, remote);
471             ejbClientStubClasses.addAll(remoteSuperIntfs);
472         }
473
474         return ejbClientStubClasses;
475     }
476
477     /**
478      * Returns all the classes that require RMI-IIOP stubs.
479      *
480      * @param jcl class loader for an app or stand alone module
481      * @param ejbHomeInterfaces all home interfaces
482      * @param ejbRemoteInterfaces all remote interfaces
483      * @param remoteEjbDescriptors remote ejbs that need stubs generated
484      * @return all classes requiring RMI-IIOPS stubs
485      * @exception IOException if an i/o error
486      * @exception ClassNotFoundException if a class is not available in
487      * the class path
488      */

489     private Set getStubClasses(ClassLoader JavaDoc jcl,
490                                Set ejbHomeInterfaces, Set ejbRemoteInterfaces,
491                                List remoteEjbDescriptors)
492             throws IOException, ClassNotFoundException JavaDoc
493     {
494       
495         Set stubClasses = new HashSet();
496      
497         for (Iterator iter = remoteEjbDescriptors.iterator(); iter.hasNext();)
498         {
499
500             EjbDescriptor desc = (EjbDescriptor) iter.next();
501
502             String JavaDoc home = desc.getHomeClassName();
503             String JavaDoc remote = desc.getRemoteClassName();
504
505             stubClasses.add(home);
506             Set homeSuperIntfs = getRemoteSuperInterfaces(jcl, home);
507             stubClasses.addAll(homeSuperIntfs);
508                         
509                         
510             stubClasses.add(remote);
511             Set remoteSuperIntfs = getRemoteSuperInterfaces(jcl, remote);
512             stubClasses.addAll(remoteSuperIntfs);
513             
514         }
515
516         return stubClasses;
517     }
518
519     /**
520      * Helper method - returns the class path as string with path separator.
521      *
522      * @param paths array of class paths
523      * @param other additional directory to be added to the class path
524      *
525      * @return class path for the given application
526      */

527     private String JavaDoc getClassPath(String JavaDoc[] paths, File other) {
528
529         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
530
531         for (int i=0; i<paths.length; i++) {
532             sb.append(paths[i]+File.pathSeparator);
533         }
534
535         if (other != null) {
536             sb.append(other.toString());
537         }
538
539         return sb.toString();
540     }
541
542     /**
543      * Generates and compiles the necessary impl classes, stubs and skels.
544      *
545      * <pre>
546      *
547      * This method makes the following assumptions:
548      * - the deployment descriptor xmls are registered with Config
549      * - the class paths are registered with Config
550      *
551      * @@@
552      * In case of re-deployment, the following steps should happen before:
553      * - rename the src dir from previous deployment (ex. /app/pet-old)
554      * - rename the stubs dir from previous deployment (ex. /stub/pet-old)
555      * - explode the ear file (ex. /app/petstore)
556      * - register the deployment descriptor xml with config
557      * - register the class path with config
558      *
559      * After successful completion of this method, the old src and sutbs
560      * directories may be deleted.
561      *
562      * </pre>
563      *
564      * @param ejbcCtx runtime environment for ejbc
565      *
566      * @return array of the client stubs files as zip items or empty array
567      *
568      * @exception GeneratorException if an error while code generation
569      * @exception ClassNotFoundException if class not available in the
570      * class path to be loaded
571      * @exception IOException if an i/o error
572      * @exception CmpCompilerException if an error from CMP compiler
573      * @exception Exception other exceptions (?)
574      */

575     public static ZipItem[] ejbc(EjbcContext ejbcCtx)
576             throws GeneratorException, ClassNotFoundException JavaDoc, IOException,
577                    CmpCompilerException, Exception JavaDoc
578     {
579         IASEJBC ejbc = new IASEJBC();
580         return ejbc.doCompile(ejbcCtx);
581     }
582
583     private ZipItem[] doCompile(EjbcContext ejbcCtx)
584             throws GeneratorException, ClassNotFoundException JavaDoc, IOException,
585                    CmpCompilerException, Exception JavaDoc
586     {
587         
588         // stubs dir for the current deployment
589
File stubsDir = ejbcCtx.getStubsDir();
590
591         // deployment descriptor object representation
592
Application application = ejbcCtx.getDescriptor();
593
594         long startTime = now();
595         long time; // scratchpad variable
596

597         _logger.log(Level.FINE, "ejbc.begin",application.getRegistrationName());
598
599         // class path to be used for this application during javac & rmic
600
String JavaDoc classPath = getClassPath(ejbcCtx.getClasspathUrls(), stubsDir);
601
602         // Warning: A class loader is passed in while constructing the
603
// application object
604
final ClassLoader JavaDoc jcl = application.getClassLoader();
605
606         // creates the stubs dir if it does not exist
607
if (!stubsDir.exists()) {
608             stubsDir.mkdirs();
609         }
610         // stubs dir is used as repository for code generator
611
final String JavaDoc gnrtrTMP = stubsDir.getCanonicalPath();
612
613         // previous thread context class loader
614
final ClassLoader JavaDoc oContextCL =
615             Thread.currentThread().getContextClassLoader();
616
617         // sets the thread context classloader for use by rmic etc.
618
java.security.AccessController.doPrivileged(
619             new java.security.PrivilegedAction JavaDoc() {
620                 public Object JavaDoc run() {
621                     Thread.currentThread().setContextClassLoader(jcl);
622                     return null;
623                 }
624             }
625         );
626
627
628         // ---- CMP --------------------------------------------------------
629

630         if (application.containsCMPEntity()) {
631             CmpCompiler cmpc = new CmpCompiler(ejbcCtx);
632             cmpc.compile();
633         }
634
635         // ---- END OF CMP -------------------------------------------------
636

637         // ---- EJB DEPLOYMENT DESCRIPTORS -------------------------------
638

639         Vector ejbRemoteDeploymentDescriptors = new Vector();
640         Set ejbHomeInterfaces = new HashSet();
641         Set ejbRemoteInterfaces = new HashSet();
642         Set<String JavaDoc> nonSerializableSfulClasses = new HashSet();
643         Set<String JavaDoc> ejb30RemoteBusinessInterfaces = new HashSet();
644
645         // Open the app using the JarClassLoader to load classes.
646
// This allows the descriptors to find generated classes
647
// (e.g. the generated CMP bean class) as soon as they are
648
// compiled below.
649
int ejbCount = 0;
650         Iterator iter = application.getEjbDescriptors().iterator();
651
652
653         // The main use-case we want to support is the one where existing
654
// stand-alone java clients that access ejbs in our appserver
655
// through CosNaming need the generated stubs. We don't want to
656
// force them to run rmic themselves so it's better for them
657
// just to tell us during the deployment of an ejb client app
658
// or ejb app that we should run rmic and put the stubs in the
659
// client.jar. Turning on the deployment-time rmic flag ONLY
660
// controls the generation of rmic stubs. It is independent of the
661
// run-time decision about whether to use dynamic RMI stubs. By
662
// default, dynamic stubs will be used in the server, in
663
// the Application Client container, and in stand-alone clients
664
// that instantiate our naming service. If the server has been
665
// explicitly configured for static RMI stubs by use of the
666
// internal ORB system property, we will always call RMIC.
667
boolean generateRmicStubs =
668             ( ejbcCtx.getDeploymentRequest().getGenerateRMIStubs() );
669             // ||
670
// !EJBUtils.getOrbUseDynamicStubs() );
671

672         while (iter.hasNext()) {
673             ejbCount++;
674             EjbDescriptor next = (EjbDescriptor) iter.next();
675
676
677             if( next.isLocalBusinessInterfacesSupported() ) {
678                 for(String JavaDoc nextBusIntfStr :
679                         next.getLocalBusinessClassNames() ) {
680                     Class JavaDoc intf = jcl.loadClass(nextBusIntfStr);
681                     if(javax.ejb.EJBLocalObject JavaDoc.class.isAssignableFrom(intf)) {
682                         throw new GeneratorException("Invalid Local Business "
683                            + "Interface " + intf + ". A Local Business " +
684                          "interface MUST not extend javax.ejb.EJBLocalObject");
685                     }
686                 }
687             }
688
689             if( next.isRemoteInterfacesSupported() ) {
690                 
691                 if( generateRmicStubs ) {
692                     ejbRemoteDeploymentDescriptors.addElement(next);
693                     ejbHomeInterfaces.add(next.getHomeClassName());
694                     ejbRemoteInterfaces.add(next.getRemoteClassName());
695                 } else {
696                     _logger.log(Level.FINE,
697                                 "Skipping RMI-IIOP STUB generation for"
698                                 + " " + next.getName());
699                 }
700             }
701             
702             if( next.isRemoteBusinessInterfacesSupported() ) {
703
704                 for(String JavaDoc nextIntf : next.getRemoteBusinessClassNames() ) {
705                     // If there's more than one ejb with same
706
// Remote business interface, only generate
707
// the artifacts once. This will work since
708
// there is nothing bean-specific about the
709
// generated artifacts. Their only dependency is
710
// the corresponding Remote business interface.
711
if( !ejb30RemoteBusinessInterfaces.contains(nextIntf) ) {
712                         ejb30RemoteBusinessInterfaces.add(nextIntf);
713                     }
714                 }
715             }
716
717             if( next.getType().equals(EjbSessionDescriptor.TYPE) &&
718                 ((EjbSessionDescriptor)next).isStateful() ) {
719
720                 Set<String JavaDoc> classNames = new HashSet<String JavaDoc>();
721                 classNames.add(next.getEjbClassName());
722                 classNames.addAll(next.getInterceptorClassNames());
723
724                 for(String JavaDoc className : classNames) {
725                     Class JavaDoc clazz = jcl.loadClass(className);
726                     if( !Serializable.class.isAssignableFrom(clazz) ) {
727                         // Add for processing. Duplicates will be ignored
728
// by Set.
729
nonSerializableSfulClasses.add(className);
730                     }
731                 }
732             }
733         }
734
735         // Need to generate Remote 3.0 internal intf/wrappers for
736
// EJB 3.0 Remote clients as well. This will be removed
737
// when we move to the new codegen API.
738
Vector ejbRefs = application.getEjbReferenceDescriptors();
739         for (int i = 0; i < ejbRefs.size(); i++) {
740             EjbReferenceDescriptor next =
741                 (EjbReferenceDescriptor) ejbRefs.get(i);
742             if( next.isEJB30ClientView() && !next.isLocal() ) {
743                 String JavaDoc busInterface = next.getEjbInterface();
744                 if( !ejb30RemoteBusinessInterfaces.contains(busInterface) ) {
745                     ejb30RemoteBusinessInterfaces.add(busInterface);
746                 }
747             }
748         }
749
750         progress(localStrings.getStringWithDefault
751                  ("generator.processing_beans", "Processing beans..."));
752
753
754         // ---- END OF EJB DEPLOYMENT DESCRIPTORS --------------------------
755

756         // ---- LOCAL HOME & OBJECT ----------------------------------------
757

758         FileArchive dArchive = new FileArchive();
759         dArchive.open(gnrtrTMP);
760         DeploymentContext context = new DeploymentContext(dArchive,application);
761
762         // Generate code for Remote EJB 30 business interfaces
763
Vector remote30Files = new Vector();
764
765         if( EJBUtils.useStaticCodegen() ) {
766
767             // Generic a single generic home interface for this application.
768
Generator genericHomeGen = new GenericHomeGenerator
769                 (context.getClassLoader());
770             
771             generateCode(genericHomeGen, remote30Files, stubsDir);
772
773             for (String JavaDoc businessIntf : ejb30RemoteBusinessInterfaces) {
774
775                 // generate RMI-IIOP version of Remote business interface
776
Generator remoteGen =
777                     new RemoteGenerator(context.getClassLoader(),
778                                         businessIntf);
779                 
780                 generateCode(remoteGen, remote30Files, stubsDir);
781                 
782                 Generator clientGen = new Remote30WrapperGenerator
783                     (context.getClassLoader(), businessIntf,
784                      remoteGen.getGeneratedClass());
785                 
786                 generateCode(clientGen, remote30Files, stubsDir);
787             }
788             // log completion message
789
if (remote30Files.size() > 0) {
790                 
791                 // compile generated Remote business interfaces
792
time = now();
793                 compileClasses(classPath, remote30Files, stubsDir, gnrtrTMP,
794                                ejbcCtx.getJavacOptions());
795                 ejbcCtx.getTiming().javaCompileTime += (now() - time);
796             
797                 _logger.fine("Done generating Remote business intfs");
798             }
799
800
801             // Generate any serializable sub-classes for EJB 3.0 stateful
802
// session beans and stateful session bean interceptors that
803
// don't implement Serializable. These classes
804
// are not put in the client.jar.
805
Vector serializableSfulSubClasses = new Vector();
806             for(String JavaDoc className : nonSerializableSfulClasses) {
807                 Generator serializableSfulGen =
808                     new SerializableBeanGenerator(context.getClassLoader(),
809                                                   className);
810
811                 generateCode(serializableSfulGen, serializableSfulSubClasses,
812                              stubsDir);
813             }
814
815             if( serializableSfulSubClasses.size() > 0 ) {
816                 // compile generated stateful serializable sub-classes
817
time = now();
818                 compileClasses(classPath, serializableSfulSubClasses, stubsDir,
819                                gnrtrTMP, ejbcCtx.getJavacOptions());
820                            
821                 ejbcCtx.getTiming().javaCompileTime += (now() - time);
822             
823                 _logger.fine("Generated Stateful Serializable subclasses");
824                         
825             }
826         }
827
828         // ---- WEB SERVICES -----------------------------------------------
829

830         
831         if (_logger.isLoggable(Level.FINE)) {
832             _logger.log(Level.FINE, "ejbc.start_jaxrpc_generation",
833                         application.getRegistrationName());
834         }
835         time = now();
836
837         JaxRpcCodegenFactory jaxrpcFactory =
838             JaxRpcCodegenFactory.newInstance();
839         JaxRpcCodegenAdapter jaxrpcAdapter = jaxrpcFactory.getAdapter();
840         jaxrpcAdapter.run(ejbcCtx);
841         
842         ejbcCtx.getTiming().jaxrpcGenerationTime += (now() - time);
843         
844         if (_logger.isLoggable(Level.FINE)) {
845             _logger.log(Level.FINE, "ejbc.end_jaxrpc_generation",
846                         application.getRegistrationName());
847         }
848         
849         // this should not be here but in AppDeployer or such but since
850
// the archive file is saved at then end of this ejbc process, and
851
// the servlet swith may require to save the DDs, I decided to put
852
// it here until we rework the codegen pluggability.
853
WebServiceDeployer deployer =
854             new WebServiceDeployer(ejbcCtx.getDeploymentRequest());
855         deployer.doWebServiceDeployment(ejbcCtx.getDescriptor(),
856                                         ejbcCtx.getSrcDir());
857         
858         
859         // ---- END OF WEB SERVICES ----------------------------------------
860

861         // ---- RMIC ALL STUB CLASSES --------------------------------------
862

863         Set allStubClasses = new HashSet();
864
865         if( generateRmicStubs ) {
866             // stubs classes for ejbs within this app that need rmic
867
Set ejbStubClasses = getStubClasses(jcl, ejbHomeInterfaces,
868                   ejbRemoteInterfaces, ejbRemoteDeploymentDescriptors);
869             
870             // stubs for any J2EE components within the app that are clients
871
// of remote ejbs but where the target ejbs are not defined within
872
// the app
873
Set ejbClientStubClasses =
874                 getEjbClientStubClasses(jcl, application, ejbStubClasses);
875                         
876             allStubClasses.addAll(ejbStubClasses);
877             allStubClasses.addAll(ejbClientStubClasses);
878             
879             // Compile and RMIC all Stubs
880

881             time = now();
882             compileAndRmic(classPath, ejbcCtx.getRmicOptions(), allStubClasses,
883                            stubsDir, gnrtrTMP);
884             
885             ejbcCtx.getTiming().RMICompileTime += (now() - time);
886         }
887
888         // ---- END OF RMIC ALL STUB CLASSES -------------------------------
889

890         // Create list of all server files and client files
891
Vector allClientFiles = new Vector();
892
893         // assemble the client files
894
addGeneratedFiles(allStubClasses, allClientFiles, stubsDir);
895
896         if( remote30Files.size() > 0 ) {
897             
898             Iterator itr = remote30Files.iterator();
899             if (itr != null) {
900                 for (;itr.hasNext();) {
901                     String JavaDoc file = (String JavaDoc) itr.next();
902                     allClientFiles.add(file.replace(".java", ".class"));
903                 }
904             }
905
906         }
907                           
908         if (jaxrpcAdapter!=null) {
909             Iterator itr = jaxrpcAdapter.getListOfBinaryFiles();
910             if (itr!=null) {
911                 for (;itr.hasNext();) {
912                     allClientFiles.add(itr.next());
913                 }
914             }
915         }
916
917         // client zip entries
918
ZipItem[] clientStubs = getClientZipEntries(allClientFiles, stubsDir);
919
920         _logger.log(Level.FINE, "ejbc.end", application.getRegistrationName());
921         ejbcCtx.getTiming().totalTime = now() - startTime;
922
923         // sets the old thread context classloader back
924
// this allows the EJB class loader to be garbage collected
925
java.security.AccessController.doPrivileged(
926             new java.security.PrivilegedAction JavaDoc() {
927                 public Object JavaDoc run() {
928                     Thread.currentThread().setContextClassLoader(oContextCL);
929                     return null;
930                 }
931             }
932         );
933
934         /*
935          *Clean up, releasing the class loader.
936          */

937         jaxrpcAdapter.done();
938         
939         return clientStubs;
940     }
941
942     private long now()
943     {
944         return System.currentTimeMillis();
945     }
946
947     private void progress(String JavaDoc message) {
948             try {
949                 _logger.log(Level.FINE, message);
950             } catch(Throwable JavaDoc t) {
951                 _logger.log(Level.FINER,"Cannot set status message",t);
952             }
953     }
954
955 }
956
Popular Tags