KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > jdo > spi > persistence > support > ejb > ejbc > JDOConcreteBean20Generator


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

23
24
25
26 /*
27  * JDOConcreteBean20Generator.java
28  *
29  * Created on February 24, 2004
30  */

31
32 package com.sun.jdo.spi.persistence.support.ejb.ejbc;
33
34 import java.util.*;
35 import java.io.IOException JavaDoc;
36 import java.lang.reflect.Method JavaDoc;
37 import java.lang.reflect.Modifier JavaDoc;
38 import java.text.MessageFormat JavaDoc;
39
40 import com.sun.jdo.api.persistence.model.Model;
41 import com.sun.jdo.api.persistence.model.ModelException;
42 import com.sun.jdo.api.persistence.model.jdo.*;
43
44 import com.sun.jdo.api.persistence.support.JDOUserException;
45 import com.sun.jdo.spi.persistence.support.ejb.model.util.NameMapper;
46 import com.sun.jdo.spi.persistence.support.ejb.ejbqlc.EJBQLC;
47 import com.sun.jdo.spi.persistence.support.ejb.ejbqlc.JDOQLElements;
48 import com.sun.jdo.spi.persistence.support.ejb.ejbqlc.EJBQLException;
49
50 import com.sun.jdo.spi.persistence.utility.I18NHelper;
51 import com.sun.jdo.spi.persistence.utility.generator.*;
52 import com.sun.jdo.spi.persistence.utility.logging.Logger;
53  
54 /*
55  * This is the JDO specific generator for the concrete CMP beans for EJB2.0
56  *
57  * @author Marina Vatkina
58  */

