001: /**
002: * JOnAS: Java(TM) Open Application Server
003: * Copyright (C) 1999-2004 Bull S.A.
004: * Contact: jonas-team@objectweb.org
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
019: * USA
020: *
021: * --------------------------------------------------------------------------
022: * $Id: BeanSources.java 10022 2007-02-21 07:40:36Z pelletib $
023: * --------------------------------------------------------------------------
024: */package org.objectweb.jonas_ejb.genic;
025:
026: import java.io.File;
027: import java.util.ArrayList;
028: import java.util.Collection;
029: import java.util.Iterator;
030:
031: import org.apache.velocity.app.VelocityEngine;
032:
033: import org.objectweb.jonas_ejb.deployment.api.BeanDesc;
034: import org.objectweb.jonas_ejb.deployment.api.EntityCmp2Desc;
035: import org.objectweb.jonas_ejb.deployment.api.EntityDesc;
036: import org.objectweb.jonas_ejb.deployment.api.EntityJdbcCmp1Desc;
037: import org.objectweb.jonas_ejb.deployment.api.SessionStatelessDesc;
038: import org.objectweb.jonas_ejb.deployment.api.SessionStatefulDesc;
039:
040: import org.objectweb.jonas_ejb.lib.BeanNaming;
041: import org.objectweb.jonas_ejb.lib.RdbMappingBuilder;
042:
043: import org.objectweb.jonas.common.Log;
044:
045: import org.objectweb.jorm.compiler.api.JormCompilerParameter;
046: import org.objectweb.jorm.compiler.lib.JormCompiler;
047:
048: import org.objectweb.util.monolog.api.BasicLevel;
049: import org.objectweb.util.monolog.api.Logger;
050:
051: /**
052: * This class allows to generate the sources of: the class that implements the
053: * Enterprise bean's remote interface, the class that implements the Enterprise
054: * bean's home interface, the class that implements the Enterprise bean's local
055: * interface, the class that implements the Enterprise bean's localhome
056: * interface, the class of the Entity Handle in case of entity, and the extended
057: * class of the Bean for persistence in case of entity with CMP, of a given
058: * Enterprise Java Bean.
059: * @author Helene Joanin : Initial developer
060: * @author Philippe Durieux
061: * @author Sebastien Chassande
062: */
063: public class BeanSources {
064:
065: /**
066: * java file suffix
067: */
068: private static final String JAVA_SUFFIX = ".java";
069:
070: /**
071: * Cluster suffix
072: */
073: private static final String CLUSTER_SUFFIX = "_Cmi";
074:
075: /**
076: * EJBObject (Remote). May be null if no Remote interface.
077: */
078: private String wrpRemoteFileName = null;
079:
080: /**
081: * EJBLocalObject (Local). May be null if no Local interface.
082: */
083: private String wrpLocalFileName = null;
084:
085: /**
086: * Home. May be null if no Home interface.
087: */
088: private String wrpHomeFileName = null;
089:
090: /**
091: * Home cluster file name. May be null if no Home interface.
092: */
093: private String wrpHomeClusterFileName = null;
094:
095: /**
096: * Remote cluster file name. May be null if no Remote interface.
097: */
098: private String wrpRemoteClusterFileName = null;
099:
100: /**
101: * LocalHome. May be null if no LocalHome interface.
102: */
103: private String wrpLocalHomeFileName = null;
104:
105: /**
106: * Handle (for Entity only)
107: */
108: private String wrpHandleFileName = null;
109:
110: /**
111: * Bean (for CMP Entity only)
112: */
113: private String wrpBeanFileName = null;
114:
115: /**
116: * Service Endpoint filename
117: */
118: private String wrpServiceEndpointFileName = null;
119:
120: /**
121: * Service Endpoint Home filename
122: */
123: private String wrpSEHomeFileName = null;
124:
125: /**
126: * Interface for Cmp2 Entity coherence
127: */
128: private String itfCohCmp2Entity = null;
129:
130: /**
131: * Source objects used to generate classes
132: */
133: private ArrayList sources;
134:
135: /**
136: * Java sources that are not Remote
137: */
138: private ArrayList noRemoteJava;
139:
140: /**
141: * directory where to place the generated files
142: */
143: private String outdir = null;
144:
145: /**
146: * bean descriptor
147: */
148: private BeanDesc dd = null;
149:
150: /**
151: * JORM compiler
152: */
153: private JormCompiler jormCompiler;
154:
155: /**
156: * logger
157: */
158: private Logger logger = null;
159:
160: /**
161: * BeanSources Constructor for entity bean with CMP2
162: * @param beanDesc deployment descriptor of the bean
163: * @param gp GenIC parameters
164: * @param ve the Velocity engine
165: * @param jormCompiler the JROM compiler
166: * @exception GenICException In error case
167: */
168: public BeanSources(BeanDesc beanDesc, GenICParameters gp,
169: VelocityEngine ve, JormCompiler jormCompiler)
170: throws GenICException {
171: this (beanDesc, gp, ve);
172: this .jormCompiler = jormCompiler;
173: }
174:
175: /**
176: * BeanSources Constructor for bean that is not a entity with CMP2
177: * @param beanDesc deployment descriptor of the bean
178: * @param gp @param gp GenIC parameters
179: * @param ve the Velocity engine
180: * @exception GenICException In error case
181: */
182: public BeanSources(BeanDesc beanDesc, GenICParameters gp,
183: VelocityEngine ve) throws GenICException {
184:
185: logger = Log.getLogger(Log.JONAS_GENIC_PREFIX);
186: dd = beanDesc;
187: outdir = gp.getOutputDirectory();
188: sources = new ArrayList();
189: noRemoteJava = new ArrayList();
190:
191: // generated Home
192: if (dd.getHomeClass() != null) {
193: if (outdir.length() > 0) {
194: wrpHomeFileName = outdir + File.separatorChar
195: + BeanNaming.getPath(dd.getFullWrpHomeName());
196: } else {
197: wrpHomeFileName = dd.getWrpHomeName();
198: }
199:
200: // Only generate _Cmi java sources when cmi is in the protocols list
201: if (gp.getProtocols().isSupported("cmi")) {
202: if (dd.getClusterHomeDistributor() != null
203: && dd.getClusterHomeDistributor()
204: .equalsIgnoreCase(
205: Source.CLUSTER_DISABLED)) {
206: // the cluster feature is disabled for this bean
207: logger.log(BasicLevel.DEBUG,
208: "Clustering disabled for the bean "
209: + dd.getEjbName()
210: + "- Home CMI class not generated");
211: } else {
212: // for the stateless, we generate both the Home and Remote
213: // '_Cmi' files and leave
214: // the choice to the user
215: if (dd instanceof SessionStatefulDesc) {
216: wrpHomeClusterFileName = wrpHomeFileName
217: .concat(CLUSTER_SUFFIX + JAVA_SUFFIX);
218: noRemoteJava.add(wrpHomeClusterFileName);
219: sources.add(new Source(dd,
220: wrpHomeClusterFileName,
221: Source.CLUSTER_HOME_SFSB, ve));
222: } else if (dd instanceof EntityDesc) {
223: wrpHomeClusterFileName = wrpHomeFileName
224: .concat(CLUSTER_SUFFIX + JAVA_SUFFIX);
225: noRemoteJava.add(wrpHomeClusterFileName);
226: sources.add(new Source(dd,
227: wrpHomeClusterFileName,
228: Source.CLUSTER_HOME_ENTITY, ve));
229: } else {
230: wrpHomeClusterFileName = wrpHomeFileName
231: .concat(CLUSTER_SUFFIX + JAVA_SUFFIX);
232: noRemoteJava.add(wrpHomeClusterFileName);
233: sources.add(new Source(dd,
234: wrpHomeClusterFileName,
235: Source.CLUSTER_HOME, ve));
236: }
237: }
238: }
239:
240: wrpHomeFileName = wrpHomeFileName.concat(JAVA_SUFFIX);
241: sources
242: .add(new Source(dd, wrpHomeFileName, Source.HOME,
243: ve));
244:
245: // generated Handle for Remote Entity bean
246: if (dd instanceof EntityDesc) {
247: if (outdir.length() > 0) {
248: wrpHandleFileName = outdir
249: + File.separatorChar
250: + BeanNaming.getPath(dd
251: .getFullWrpHandleName());
252: } else {
253: wrpHandleFileName = dd.getWrpHandleName();
254: }
255: wrpHandleFileName = wrpHandleFileName
256: .concat(JAVA_SUFFIX);
257: noRemoteJava.add(wrpHandleFileName);
258: sources.add(new Source(dd, wrpHandleFileName,
259: Source.ENTITY_HANDLE, ve));
260: }
261: }
262:
263: // generated EJBObject (Remote)
264: if (dd.getRemoteClass() != null) {
265: if (outdir.length() > 0) {
266: wrpRemoteFileName = outdir + File.separatorChar
267: + BeanNaming.getPath(dd.getFullWrpRemoteName());
268: } else {
269: wrpRemoteFileName = dd.getWrpRemoteName();
270: }
271:
272: // Only generate _Cmi java sources when cmi is in the protocols list and for SSB
273: // For the SFSB, the _Cmi class is generated only the replication is required in the DD (cluster-replicated=true)
274: if (gp.getProtocols().isSupported("cmi")) {
275: SessionStatelessDesc ssbDd = null;
276: if (dd instanceof SessionStatelessDesc) {
277: ssbDd = (SessionStatelessDesc) dd;
278: }
279:
280: if ((dd.getClusterHomeDistributor() != null && dd
281: .getClusterHomeDistributor().equalsIgnoreCase(
282: Source.CLUSTER_DISABLED))
283: || (dd.getClusterRemoteDistributor() != null && dd
284: .getClusterRemoteDistributor()
285: .equalsIgnoreCase(
286: Source.CLUSTER_DISABLED))
287: || (ssbDd != null && ssbDd.isSingleton() == false)) {
288: // the cluster feature is disabled for this bean or the SSB is not a singleton
289: logger
290: .log(
291: BasicLevel.DEBUG,
292: "Clustering disabled for the bean "
293: + dd.getEjbName()
294: + "- Remote CMI class not generated");
295:
296: } else {
297: if (dd instanceof SessionStatelessDesc) {
298: wrpRemoteClusterFileName = wrpRemoteFileName
299: .concat(CLUSTER_SUFFIX + JAVA_SUFFIX);
300: noRemoteJava.add(wrpRemoteClusterFileName);
301: sources.add(new Source(dd,
302: wrpRemoteClusterFileName,
303: Source.CLUSTER_REMOTE, ve));
304: } else if (dd instanceof SessionStatefulDesc
305: && dd.isClusterReplicated()) {
306: wrpRemoteClusterFileName = wrpRemoteFileName
307: .concat(CLUSTER_SUFFIX + JAVA_SUFFIX);
308: noRemoteJava.add(wrpRemoteClusterFileName);
309: sources.add(new Source(dd,
310: wrpRemoteClusterFileName,
311: Source.CLUSTER_REMOTE_SFSB, ve));
312: } else if (dd instanceof EntityDesc
313: && dd.isClusterReplicated()) {
314: wrpRemoteClusterFileName = wrpRemoteFileName
315: .concat(CLUSTER_SUFFIX + JAVA_SUFFIX);
316: noRemoteJava.add(wrpRemoteClusterFileName);
317: sources.add(new Source(dd,
318: wrpRemoteClusterFileName,
319: Source.CLUSTER_REMOTE_ENTITY, ve));
320: }
321: }
322: }
323:
324: wrpRemoteFileName = wrpRemoteFileName.concat(JAVA_SUFFIX);
325: sources.add(new Source(dd, wrpRemoteFileName,
326: Source.REMOTE, ve));
327: }
328:
329: // generated LocalHome
330: if (dd.getLocalHomeClass() != null) {
331: if (outdir.length() > 0) {
332: wrpLocalHomeFileName = outdir
333: + File.separatorChar
334: + BeanNaming.getPath(dd
335: .getFullWrpLocalHomeName());
336: } else {
337: wrpLocalHomeFileName = dd.getWrpLocalHomeName();
338: }
339: wrpLocalHomeFileName = wrpLocalHomeFileName
340: .concat(JAVA_SUFFIX);
341: noRemoteJava.add(wrpLocalHomeFileName);
342: sources.add(new Source(dd, wrpLocalHomeFileName,
343: Source.LOCAL_HOME, ve));
344: }
345:
346: // generated EJBLocalObject (Local)
347: if (dd.getLocalClass() != null) {
348: if (outdir.length() > 0) {
349: wrpLocalFileName = outdir + File.separatorChar
350: + BeanNaming.getPath(dd.getFullWrpLocalName());
351: } else {
352: wrpLocalFileName = dd.getWrpLocalName();
353: }
354: wrpLocalFileName = wrpLocalFileName.concat(JAVA_SUFFIX);
355: noRemoteJava.add(wrpLocalFileName);
356: sources.add(new Source(dd, wrpLocalFileName, Source.LOCAL,
357: ve));
358: }
359:
360: // generated ServiceEndpoint and SEHome
361: if (dd instanceof SessionStatelessDesc) {
362: SessionStatelessDesc ssd = (SessionStatelessDesc) dd;
363: if (ssd.getServiceEndpointClass() != null) {
364: // ServiceEndpoint
365: if (outdir.length() > 0) {
366: wrpServiceEndpointFileName = outdir
367: + File.separatorChar
368: + BeanNaming.getPath(ssd
369: .getFullWrpServiceEndpointName());
370: } else {
371: wrpServiceEndpointFileName = ssd
372: .getWrpServiceEndpointName();
373: }
374: wrpServiceEndpointFileName = wrpServiceEndpointFileName
375: .concat(JAVA_SUFFIX);
376: //noRemoteJava.add(wrpServiceEndpointFileName); // Accessed locally only
377: sources.add(new Source(dd, wrpServiceEndpointFileName,
378: Source.SERVICE_ENDPOINT, ve));
379: // ServiceEndpointHome
380: if (outdir.length() > 0) {
381: wrpSEHomeFileName = outdir
382: + File.separatorChar
383: + BeanNaming.getPath(ssd
384: .getFullWrpSEHomeName());
385: } else {
386: wrpSEHomeFileName = ssd.getWrpSEHomeName();
387: }
388: wrpSEHomeFileName = wrpSEHomeFileName
389: .concat(JAVA_SUFFIX);
390: noRemoteJava.add(wrpSEHomeFileName); // Accessed locally only
391: sources.add(new Source(dd, wrpSEHomeFileName,
392: Source.SERVICE_ENDPOINT_HOME, ve));
393: }
394: }
395:
396: // generated derived bean class for Entity Bean CMP
397: if (dd instanceof EntityJdbcCmp1Desc) {
398: if (outdir.length() > 0) {
399: wrpBeanFileName = outdir
400: + File.separatorChar
401: + BeanNaming.getPath(dd
402: .getFullDerivedBeanName());
403: } else {
404: wrpBeanFileName = dd.getDerivedBeanName();
405: }
406: wrpBeanFileName = wrpBeanFileName.concat(JAVA_SUFFIX);
407: noRemoteJava.add(wrpBeanFileName);
408: sources.add(new Source(dd, wrpBeanFileName,
409: Source.ENTITY_CMP_JDBC, ve));
410: }
411: if (dd instanceof EntityCmp2Desc) {
412: EntityCmp2Desc ecd = (EntityCmp2Desc) dd;
413: if (outdir.length() > 0) {
414: wrpBeanFileName = outdir
415: + File.separatorChar
416: + BeanNaming.getPath(dd
417: .getFullDerivedBeanName())
418: + JAVA_SUFFIX;
419: if (ecd.needJormCoherenceHelper()) {
420: itfCohCmp2Entity = outdir
421: + File.separatorChar
422: + BeanNaming.getPath(ecd
423: .getJormCoherenceHelperFQItfName())
424: + JAVA_SUFFIX;
425: }
426: } else {
427: wrpBeanFileName = BeanNaming.getPath(dd
428: .getDerivedBeanName())
429: + JAVA_SUFFIX;
430: if (ecd.needJormCoherenceHelper()) {
431: itfCohCmp2Entity = BeanNaming.getPath(ecd
432: .getJormCoherenceHelperItfName())
433: + JAVA_SUFFIX;
434: }
435: }
436: if (ecd.needJormCoherenceHelper()) {
437: sources.add(new Source(dd, itfCohCmp2Entity,
438: Source.ITF_COH_CMP2_ENTITY, ve));
439: noRemoteJava.add(itfCohCmp2Entity);
440: }
441: noRemoteJava.add(wrpBeanFileName);
442: sources.add(new Source(dd, wrpBeanFileName,
443: Source.ENTITY_CMP_JDBC, ve));
444: }
445: }
446:
447: /**
448: * Generates the java sources
449: * @throws GenICException in error case
450: */
451: public void generate() throws GenICException {
452: // Generates the java sources
453: for (Iterator it = sources.iterator(); it.hasNext();) {
454: Source src = (Source) it.next();
455: src.generate();
456: }
457:
458: // In case of Cmp2, call jorm compiler.
459: if (dd instanceof EntityCmp2Desc) {
460: EntityCmp2Desc ecd = (EntityCmp2Desc) dd;
461:
462: // Build and fill a JormCompilerParameter dedicated to the bean
463: JormCompilerParameter cp = jormCompiler
464: .getCompilerParameter();
465: cp.setProjectName(RdbMappingBuilder.getProjectName());
466: cp.setKeepSrc(true);
467: cp.setOutput(outdir);
468: cp
469: .setClassMappingInheritance("org.objectweb.jonas_ejb.container.jorm.RdbFactory");
470: cp.setStateGenerated(true);
471: cp.setStateInheritance(ecd.getEjbClass().getName());
472: switch (ecd.getLockPolicy()) {
473: case EntityDesc.LOCK_CONTAINER_READ_UNCOMMITTED:
474: cp
475: .setBindingInheritance("org.objectweb.jonas_ejb.container.JEntitySwitchCRU");
476: break;
477: case EntityDesc.LOCK_CONTAINER_SERIALIZED:
478: cp
479: .setBindingInheritance("org.objectweb.jonas_ejb.container.JEntitySwitchCS");
480: break;
481: case EntityDesc.LOCK_CONTAINER_SERIALIZED_TRANSACTED:
482: cp
483: .setBindingInheritance("org.objectweb.jonas_ejb.container.JEntitySwitchCST");
484: break;
485: case EntityDesc.LOCK_CONTAINER_READ_COMMITTED:
486: cp
487: .setBindingInheritance("org.objectweb.jonas_ejb.container.JEntitySwitchCRC");
488: break;
489: case EntityDesc.LOCK_DATABASE:
490: cp
491: .setBindingInheritance("org.objectweb.jonas_ejb.container.JEntitySwitchDB");
492: break;
493: case EntityDesc.LOCK_READ_ONLY:
494: cp
495: .setBindingInheritance("org.objectweb.jonas_ejb.container.JEntitySwitchRO");
496: break;
497: case EntityDesc.LOCK_CONTAINER_READ_WRITE:
498: cp
499: .setBindingInheritance("org.objectweb.jonas_ejb.container.JEntitySwitchCRW");
500: break;
501: default:
502: throw new GenICException(
503: "Cannot find JEntitySwitch: Unknown lock policy");
504: }
505:
506: // Run the Jorm Compiler
507: Collection jormflist = null;
508: try {
509: // For debug only: Generate the '.pd' Jorm Files
510: if (Log.getLogger("org.objectweb.jonas_ejb.mijorm")
511: .isLoggable(BasicLevel.DEBUG)) {
512: jormCompiler.generateJormFiles(ecd.getJormList());
513: }
514: jormflist = jormCompiler.generateFiles(ecd
515: .getJormList());
516: } catch (Exception e) {
517: throw new GenICException(
518: "Problem during jorm generation", e);
519: }
520: // Save the list of Jorm generated files
521: for (Iterator i = jormflist.iterator(); i.hasNext();) {
522: String file = (String) i.next();
523: logger.log(BasicLevel.DEBUG, "Jorm generated file: "
524: + file);
525: noRemoteJava.add(file);
526: }
527: }
528: }
529:
530: /**
531: * @return Return the bean's name
532: */
533: public String getEjbName() {
534: return dd.getEjbName();
535: }
536:
537: /**
538: * @return Return the file name of the generated source for the Home (null
539: * if none)
540: */
541: public String getWrpHomeFileName() {
542: return wrpHomeFileName;
543: }
544:
545: /**
546: * @return Return the file name of the cluster configuration for the Home
547: * (null if none)
548: */
549: public String getWrpHomeClusterFileName() {
550: return wrpHomeClusterFileName;
551: }
552:
553: /**
554: * @return Return the file name of the cluster configuration for the Remote
555: * (null if none)
556: */
557: public String getWrpRemoteClusterFileName() {
558: return wrpRemoteClusterFileName;
559: }
560:
561: /**
562: * @return Return the file name of the generated source for the Remote (null
563: * if none)
564: */
565: public String getWrpRemoteFileName() {
566: return wrpRemoteFileName;
567: }
568:
569: /**
570: * @return Return the class name of the generated source for the Remote
571: * (package included)
572: */
573: public String getWrpRemoteClassName() {
574: return dd.getFullWrpRemoteName();
575: }
576:
577: /**
578: * @return Return the file name of the generated source for the
579: * ServiceEndpoint (null if none)
580: */
581: public String getWrpServiceEndpointFileName() {
582: return wrpServiceEndpointFileName;
583: }
584:
585: /**
586: * @return Return the file name of the generated source for the
587: * ServiceEndpointHome (null if none)
588: */
589: public String getWrpSEHomeFileName() {
590: return wrpSEHomeFileName;
591: }
592:
593: /**
594: * @return Return the class name of the generated source for the
595: * ServiceEndpoint (package included)
596: */
597: public String getWrpServiceEndpointClassName() {
598: if (dd instanceof SessionStatelessDesc) {
599: return ((SessionStatelessDesc) dd)
600: .getFullWrpServiceEndpointName();
601: }
602: return null;
603: }
604:
605: /**
606: * @return Return the class name of the generated source for the Home
607: * (package included)
608: */
609: public String getWrpHomeClassName() {
610: return dd.getFullWrpHomeName();
611: }
612:
613: /**
614: * @return Returns the list of the sources that are not Remote
615: */
616: public Collection getNoRemoteJavas() {
617: return noRemoteJava;
618: }
619: }
|