59 class JDOConcreteBean20Generator extends JDOConcreteBeanGenerator {
60
61     // EJBQLC ejbqlc
62
private EJBQLC ejbqlc;
63
64     /**
65      * Map that holds EJBQL compilation results for CMP 2.x beans queries.
66      * <tt>key</tt> is java.lang.reflect.Method object for the bean's
67      * finder or selector and the <tt>value</tt> is JDOQLElements object
68      * that represents EJBQL compilation results.
69      */

70     private Map jdoqlElementsMap;
71
72     // StringBuffer for cascade-delete operations on ejbRemove
73
private StringBuffer JavaDoc cascadeDelete = null;
74
75     // String for getter method body
76
private String JavaDoc gbody = null;
77
78     // String for setter method body
79
private String JavaDoc sbody = null;
80
81     /**
82      * Signature with CVS keyword substitution for identifying the generated code
83      */

84     static final String JavaDoc SIGNATURE =
85             "$RCSfile: JDOConcreteBean20Generator.java,v $ $Revision: 1.2 $"; //NOI18N
86

87     JDOConcreteBean20Generator(ClassLoader JavaDoc loader,
88                              Model model,
89                              NameMapper nameMapper)
90                              throws IOException JavaDoc {
91
92         super(loader, model, nameMapper);
93         CMP20TemplateFormatter.initHelpers();
94
95         // Add the code generation signature of the generic and 2.x-specific
96
// generator classes.
97
addCodeGeneratorClassSignature(getSignaturesOfGeneratorClasses());
98
99         // init EJBQL compiler
100
ejbqlc = new EJBQLC(model, nameMapper);
101     }
102
103     /**
104      * Validate this CMP bean. At this point, only EJBQL validation is done for
105      * 2.0 CMP beans. Adds validation result to that of the super class.
106      * @param methodHelper the AbstractMethodHelper instance that contains
107      * all categorized methods and some other convenience methods for this bean.
108      * @param beanName the ejb name for this bean.
109      * @return a Collection of Exception instances with a separate instance for
110      * each failed validation.
111      */

112     Collection validate(AbstractMethodHelper methodHelper, String JavaDoc beanName) {
113         Collection rc = super.validate(methodHelper, beanName);
114
115         this.beanName = beanName;
116         rc.addAll(validateEJBQL(methodHelper));
117
118         return rc;
119     }
120
121
122     /** Add interfaces to the class declarations.
123      */

124     void addInterfaces() throws IOException JavaDoc {
125         super.addInterfaces();
126         jdoHelperWriter.addInterface(CMP20TemplateFormatter.helper20Interface_);
127     }
128
129     /** Set super class for the helper class.
130      */

131     void setHelperSuperclass() throws IOException JavaDoc {
132         jdoHelperWriter.setSuperclass(CMP20TemplateFormatter.helper20Impl_);
133     }
134
135     /** Add import statements for for the generated classes.
136      */

137     void addImportStatements(JavaFileWriter concreteImplFileWriter,
138             JavaFileWriter helperFileWriter) throws IOException JavaDoc {
139
140         super.addImportStatements(concreteImplFileWriter, helperFileWriter);
141         concreteImplFileWriter.addImport(
142                 CMP20TemplateFormatter.ejbHashSetImport_, null);
143     }
144
145     /** Generate CMP2.0 specific methods.
146      */

147     void generateTypeSpecificMethods(PersistenceFieldElement[] allFields,
148             AbstractMethodHelper methodHelper) throws IOException JavaDoc {
149
150         super.generateTypeSpecificMethods(allFields, methodHelper);
151
152         // Print getters and setters for CMP2.0 only.
153
generateGetSetMethods(allFields);
154
155         // Add selectors.
156
generateSelectors(methodHelper);
157
158     }
159
160     /** Adds getters and setters.
161      */

162     private void generateGetSetMethods(PersistenceFieldElement[] fields)
163                        throws IOException JavaDoc{
164         int i, count = ((fields != null) ? fields.length : 0);
165         setPKField = null; // reset to null to clean it up.
166
cascadeDelete = new StringBuffer JavaDoc();
167
168         // jdoCleanCollectionRef() body
169
StringBuffer JavaDoc cmrcleanbodyBuf = new StringBuffer JavaDoc(CMP20TemplateFormatter.none_);
170
171         for (i = 0; i < count; i++) {
172             PersistenceFieldElement pfe = fields[i];
173
174             if (PersistenceFieldElement.PERSISTENT == pfe.getPersistenceType()) {
175
176                 // Reset the strings.
177
gbody = null;
178                 sbody = null;
179
180                 FieldInfo fieldInfo = new FieldInfo(model, nameMapper, pfe, beanName, pcname);
181
182                 if (fieldInfo.isGeneratedField) {
183                 // Skip generated fields as they are not present in the bean class.
184
// A field is generated for the unknown PK class, version consistency, or
185
// a 2 way managed relationship.
186
if (fieldInfo.isKey) {
187                         // This is an extra field for the unknown PK class.
188
// PK setter name is used to generate the line for ejbCreate
189
// to set the PK value in _JDOState.
190
setPKField = fieldInfo.setter;
191                     }
192                     continue;
193                 }
194
195                 if (!(pfe instanceof RelationshipElement)) {
196                     generateCMPGetSetBodies(fieldInfo);
197
198                 } else { // CMR
199
if (isUpdateable) {
200                         generateCMRGetSetBodies(fieldInfo, cmrcleanbodyBuf);
201
202                     } else {
203                         logger.log(Logger.WARNING, I18NHelper.getMessage(messages,
204                                 "CMG.CMRAccessNotAllowed", beanName, fieldInfo.name)); // NOI18N
205

206                         gbody = CMPROTemplateFormatter.accessNotAllowedTemplate;
207                         sbody = CMPROTemplateFormatter.updateNotAllowedTemplate;
208                     }
209                 }
210
211                 // Now generate getter and setter:
212
CMPTemplateFormatter.addGenericMethod(
213                     fieldInfo.getter, Modifier.PUBLIC, fieldInfo.type,
214                     CMP20TemplateFormatter.getBodyAsStrings(gbody),
215                     concreteImplWriter);
216
217                 oneParam[0] = fieldInfo.type;
218                 concreteImplWriter.addMethod(fieldInfo.setter, // name
219
Modifier.PUBLIC, // modifiers
220
CMP20TemplateFormatter.void_, // returnType
221
param0, // parameterNames
222
oneParam,// parameterTypes
223
null,// exceptions
224
CMP20TemplateFormatter.getBodyAsStrings(sbody), // body
225
null);// comments
226
}
227         }
228
229         // Now generate jdoCleanCollectionRef method
230
CMPTemplateFormatter.addGenericMethod(
231                CMP20TemplateFormatter.jdoCleanCollectionRef_,
232                CMP20TemplateFormatter.getBodyAsStrings(cmrcleanbodyBuf.toString()),
233                concreteImplWriter);
234     }
235
236     /** Generate bodies of getters and setters for CMP field
237      * @param fieldInfo the field information as FieldInfo instance.
238      */

239     private void generateCMPGetSetBodies(FieldInfo fieldInfo) {
240
241         // For read-only beans it will be the same. For updateable
242
// beans it will be generated per field type.
243
sbody = CMPROTemplateFormatter.updateNotAllowedTemplate;
244
245         // Add code to load non-DFG field if necessary.
246
loadNonDFGField(fieldInfo);
247
248         if( fieldInfo.requireCloneOnGetAndSet ) {
249             // CMP field should have copy-in, copy-out semantics
250
// via clone.
251
twoParams[0] = fieldInfo.getter;
252             twoParams[1] = fieldInfo.type;
253             gbody = CMP20TemplateFormatter.copygformatter.format(twoParams);
254
255             if (isUpdateable) {
256                 twoParams[0] = fieldInfo.setter;
257                 if (!fieldInfo.isKey) {
258                     sbody = CMP20TemplateFormatter.copysformatter.format(twoParams);
259                 } else {
260                     String JavaDoc[] params = new String JavaDoc[] {concreteImplName, fieldInfo.name};
261                     sbody = CMP20TemplateFormatter.assertpksformatter.format(params) +
262                         CMP20TemplateFormatter.pkcopysformatter.format(twoParams);
263                 }
264             }
265
266         } else if( fieldInfo.isByteArray ) {
267             // A byte[] CMP field should have copy-in, copy-out semantics
268
// via System.arraycopy.
269
oneParam[0] = fieldInfo.getter;
270             gbody = CMP20TemplateFormatter.arraygformatter.format(oneParam);
271
272             if (isUpdateable) {
273                 oneParam[0] = fieldInfo.setter;
274                 sbody = CMP20TemplateFormatter.arraysformatter.format(oneParam);
275             }
276         } else if( fieldInfo.isSerializable ) {
277             // A special case for a Serializable CMP field (but not byte[]) -
278
// it should be serialized to/from a byte[] in PC instance.
279

280             threeParams[0] = fieldInfo.getter;
281             threeParams[1] = fieldInfo.type;
282             threeParams[2] = concreteImplName;
283             gbody = CMP20TemplateFormatter.sfldgformatter.format(threeParams);
284
285             if (isUpdateable) {
286                 twoParams[0] = fieldInfo.setter;
287                 twoParams[1] = concreteImplName;
288                 sbody = CMP20TemplateFormatter.sfldsformatter.format(twoParams);
289             }
290         } else {
291             oneParam[0] = fieldInfo.getter;
292             gbody = CMP20TemplateFormatter.gformatter.format(oneParam);
293
294             if (isUpdateable) {
295                 oneParam[0] = fieldInfo.setter;
296                 if (!fieldInfo.isKey) {
297                     sbody = CMP20TemplateFormatter.sformatter.format(oneParam);
298
299                 } else {
300                     StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
301                     if (!fieldInfo.isPrimitive) {
302                         twoParams[0] = concreteImplName;
303                         twoParams[1] = fieldInfo.name;
304                         sb.append(
305                             CMP20TemplateFormatter.assertpksformatter.format(twoParams));
306                     }
307     
308                     sb.append(requireTrimOnSet(fieldInfo.type) ?
309                         CMP20TemplateFormatter.pkstringsformatter.format(oneParam) :
310                         CMP20TemplateFormatter.pksformatter.format(oneParam));
311
312                     sbody = sb.toString();
313                 }
314             }
315         }
316
317     }
318
319     /** Generate bodies of getters and setters for CMR field
320      * @param fieldInfo the field information as FieldInfo instance.
321      * @param cmrcleanbodyBuf the StringBuffer to append code for CMR cleanup
322      * if necessary.
323      */

324     private void generateCMRGetSetBodies(FieldInfo fieldInfo,
325             StringBuffer JavaDoc cmrcleanbodyBuf) throws IOException JavaDoc {
326
327         RelationshipElement rel = (RelationshipElement)fieldInfo.pfe;
328
329         String JavaDoc otherPC = model.getRelatedClass(rel);
330         boolean manySide = model.isCollection(fieldInfo.type);
331
332         if (logger.isLoggable(Logger.FINE)) {
333             RelationshipElement otherField = rel.getInverseRelationship(model);
334             String JavaDoc otherFieldName = ((otherField != null) ?
335                     nameMapper.getEjbFieldForPersistenceField(otherPC,
336                             otherField.getName()) :
337                     null);
338
339             logger.fine("manySide: " + manySide); // NOI18N
340
logger.fine("Field: " + otherFieldName); // NOI18N
341
}
342
343         String JavaDoc otherEJB = nameMapper.getEjbNameForPersistenceClass(otherPC);
344         String JavaDoc otherImpl = nameMapper.getConcreteBeanClassForEjbName(otherEJB);
345         MessageFormat JavaDoc mformat = null;
346
347         if (manySide) {
348             threeParams[0] = fieldInfo.getter;
349             threeParams[1] = fieldInfo.name;
350             threeParams[2] = otherImpl;
351             gbody = CMP20TemplateFormatter.cmrCgformatter.format(threeParams);
352
353             fourParams[0] = otherImpl;
354             fourParams[1] = fieldInfo.setter;
355             fourParams[2] = fieldInfo.getter;
356             fourParams[3] = fieldInfo.name;
357             sbody = CMP20TemplateFormatter.cmrCsformatter.format(fourParams);
358
359             mformat = CMP20TemplateFormatter.cmrcdCformatter;
360
361             twoParams[0] = fieldInfo.type;
362             twoParams[1] = fieldInfo.name;
363             CMP20TemplateFormatter.addPrivateField(
364                 CMP20TemplateFormatter.cmrvformatter.format(twoParams),
365                 0, concreteImplWriter);
366
367             oneParam[0] = fieldInfo.name;
368             cmrcleanbodyBuf.append(CMP20TemplateFormatter.cleancmrformatter.format(oneParam));
369
370         } else { // 1 side
371
fourParams[0] = otherPC;
372             fourParams[1] = fieldInfo.getter;
373             fourParams[2] = fieldInfo.type;
374             fourParams[3] = otherImpl;
375             gbody = CMP20TemplateFormatter.cmrgformatter.format(fourParams);
376
377             threeParams[0] = otherPC;
378             threeParams[1] = otherImpl;
379             threeParams[2] = fieldInfo.setter;
380             sbody = CMP20TemplateFormatter.cmrsformatter.format(threeParams);
381
382             mformat = CMP20TemplateFormatter.cmrcdformatter;
383
384         }
385
386         if (rel.getDeleteAction() == RelationshipElement.CASCADE_ACTION) {
387             twoParams[0] = fieldInfo.getter;
388             twoParams[1] = otherImpl;
389             cascadeDelete.append(mformat.format(twoParams));
390             try {
391                 // Reset DeleteAction to NONE to suppress it in PM.deletePersistent().
392
rel.setDeleteAction(RelationshipElement.NONE_ACTION);
393             } catch (ModelException me) {
394                 logger.log(Logger.SEVERE, I18NHelper.getMessage(messages,
395                         "CMG.ModelExceptionOnDeleteAction", me)); //NOI18N
396
}
397         }
398
399     }
400
401     /** Validate EJBQL for ejbFind and ejbSelect methods by calling compilation.
402      * The method stores compilation results in the {@link #jdoqlElementsMap} map.
403      * This method is called only for CMP 2.x beans as there is no validation of
404      * CMP 1.1 queries at the deployment time.
405      * @param methodHelper the AbstractMethodHelper instance that contains
406      * all categorized methods and some other convenience methods for this bean.
407      * @return a Collection of found exceptions.
408      */

409     private Collection validateEJBQL(AbstractMethodHelper methodHelper) {
410         Collection rc = new ArrayList();
411         jdoqlElementsMap = new HashMap();
412
413         List methods = new ArrayList(methodHelper.getFinders());
414         methods.addAll(methodHelper.getSelectors());
415         for (int i = 0; i < methods.size(); i++) {
416             Method JavaDoc m = (Method JavaDoc)methods.get(i);
417             String JavaDoc mname = m.getName();
418             if (mname.equals(CMP20TemplateFormatter.findByPrimaryKey_)) {
419                 // No EJBQL is defined for findByPrimaryKey.
420
continue;
421             }
422
423             try {
424                 // EJBQLC needs to know if we are processing a finder or a selector.
425
jdoqlElementsMap.put(m,
426                         ejbqlc.compile(methodHelper.getQueryString(m), m,
427                                methodHelper.getQueryReturnType(m),
428                                mname.startsWith(CMP20TemplateFormatter.find_),
429                                beanName));
430             } catch (EJBQLException e) {
431                 rc.add(e);
432             }
433         }
434
435         return rc;
436     }
437
438     /** Returns JDOQLElements instance for this finder method.
439      * @param m the finder method as a java.lang.reflect.Method
440      * @param methodHelper the AbstractMethodHelper instance that contains
441      * all categorized methods and some other convenience methods for this bean.
442      * @return JDOQLElements instance.
443      */

444     JDOQLElements getJDOQLElements(Method JavaDoc m,
445             AbstractMethodHelper methodHelper) throws IOException JavaDoc{
446         // Call the EJBQL compiler if there is no known result
447
// from validate call.
448
JDOQLElements rs = (JDOQLElements)jdoqlElementsMap.get(m);
449         if (rs == null) {
450             if (logger.isLoggable(Logger.FINE)) {
451                 logger.fine("JDOQLElements NOT FOUND for: " + m.getName());
452             }
453
454             rs = ejbqlc.compile(methodHelper.getQueryString(m), m,
455                     methodHelper.getQueryReturnType(m), true, beanName);
456         }
457
458         return rs;
459     }
460
461     /** Adds ejbSelectBy methods.
462      */

463     private void generateSelectors(AbstractMethodHelper methodHelper) throws IOException JavaDoc{
464         List selectors = methodHelper.getSelectors();
465         boolean debug = logger.isLoggable(Logger.FINE);
466         if (debug) {
467             logger.fine("Selectors: " + selectors.size()); // NOI18N
468
}
469
470         for (int i = 0; i < selectors.size(); i++) {
471             Method JavaDoc m = (Method JavaDoc)selectors.get(i);
472             String JavaDoc mname = m.getName();
473
474             if (debug) {
475                 logger.fine("Selector: " + mname); // NOI18N
476
}
477
478             JDOQLElements rs = (JDOQLElements)jdoqlElementsMap.get(m);
479             if (rs == null) {
480                 if (debug) {
481                     logger.fine("JDOQLElements NOT FOUND for: " + mname);
482                 }
483
484                 // calling EJBQL compiler
485
rs = ejbqlc.compile(methodHelper.getQueryString(m), m,
486                     methodHelper.getQueryReturnType(m), false, beanName);
487             }
488
489             String JavaDoc returnType = m.getReturnType().getName();
490             CMP20TemplateFormatter.addGenericMethod(
491                 m, mname, returnType,
492                 generateSelectorMethodBody(methodHelper, rs, mname, m, returnType, i),
493                 concreteImplWriter);
494         }
495     }
496
497     /** Returns method body for EJBCreate method.
498      * @param createName the actual name of the method as String.
499      * @param exc a String[] of decleared exceptions for this method.
500      * @param parametersList the list of method parameters as String.
501      * @param parametersListWithSeparator the list of concatenated method
502      * parameters to be passed to another method as String.
503      * @return method body as String.
504      */

505     String JavaDoc getEJBCreateMethodBody(String JavaDoc createName,
506             String JavaDoc[] exc, String JavaDoc parametersList,
507             String JavaDoc parametersListWithSeparator) {
508
509         // ejbCreate in the superclass will have the same suffix, so we need
510
// to pass the actual name to the formatter - see 'createName' parameter.
511
if (!containsException(exc, CMP20TemplateFormatter.CreateException_)) {
512             throw new JDOUserException(I18NHelper.getMessage(messages,
513                     "EXC_NoCreateException", createName, abstractBean)); // NOI18N
514
}
515
516         // For read-only beans it will be the same. For updateable
517
// beans it will be generated as required.
518
String JavaDoc body = CMPROTemplateFormatter.accessNotAllowedTemplate;
519         if (isUpdateable) {
520             sixParams[0] = pcname;
521             sixParams[1] = createName;
522             sixParams[2] = parametersList;
523             sixParams[4] = concreteImplName;
524             sixParams[5] = parametersListWithSeparator;
525
526             if (pkClass.equals(Object JavaDoc.class.getName())) {
527                 sixParams[3] = setPKField;
528
529                 body = CMP20TemplateFormatter.cunpkformatter.format(sixParams);
530             } else {
531                 sixParams[3] = pkClass;
532                 body = CMP20TemplateFormatter.cformatter.format(sixParams);
533             }
534         }
535
536         return body;
537     }
538
539     /** Returns method body for EJBPostCreate method.
540      * @param postCreateName the actual name of the method as String.
541      * @param parametersList the list of method parameters as String.
542      * @param parametersListWithSeparator the list of concatenated method
543      * parameters to be passed to another method as String.
544      * @return method body as String.
545      */

546     String JavaDoc getEJBPostCreateMethodBody(String JavaDoc postCreateName,
547             String JavaDoc parametersList, String JavaDoc parametersListWithSeparator) {
548
549         // For read-only beans it will be the same. For updateable
550
// beans it will be generated as required.
551
String JavaDoc body = CMPTemplateFormatter.none_;
552
553         if (isUpdateable) {
554             twoParams[0] = postCreateName;
555             twoParams[1] = parametersList;
556
557             body = CMP20TemplateFormatter.postcformatter.format(twoParams);
558         }
559
560         return body;
561     }
562
563     /** Returns method body for EJBRemove method.
564      * @return method body as String.
565      */

566     String JavaDoc getEJBRemoveMethodBody() {
567         // For read-only beans it will throw an exception. For updateable
568
// beans it will be generated as required.
569
String JavaDoc body = CMPROTemplateFormatter.updateNotAllowedTemplate;
570         if (isUpdateable) {
571             // CMP2.0 might have cascade-delete requirement.
572
if (cascadeDelete.length() > 0) {
573                 oneParam[0] = CMP20TemplateFormatter.startCascadeDeleteTemplate +
574                         cascadeDelete.append(
575                         CMP20TemplateFormatter.endCascadeDeleteTemplate).
576                         toString();
577             } else {
578                 oneParam[0] = CMP20TemplateFormatter.none_;
579             }
580
581             body = CMP20TemplateFormatter.rmformatter.format(oneParam);
582          }
583
584         return body;
585     }
586
587     /** Adds other known required methods identified by properties that do
588      * not need formatting but differ between CMP types.
589      * CMP20TemplateFormatter.otherPublicMethods_ differ between CMP types.
590      */

591     void generateKnownMethods(AbstractMethodHelper methodHelper)
592                        throws IOException JavaDoc {
593
594         super.generateKnownMethods(methodHelper);
595
596         String JavaDoc[] exc = null;
597         String JavaDoc[] st = CMP20TemplateFormatter.otherPublicMethodsArray;
598         for (int i = 0; i < st.length; i++) {
599             String JavaDoc mname = st[i];
600             exc = getExceptionList(methodHelper, mname);
601
602             String JavaDoc body = CMPROTemplateFormatter.updateNotAllowedTemplate;
603             // Only ejbLoad from this list doesn't differ for read-only beans.
604
if (isUpdateable || mname.equals(CMPTemplateFormatter.ejbLoad_)) {
605                 body = CMP20TemplateFormatter.helpers.getProperty(mname);
606             } else if (mname.equals(CMPTemplateFormatter.jdoCleanAllRefs_)) {
607                 body = CMPROTemplateFormatter.jdoCleanAllRefsTemplate;
608             }
609
610             concreteImplWriter.addMethod(mname, // name
611
Modifier.PUBLIC, // modifiers
612
CMP20TemplateFormatter.void_, // returnType
613
null, // parameterNames
614
null,// parameterTypes
615
exc,// exceptions
616
CMP20TemplateFormatter.getBodyAsStrings(body), // body
617
null);// comments
618
}
619
620     }
621
622     /**
623      * Generates helper methods for the helper class.
624      */

625     void generateHelperClassMethods() throws IOException JavaDoc {
626
627         super.generateHelperClassMethods();
628         // Add Helper.assertInstanceOfLocalInterfaceImpl() method for cmp2.0 only.
629
oneParam[0] = CMP20TemplateFormatter.assertInstanceOfLocalInterfaceImplTemplate;
630
631         jdoHelperWriter.addMethod(CMP20TemplateFormatter.assertInstanceOfLocalInterfaceImpl_, // name
632
Modifier.PUBLIC, // modifiers
633
CMP20TemplateFormatter.void_, // returnType
634
param0, // parameterNames
635
objectType,// parameterTypes
636
null,// exceptions
637
oneParam, // body
638
null);// comments
639
}
640
641     /**
642      * Generates conversion methods from PC to EJBObject and back
643      * to the helper class.
644      */

645     void generateConversions() throws IOException JavaDoc {
646
647         super.generateConversions();
648
649         // For EJBLocalObject.
650
if (hasLocalInterface == false) {
651             String JavaDoc[] pcParams = new String JavaDoc[] {CMP20TemplateFormatter.pc_,
652                     CMP20TemplateFormatter.jdoPersistenceManager_};
653             String JavaDoc[] pcParamTypes = new String JavaDoc[] {CMP20TemplateFormatter.Object_,
654                     CMP20TemplateFormatter.jdoPersistenceManagerClass_};
655
656             String JavaDoc[] body = CMP20TemplateFormatter.getBodyAsStrings(
657                     CMP20TemplateFormatter.returnNull_);
658
659             jdoHelperWriter.addMethod(CMP20TemplateFormatter.convertPCToEJBLocalObject_, // name
660
Modifier.PUBLIC, // modifiers
661
CMP20TemplateFormatter.ejbLocalObject_, // returnType
662
pcParams, // parameterNames
663
pcParamTypes,// parameterTypes
664
null,// exceptions
665
body, // body
666
null);// comments
667

668             String JavaDoc[] pcParamsX = new String JavaDoc[] {CMP20TemplateFormatter.pc_,
669                     CMP20TemplateFormatter.jdoPersistenceManager_,
670                     CMP20TemplateFormatter.context_};
671             String JavaDoc[] pcParamTypesX = new String JavaDoc[] {CMP20TemplateFormatter.Object_,
672                     CMP20TemplateFormatter.jdoPersistenceManagerClass_,
673                     CMP20TemplateFormatter.ejbContext_};
674             jdoHelperWriter.addMethod(CMP20TemplateFormatter.convertPCToEJBLocalObject_, // name
675
Modifier.PUBLIC, // modifiers
676
CMP20TemplateFormatter.ejbLocalObject_, // returnType
677
pcParamsX, // parameterNames
678
pcParamTypesX,// parameterTypes
679
null,// exceptions
680
body, // body
681
null);// comments
682

683
684             twoParams[0] = CMP20TemplateFormatter.ejbLocalObject_;
685             twoParams[1] = CMP20TemplateFormatter.jdoPersistenceManagerClass_;
686             jdoHelperWriter.addMethod(CMP20TemplateFormatter.convertEJBLocalObjectToPC_, // name
687
Modifier.PUBLIC, // modifiers
688
CMP20TemplateFormatter.Object_, // returnType
689
param0PM, // parameterNames
690
twoParams,// parameterTypes
691
null,// exceptions
692
body, // body
693
null);// comments
694
}
695     }
696
697     /**
698      * Generates the body of the Entity-Bean selector methods.
699      * This is the special result set handling.
700      * @param methodHelper the AbstractMethodHelper instance that contains
701      * all categorized methods and some other convenience methods for this bean
702      * @param jdoqlElements the result of the EJBQL-Compiler
703      * @param mname name of the selector method in
704      * the concrete entity bean implementation
705      * @param m selector method object
706      * @param index index of selector method in selectors list
707      * @param returnType the returntype of the selectormethod
708      * @return the generated body
709      * @exception IOException
710      */

711     private String JavaDoc generateSelectorMethodBody(AbstractMethodHelper methodHelper,
712                                               JDOQLElements jdoqlElements,
713                                               String JavaDoc mname,
714                                               Method JavaDoc m,
715                                               String JavaDoc returnType,
716                                               int index) throws IOException JavaDoc {
717
718         StringBuffer JavaDoc body = new StringBuffer JavaDoc();
719
720         // add preSelect callback
721
oneParam[0] = concreteImplName;
722         body.append(CMP20TemplateFormatter.preselectformatter.format(oneParam));
723
724         // common body for finder/selectors
725
body.append(generateFinderSelectorCommonBody(methodHelper,
726                                                      jdoqlElements,
727                                                      mname,
728                                                      m,
729                                                      returnType,
730                                                      index));
731
732         // body with resulthandling depending on the type of the selector
733
// (single or multivalue)
734
if (isSingleObjectSelector(m)) {
735             body.append(generateResultHandlingForSingleSelector(
736                 jdoqlElements, mname, m, methodHelper, returnType));
737         } else {
738             body.append(generateResultHandlingForMultiSelector(
739                 jdoqlElements, m, methodHelper));
740         }
741
742         return body.toString();
743     }
744
745
746     /**
747      * Generates the result handling for a multi-value selector method.
748      * The generated code converts the JDO query result set into the appropriate
749      * selector result.
750      * @param jdoqlElements the result of the JDOQL compiler
751      * @param m selector method object
752      * @param methodHelper the AbstractMethodHelper instance that contains
753      * all categorized methods and some other convenience methods for this bean
754      * @return the generated result set handling
755      */

756     private String JavaDoc generateResultHandlingForMultiSelector(
757                                                     JDOQLElements jdoqlElements,
758                                                     Method JavaDoc m,
759                                                     AbstractMethodHelper methodHelper) {
760
761         boolean convertToSet = false;
762         String JavaDoc body = null;
763         MessageFormat JavaDoc mformat = null;
764         // getting the catch-clause body from the properties
765
oneParam[0] = m.getName();
766
767         // depending of the kind of returntype a different convertermethodcall
768
// is generated
769
if (isSelectorReturningSet(m)) convertToSet = true;
770
771         int queryReturnType = methodHelper.getQueryReturnType(m);
772         if ((queryReturnType == AbstractMethodHelper.NO_RETURN) &&
773             jdoqlElements.isPCResult()) {
774             // Use LOCAL_RETURN as default,
775
// if there is no result-type-mapping specified and
776
// the JDOQL query returns a collection of pc instances
777
queryReturnType = AbstractMethodHelper.LOCAL_RETURN;
778         }
779
780         switch (queryReturnType) {
781         case (AbstractMethodHelper.LOCAL_RETURN):
782             mformat = CMP20TemplateFormatter.multiselectorconvformatter;
783             threeParams[0] =
784                 getConcreteBeanForPCClass(jdoqlElements.getResultType());
785             threeParams[1] = convertToSet ?
786                 CMP20TemplateFormatter.convertCollectionPCToEJBLocalObjectSet_ :
787                 CMP20TemplateFormatter.convertCollectionPCToEJBLocalObject_;
788             threeParams[2] = CMP20TemplateFormatter.catchClauseTemplate;
789             body = mformat.format(threeParams);
790             break;
791         case (AbstractMethodHelper.REMOTE_RETURN):
792             mformat = CMP20TemplateFormatter.multiselectorconvformatter;
793             threeParams[0] =
794                 getConcreteBeanForPCClass(jdoqlElements.getResultType());
795             threeParams[1] = convertToSet ?
796                 CMP20TemplateFormatter.convertCollectionPCToEJBObjectSet_ :
797                 CMP20TemplateFormatter.convertCollectionPCToEJBObject_;
798             threeParams[2] = CMP20TemplateFormatter.catchClauseTemplate;
799             body = mformat.format(threeParams);
800             break;
801         case (AbstractMethodHelper.NO_RETURN):
802         default:
803             mformat = convertToSet ?
804                 CMP20TemplateFormatter.multiselectorsetformatter :
805                 CMP20TemplateFormatter.multiselectorformatter;
806             oneParam[0] = CMP20TemplateFormatter.catchClauseTemplate;
807             body = mformat.format(oneParam);
808             break;
809         }
810
811         return body;
812     }
813
814     /**
815      * Generates the result handling for a single-object selector method.
816      * The generated code converts the JDO query result set into the appropriate
817      * selector result.
818      * @param jdoqlElements the result of the JDOQL compiler
819      * @param mname name of the selector method in
820      * the concrete entity bean implementation
821      * @param m selector method object
822      * @param methodHelper the AbstractMethodHelper instance that contains
823      * all categorized methods and some other convenience methods for this bean
824      * @param returnType the returntype of the selectormethod
825      * @return the generated result set handling
826      */

827     private String JavaDoc generateResultHandlingForSingleSelector(
828                                                     JDOQLElements jdoqlElements,
829                                                     String JavaDoc mname,
830                                                     Method JavaDoc m,
831                                                     AbstractMethodHelper methodHelper,
832                                                     String JavaDoc returnType) {
833
834         StringBuffer JavaDoc body = new StringBuffer JavaDoc();
835         MessageFormat JavaDoc mformat = null;
836         String JavaDoc jdoResultType = jdoqlElements.getResultType();
837         String JavaDoc ejbName = null;
838         // generated code that tests the cardinality of the JDO query
839
// a JDOQL aggregate query returns a single object => no check needed
840
if (!jdoqlElements.isAggregate()) {
841             mformat = CMP20TemplateFormatter.singleselectorformatter;
842             oneParam[0] = mname;
843             body.append(mformat.format(oneParam));
844         }
845
846         // getting the catch-clause body from the properties
847
oneParam[0] = CMP20TemplateFormatter.none_;
848
849         int queryReturnType = methodHelper.getQueryReturnType(m);
850         if ((queryReturnType == AbstractMethodHelper.NO_RETURN) &&
851             jdoqlElements.isPCResult()) {
852             // Use LOCAL_RETURN as default,
853
// if there is no result-type-mapping specified and
854
// the JDOQL query returns a collection of pc instances
855
queryReturnType = AbstractMethodHelper.LOCAL_RETURN;
856         }
857
858         // generate different converter method call depending on return type
859
switch (queryReturnType) {
860         case (AbstractMethodHelper.LOCAL_RETURN):
861             ejbName = nameMapper.getEjbNameForPersistenceClass(jdoResultType);
862             mformat = CMP20TemplateFormatter.singleselectorreturnconvformatter;
863             fourParams[0] = nameMapper.getLocalInterfaceForEjbName(ejbName);
864             fourParams[1] = nameMapper.getConcreteBeanClassForEjbName(ejbName);
865             fourParams[2] = CMP20TemplateFormatter.convertPCToEJBLocalObject_;
866             fourParams[3] = CMP20TemplateFormatter.catchClauseTemplate;
867             body.append(mformat.format(fourParams));
868             break;
869         case (AbstractMethodHelper.REMOTE_RETURN):
870             ejbName = nameMapper.getEjbNameForPersistenceClass(jdoResultType);
871             mformat = CMP20TemplateFormatter.singleselectorreturnconvformatter;
872             fourParams[0] = nameMapper.getRemoteInterfaceForEjbName(ejbName);
873             fourParams[1] = nameMapper.getConcreteBeanClassForEjbName(ejbName);
874             fourParams[2] = CMP20TemplateFormatter.convertPCToEJBObject_;
875             fourParams[3] = CMP20TemplateFormatter.catchClauseTemplate;
876             body.append(mformat.format(fourParams));
877             break;
878         case (AbstractMethodHelper.NO_RETURN):
879         default:
880             Class JavaDoc returnTypeClass = m.getReturnType();
881             // tests if it is aggregate function and proceed it first
882
if (jdoqlElements.isAggregate()) {
883                 if (returnTypeClass.isPrimitive()) {
884                     mformat = CMP20TemplateFormatter.aggregateselectorprimitivereturnformatter;
885                     fourParams[0] = mname;
886                     fourParams[1] = jdoResultType;
887                     fourParams[2] = CMP20TemplateFormatter.dot_ +
888                         CMP20TemplateFormatter.getUnwrapMethodName(returnTypeClass);
889                     fourParams[3] = CMP20TemplateFormatter.catchClauseTemplate;
890                     body.append(mformat.format(fourParams));
891                 } else if (returnTypeClass.getName().equals(jdoResultType)) {
892                     mformat = CMP20TemplateFormatter.aggregateselectorreturnformatter;
893                     twoParams[0] = jdoResultType;
894                     twoParams[1] = CMP20TemplateFormatter.catchClauseTemplate;
895                     body.append(mformat.format(twoParams));
896                 } else if (returnTypeClass.isAssignableFrom(
897                     java.math.BigDecimal JavaDoc.class)) {
898                     mformat = CMP20TemplateFormatter.aggregateselectorreturnbigdecimalconvformatter;
899                     twoParams[0] = jdoResultType;
900                     twoParams[1] = CMP20TemplateFormatter.catchClauseTemplate;
901                     body.append(mformat.format(twoParams));
902                 } else if (returnTypeClass.isAssignableFrom(
903                     java.math.BigInteger JavaDoc.class)) {
904                     mformat = CMP20TemplateFormatter.aggregateselectorreturnbigintegerconvformatter;
905                     twoParams[0] = jdoResultType;
906                     twoParams[1] = CMP20TemplateFormatter.catchClauseTemplate;
907                     body.append(mformat.format(twoParams));
908
909                 } else {
910                     mformat = CMP20TemplateFormatter.aggregateselectorreturnconvformatter;
911                     fourParams[0] = returnType;
912                     fourParams[1] = jdoResultType;
913                     fourParams[2] = CMP20TemplateFormatter.dot_ +
914                         CMP20TemplateFormatter.getUnwrapMethodName(
915                         CMP20TemplateFormatter.getPrimitiveClass(
916                         CMP20TemplateFormatter.getPrimitiveName(returnTypeClass)));
917                     fourParams[3] = CMP20TemplateFormatter.catchClauseTemplate;
918                     body.append(mformat.format(fourParams));
919                 }
920             } else {
921                 // tests if the returntype is a primitive java type
922
// if so, the cast parameter is the wrapperclass of the
923
// primitive type and the getterMethod for the primitive
924
// value of the wrapper class is added.
925
// This is necessary because the JDOQuery returns collections
926
// of objects only, but the selector returns a primitive type.
927
mformat = CMP20TemplateFormatter.singleselectorreturnformatter;
928                 if (returnTypeClass.isPrimitive()) {
929                     threeParams[0] = CMP20TemplateFormatter.getWrapperName(returnType);
930                     threeParams[1] = CMP20TemplateFormatter.dot_ +
931                        CMP20TemplateFormatter.getUnwrapMethodName(returnTypeClass);
932                     threeParams[2] = CMP20TemplateFormatter.catchClauseTemplate;
933                 } else {
934                     threeParams[0] = returnType;
935                     threeParams[1] = CMP20TemplateFormatter.none_;
936                     threeParams[2] = CMP20TemplateFormatter.catchClauseTemplate;
937                 }
938                 body.append(mformat.format(threeParams));
939             }
940
941             break;
942         }
943
944         return body.toString();
945     }
946
947     /**
948      * Generates code that check the finder/selector parameters for the
949      * Query.execute call (if necessary).
950      * @param m Method instance of the specific finder/selector method
951      * @param parameterEjbNames array of ejb names
952      * @return the codefragment for the checking local/remote parameters
953      * for method if EJB name is known from ejbql.
954      */

955     String JavaDoc generateFinderSelectorParamCheck(Method JavaDoc m,
956             String JavaDoc[] parameterEjbNames) {
957         StringBuffer JavaDoc checkBody = new StringBuffer JavaDoc();
958
959         Class JavaDoc[] paramTypes = m.getParameterTypes();
960         int paramLength = paramTypes.length;
961         String JavaDoc paramClassName = null;
962         for (int i = 0; i < paramLength; i++) {
963             if (parameterEjbNames[i] != null) {
964                 paramClassName = paramTypes[i].getName();
965                 String JavaDoc concreteImplName =
966                     nameMapper.getConcreteBeanClassForEjbName(
967                     parameterEjbNames[i]);
968                 twoParams[0] = concreteImplName;
969                 twoParams[1] = CMP20TemplateFormatter.param_ + i;
970
971                 if (nameMapper.isLocalInterface(paramClassName)) {
972                     checkBody.append(CMP20TemplateFormatter.finderselectorchecklocalformatter.format(twoParams));
973                 } else { // Remote
974
checkBody.append(CMP20TemplateFormatter.finderselectorcheckremoteformatter.format(twoParams));
975                 }
976             }
977         }
978
979         return checkBody.toString();
980     }
981
982    /**
983      * Checks if the finder returns an Enumeration. Returns <code>false</code>
984      * for CMP2.0.
985      * @param finder Methodobject of the finder
986      * @return <code>true</code> if the finder returns a Enumeration
987      */

988     boolean isFinderReturningEnumeration(Method JavaDoc finder) {
989         return false;
990     }
991
992    /**
993      * Checks if the selector method is a single-object or multi-object selector.
994      * @param finder Method object of the finder
995      * @return <code>true</code> if it is a single-object-value selector
996      */

997     private boolean isSingleObjectSelector(Method JavaDoc finder) {
998         return (!(finder.getReturnType().equals(java.util.Collection JavaDoc.class) ||
999                   finder.getReturnType().equals(java.util.Set JavaDoc.class)));
1000    }
1001
1002   /**
1003     * Checks if the a selector returns a Set (for CMP2.0)
1004     * @param selector Methodobject of the selector
1005     * @return <code>true</code> if the selector returns a Set
1006     */

1007    private boolean isSelectorReturningSet(Method JavaDoc selector) {
1008        return (selector.getReturnType().equals(java.util.Set JavaDoc.class));
1009    }
1010
1011    /**
1012     * Returns the signatures of the classes and properties which are
1013     * involved in the codegen.
1014     * @return The signatures as a string.
1015     */

1016    String JavaDoc getSignaturesOfGeneratorClasses()
1017    {
1018        StringBuffer JavaDoc signatures = new StringBuffer JavaDoc().
1019
1020            // adding signature of JDOConcreteBeanGenerator
1021
append(super.getSignaturesOfGeneratorClasses()).
1022            append(CMPTemplateFormatter.signatureDelimiter_).
1023
1024            // adding signature of JDOConcreteBean20Generator
1025
append(JDOConcreteBean20Generator.SIGNATURE).
1026            append(CMPTemplateFormatter.signatureDelimiter_).
1027
1028            // adding signature of CMP20Templates.properties
1029
append(CMP20TemplateFormatter.signature2_0Template).
1030            append(CMPTemplateFormatter.signatureDelimiter_).
1031
1032            // adding signature of EJBQLC
1033
append(EJBQLC.SIGNATURE);
1034
1035        return signatures.toString();
1036    }
1037
1038}
1039
1040
Popular Tags