KickJava   Java API By Example, From Geeks To Geeks.

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


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  * JDOConcreteBeanGenerator.java
28  *
29  * Created on November 20, 2001
30  */

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

62 abstract class JDOConcreteBeanGenerator {
63
64     static final Logger logger = LogHelperEJBCompiler.getLogger();
65
66     // used to transform b/w various ejb names and pc class names
67
NameMapper nameMapper = null;
68
69     Model model = null; // used to look up various metadata
70

71     String JavaDoc beanName = null;
72     String JavaDoc helperName = null;
73     String JavaDoc concreteImplName = null;
74     String JavaDoc abstractBean = null;
75     String JavaDoc pkClass = null;
76     String JavaDoc pcname = null;
77     boolean hasLocalInterface;
78     boolean hasRemoteInterface;
79     boolean isUpdateable;
80
81     String JavaDoc setPKField = null;
82
83     // Name of the PC or PK Class as a single String parameter.
84
String JavaDoc[] pcnameParam = new String JavaDoc[1];
85     String JavaDoc[] pkClassParam = new String JavaDoc[1];
86
87     static String JavaDoc[] objectType = new String JavaDoc[]{CMPTemplateFormatter.Object_};
88     static String JavaDoc[] param0 = new String JavaDoc[]{CMPTemplateFormatter.param0_};
89     static String JavaDoc[] param0PM = new String JavaDoc[] {CMPTemplateFormatter.param0_,
90                     CMPTemplateFormatter.jdoPersistenceManager_};
91
92     // Generic parameters
93
String JavaDoc[] oneParam = new String JavaDoc[1];
94     String JavaDoc[] twoParams = new String JavaDoc[2];
95     String JavaDoc[] threeParams = new String JavaDoc[3];
96     String JavaDoc[] fourParams = new String JavaDoc[4];
97     String JavaDoc[] fiveParams = new String JavaDoc[5];
98     String JavaDoc[] sixParams = new String JavaDoc[6];
99
100     String JavaDoc[] queryParams = new String JavaDoc[10];
101
102     // StringBuffer for loading nonDFG fields into read-only beans
103
StringBuffer JavaDoc loadNonDFGBody = null;
104
105     ClassLoader JavaDoc loader;
106
107     // Writer for the concrete bean.
108
JavaClassWriter concreteImplWriter;
109
110     // Writer for the static _JDOHelper class.
111
JavaClassWriter jdoHelperWriter;
112
113     /**
114      * I18N message handler
115      */

116     final static ResourceBundle messages = I18NHelper.loadBundle(
117         JDOConcreteBeanGenerator.class);
118
119     /**
120      * Signature of the input files.
121      */

122     String JavaDoc inputFilesSignature;
123
124     /**
125      * Signature of the generator classes for the codegen.
126      */

127     String JavaDoc generatorClassesSignature;
128
129     /**
130      * Signature with CVS keyword substitution for identifying the generated code
131      */

132     static final String JavaDoc SIGNATURE = "$RCSfile: JDOConcreteBeanGenerator.java,v $ $Revision: 1.2 $"; //NOI18N
133

134     JDOConcreteBeanGenerator(ClassLoader JavaDoc loader,
135                              Model model,
136                              NameMapper nameMapper)
137                              throws IOException JavaDoc {
138         this.loader = loader;
139         this.model = model;
140         this.nameMapper = nameMapper;
141
142         CMPTemplateFormatter.initHelpers();
143         CMPROTemplateFormatter.initHelpers();
144     }
145     
146     void setUpdateable(boolean updateable) {
147         isUpdateable = updateable;
148     }
149
150     /**
151      * Validate this CMP bean. To be overridden in subclass if necessary.
152      * No generic validation is done at this time.
153      * @param methodHelper the AbstractMethodHelper instance that contains
154      * all categorized methods and some other convenience methods for this bean.
155      * @param beanName the ejb name for this bean.
156      * @return a Collection of Exception instances with a separate instance for
157      * each failed validation. This implementation returns an empty collection
158      * because generic validation always succeeds.
159      */

160     Collection validate(AbstractMethodHelper methodHelper, String JavaDoc beanName) {
161         return new ArrayList();
162     }
163
164     /**
165      * Generate all required classes for this CMP bean.
166      * @param methodHelper the AbstractMethodHelper instance that contains
167      * all categorized methods and some other convenience methods for this bean.
168      * @param beanName the ejb-name of this bean.
169      * @param srcout that path to the generated source files.
170      * @param classout that path to the compiled class files.
171      * @return a Collection of generated source files.
172      */

173     Collection generate(AbstractMethodHelper methodHelper, String JavaDoc beanName,
174                        File JavaDoc srcout, File JavaDoc classout)
175                        throws IOException JavaDoc {
176
177         Collection files = new ArrayList();
178
179         this.beanName = beanName;
180         this.abstractBean = nameMapper.getAbstractBeanClassForEjbName(beanName);
181
182         String JavaDoc pkgName = CMPTemplateFormatter.getPackageName(abstractBean);
183         concreteImplName = nameMapper.getConcreteBeanClassForEjbName(beanName);
184         String JavaDoc shortCmpName = CMPTemplateFormatter.getShortClassName(concreteImplName);
185
186         pcname = nameMapper.getPersistenceClassForEjbName(beanName);
187         pcnameParam[0] = pcname;
188
189         PersistenceClassElement pcClassElement =
190             model.getPersistenceClass(pcname);
191
192         pkClass = nameMapper.getKeyClassForEjbName(beanName).
193             replace('$', '.');
194         pkClassParam[0] = pkClass;
195
196         PersistenceFieldElement[] allFields = pcClassElement.getFields();
197
198         String JavaDoc prefix = srcout.getPath() + File.separator +
199             concreteImplName.replace('.', File.separatorChar);
200     
201         String JavaDoc cmp_file_name = prefix + CMPTemplateFormatter.javaExtension_;
202     
203         String JavaDoc hlp_file_name = prefix + CMPTemplateFormatter.Helper_ +
204             CMPTemplateFormatter.javaExtension_;
205
206         hasLocalInterface =
207             (nameMapper.getLocalInterfaceForEjbName(beanName) != null);
208         hasRemoteInterface =
209             (nameMapper.getRemoteInterfaceForEjbName(beanName) != null);
210
211         if (logger.isLoggable(Logger.FINE)) {
212             logger.fine("allFields: " + // NOI18N
213
((allFields != null) ? allFields.length : 0));
214             logger.fine("cmp_file_name: " + cmp_file_name); // NOI18N
215
logger.fine("hlp_file_name: " + hlp_file_name); // NOI18N
216
logger.fine("cmp_name: " + concreteImplName); // NOI18N
217
logger.fine("pkClass: " + pkClass); // NOI18N
218
logger.fine("PCname: " + pcname); // NOI18N
219
}
220
221         File JavaDoc cmp_file = new File JavaDoc(cmp_file_name);
222         JavaFileWriter concreteImplFileWriter = new IOJavaFileWriter(cmp_file);
223         concreteImplWriter = new IOJavaClassWriter();
224
225         File JavaDoc hlp_file = new File JavaDoc(hlp_file_name);
226         JavaFileWriter helperFileWriter = new IOJavaFileWriter(hlp_file);
227         jdoHelperWriter = new IOJavaClassWriter();
228
229         // Add package statement to both classes.
230
if (pkgName != null && pkgName.length() > 0) {
231             concreteImplFileWriter.setPackage(pkgName, null);
232             helperFileWriter.setPackage(pkgName, null);
233         }
234
235         // Add imports statements to both classes.
236
addImportStatements(concreteImplFileWriter, helperFileWriter);
237
238         // Generate class name for the concrete impl.
239
oneParam[0] = CMPTemplateFormatter.cmpImplCommentsTemplate;
240         concreteImplWriter.setClassDeclaration(Modifier.PUBLIC,
241             shortCmpName, oneParam);
242
243         // Add interfaces to the class declarations.
244
addInterfaces();
245
246         concreteImplWriter.setSuperclass(abstractBean);
247
248         // Add no-arg constructor.
249
concreteImplWriter.addConstructor(shortCmpName,
250             Modifier.PUBLIC, null, null, null,
251             CMPTemplateFormatter.super_, null);
252
253         // Add helper class.
254
helperName = shortCmpName + CMPTemplateFormatter.Helper_;
255
256         oneParam[0] = shortCmpName;
257         jdoHelperWriter.setClassDeclaration(Modifier.PUBLIC,
258             helperName, CMPTemplateFormatter.getBodyAsStrings(
259                 CMPTemplateFormatter.hcomformatter.format(oneParam)));
260
261         setHelperSuperclass();
262
263         // Print internal variables.
264
generateFields();
265
266         // Generate type specific methods.
267
generateTypeSpecificMethods(allFields, methodHelper);
268
269         // Add finders for all types and selectors for CMP2.0 only.
270
generateFinders(methodHelper);
271
272         // Add ejbCreate<XXX> methods.
273
generateCreateMethods(methodHelper.getCreateMethods());
274
275         // Add other required methods.
276
generateKnownMethods(methodHelper);
277
278         // Add helper methods for the helper class.
279
generateHelperClassMethods();
280
281         // Add conversion methods to the helper class.
282
generateConversions();
283
284         // Add ObjectId/PrimaryKey conversion methods.
285
generatePKObjectIdConversion(getKeyFields(allFields));
286
287         // Print end of classes.
288
concreteImplFileWriter.addClass(concreteImplWriter);
289         concreteImplFileWriter.save();
290
291         helperFileWriter.addClass(jdoHelperWriter);
292         helperFileWriter.save();
293
294         files.add(cmp_file);
295         files.add(hlp_file);
296
297         return files;
298     }
299
300     /** Add import statements for for the generated classes.
301      */

302     void addImportStatements(JavaFileWriter concreteImplFileWriter,
303             JavaFileWriter helperFileWriter) throws IOException JavaDoc {
304
305         String JavaDoc[] st = CMPTemplateFormatter.importsArray;
306         for (int i = 0; i < st.length; i++) {
307             concreteImplFileWriter.addImport(st[i], null);
308         }
309
310         st = CMPTemplateFormatter.helperImportsArray;
311         for (int i = 0; i < st.length; i++) {
312             helperFileWriter.addImport(st[i], null);
313         }
314     }
315
316     /**
317      * Add interfaces to the class declarations.
318      */

319     void addInterfaces() throws IOException JavaDoc {
320
321         String JavaDoc[] st = CMPTemplateFormatter.interfacesArray;
322         for (int i = 0; i < st.length; i++) {
323             concreteImplWriter.addInterface(st[i]);
324         }
325     }
326
327     /**
328      * Super class for the helper class is type specific.
329      */

330     abstract void setHelperSuperclass() throws IOException JavaDoc;
331
332     /**
333      * Generate type specific methods for setters, getters,
334      * and any other methods that are completely different
335      * between bean types.
336      */

337     void generateTypeSpecificMethods(
338             PersistenceFieldElement[] allFields,
339             AbstractMethodHelper methodHelper)
340             throws IOException JavaDoc {
341
342         // Initialize loadNonDFGBody for preloading non-DFG fields
343
// in read-only beans.
344
if (isUpdateable) {
345             loadNonDFGBody = null;
346         } else {
347             loadNonDFGBody = new StringBuffer JavaDoc();
348         }
349     }
350
351     /**
352      * Sets the signature of the input files for the codegen.
353      * @param newSignature The signature of the input files.
354      */

355     void addCodeGenInputFilesSignature(String JavaDoc newSignature)
356     {
357         if ((inputFilesSignature == null) ||
358             (inputFilesSignature.length() == 0)) {
359             inputFilesSignature = newSignature;
360         }
361         else {
362             inputFilesSignature =
363                 inputFilesSignature +
364                 CMPTemplateFormatter.signatureDelimiter_ +
365                 newSignature;
366         }
367     }
368     
369     /**
370      * Sets the signature of the generator classes for codegen.
371      * @param newSignature The signature of the generator classes.
372      */

373     void addCodeGeneratorClassSignature(String JavaDoc newSignature)
374     {
375         if ((generatorClassesSignature == null) ||
376             (generatorClassesSignature.length() == 0)) {
377             generatorClassesSignature = newSignature;
378         }
379         else {
380             generatorClassesSignature =
381                 generatorClassesSignature +
382                 CMPTemplateFormatter.signatureDelimiter_ +
383                 newSignature;
384         }
385     }
386
387     /**
388      * Generates required internal variables.
389      */

390     void generateFields() throws IOException JavaDoc {
391
392         // Add private transient fields:
393
CMPTemplateFormatter.addPrivateField(
394             CMPTemplateFormatter.privatetransientvformatter.format(pcnameParam),
395             Modifier.TRANSIENT,
396             concreteImplWriter);
397
398         // Add private static fields:
399
CMPTemplateFormatter.addPrivateField(
400             CMPTemplateFormatter.privateStaticVariablesTemplate,
401             Modifier.STATIC,
402             concreteImplWriter);
403
404         // Add private static final fields:
405
twoParams[0] = pcname;
406         twoParams[1] = beanName;
407         CMPTemplateFormatter.addPrivateField(
408             CMPTemplateFormatter.privatestaticfinalvformatter.format(twoParams),
409             Modifier.STATIC + Modifier.FINAL,
410             concreteImplWriter);
411
412         // Add public static final variables for signatures
413
twoParams[0] = generatorClassesSignature;
414         twoParams[1] = inputFilesSignature;
415         CMPTemplateFormatter.addFields(
416              CMPTemplateFormatter.publicstaticfinalvformatter.format(twoParams),
417              Modifier.PUBLIC + Modifier.STATIC + Modifier.FINAL,
418              concreteImplWriter);
419         
420         // The static fields holding the Query variables and their monitors
421
// are generated during finder/selector method handling.
422

423         CMPTemplateFormatter.addPrivateField(
424             CMPTemplateFormatter.otherVariablesTemplate,
425             0, concreteImplWriter);
426
427         twoParams[0] = concreteImplName;
428         twoParams[1] = beanName;
429         CMPTemplateFormatter.addPrivateField(
430             CMPTemplateFormatter.hvformatter.format(twoParams),
431             Modifier.TRANSIENT+Modifier.STATIC,
432             jdoHelperWriter);
433
434         // Add read-only fields:
435
if (!isUpdateable) {
436             // private transient fields:
437
CMPTemplateFormatter.addPrivateField(
438                 CMPROTemplateFormatter.privatetransientvformatter.format(pcnameParam),
439                 Modifier.TRANSIENT,
440                 concreteImplWriter);
441
442             // private static fields:
443
CMPTemplateFormatter.addPrivateField(
444                 CMPROTemplateFormatter.privateStaticVariablesTemplate,
445                 Modifier.STATIC,
446                 concreteImplWriter);
447         }
448
449     }
450
451     /** Adds ejbFindBy methods.
452      */

453     void generateFinders(AbstractMethodHelper methodHelper)
454             throws IOException JavaDoc {
455
456         boolean debug = logger.isLoggable(Logger.FINE);
457         List finders = methodHelper.getFinders();
458         for (int i = 0; i < finders.size(); i++) {
459             Method JavaDoc m = (Method JavaDoc)finders.get(i);
460             String JavaDoc mname = CMPTemplateFormatter.ejb_ +
461                 StringHelper.getCapitalizedString(m.getName());
462
463             if (debug) {
464                 logger.fine("Finder: " + mname); // NOI18N
465
}
466
467             if (mname.equals(CMPTemplateFormatter.ejbFindByPrimaryKey_)) {
468                 // ejbFindByPrimaryKey
469
String JavaDoc[] exceptionTypes =
470                     CMPTemplateFormatter.getExceptionNames(m);
471
472                 oneParam[0] = CMPTemplateFormatter.key_;
473
474                 concreteImplWriter.addMethod(CMPTemplateFormatter.ejbFindByPrimaryKey_, // name
475
Modifier.PUBLIC , // modifiers
476
pkClass, // returnType
477
oneParam, // parameterNames
478
pkClassParam, //parameterTypes
479
exceptionTypes,// exceptions
480
CMPTemplateFormatter.ejbFindByPrimaryKeyBody, //body
481
null);// comments
482

483             } else {
484                 JDOQLElements rs = getJDOQLElements(m, methodHelper);
485
486                 // check for single-object finder vs. multi-object finder
487
String JavaDoc returnType = isSingleObjectFinder(m) ?
488                     pkClass : m.getReturnType().getName();
489                 CMPTemplateFormatter.addGenericMethod(
490                     m, mname, returnType,
491                     generateFinderMethodBody(methodHelper, rs, mname, m, returnType, i),
492                     concreteImplWriter);
493             }
494         }
495
496
497     }
498
499     /** Returns JDOQLElements instance for this finder method.
500      * @param m the finder method as a java.lang.reflect.Method
501      * @param methodHelper the AbstractMethodHelper instance that contains
502      * all categorized methods and some other convenience methods for this bean.
503      * @return JDOQLElements instance.
504      */

505     abstract JDOQLElements getJDOQLElements(Method JavaDoc m,
506             AbstractMethodHelper methodHelper) throws IOException JavaDoc;
507
508     /** Adds ejbCreate<XXX> methods.
509      */

510     private void generateCreateMethods(List createMethods) throws IOException JavaDoc {
511         Class JavaDoc beanClass = null;
512         try {
513             beanClass = Class.forName(abstractBean, true, loader);
514         } catch (Exception JavaDoc e) {
515             throw new RuntimeException JavaDoc(e.toString());
516         }
517
518         // Store generated getters to avoid duplicates.
519
HashSet generated = new HashSet();
520
521         for (int i = 0; i < createMethods.size(); i++) {
522             Method JavaDoc m = (Method JavaDoc)createMethods.get(i);
523             Method JavaDoc m1 = m;
524
525             // Method name is ejbCreate<Method>
526
String JavaDoc createName =CMPTemplateFormatter.ejbCreate_;
527             String JavaDoc postCreateName =CMPTemplateFormatter.ejbPostCreate_;
528             if (m.getName().length() > 6) {
529                 String JavaDoc suffix = m.getName().substring(6);
530                 createName += suffix;
531                 postCreateName += suffix;
532             }
533
534             boolean debug = logger.isLoggable(Logger.FINE);
535             if (debug) {
536                 logger.fine("CreateMethod: " + abstractBean + "" + m.getName()); // NOI18N
537
logger.fine("ejbCreateMethod: " + createName); // NOI18N
538
logger.fine("ejbPostCreateMethod: " + postCreateName); // NOI18N
539
}
540
541             // Get actual method in the bean and resolve exception type to generate...
542
try {
543                 Class JavaDoc[] params = m.getParameterTypes();
544
545                 // This is a work around the case when the parameter class loader
546
// differs from the given class loader ("loader").
547
for (int j = 0; j < params.length; j++) {
548                     if (params[j].isPrimitive() ||
549                         params[j].getClassLoader() == null ||
550                         params[j].getClassLoader().equals(loader)) {
551                         continue;
552                     }
553                     String JavaDoc pname = params[j].getName();
554
555                     if (debug) {
556                         logger.fine("Replacing parameter class for: " + pname); // NOI18N
557
logger.fine("Param ClassLoader: " + params[j].getClassLoader());
558                         logger.fine("Need ClassLoader: " + loader);
559                     }
560
561                     params[j] = Class.forName(pname, true, loader);
562                 }
563                 // End of the work around the class loader problem.
564

565                 // Cannot use getDeclaredMethod() as the actual method can be in a
566
// superclass.
567
m = beanClass.getMethod(createName, params);
568                 m1 = beanClass.getMethod(postCreateName, params);
569                 if (generated.contains(m)) {
570                     // Called from more than one interface - skip it.
571
if (debug) {
572                         logger.fine("...generated..."); // NOI18N
573
}
574
575                     continue;
576
577                 }
578                 generated.add(m);
579
580             } catch (Exception JavaDoc e) {
581                 // method does not exist as ejbCreateXxx. It was a business method.
582
continue;
583             }
584
585             String JavaDoc[] exc = CMPTemplateFormatter.getExceptionNames(m);
586             String JavaDoc parametersList = CMPTemplateFormatter.getParametersList(m);
587             String JavaDoc parametersListWithSeparator = makeLiteral(
588                     CMPTemplateFormatter.getParametersListWithSeparator(
589                             m, CMPTemplateFormatter.paramConcatenator_ ));
590
591             String JavaDoc body = getEJBCreateMethodBody(createName, exc,
592                     parametersList, parametersListWithSeparator);
593
594             CMPTemplateFormatter.addGenericMethod(
595                     m, createName, pkClass, body, concreteImplWriter);
596
597             body = getEJBPostCreateMethodBody(postCreateName,
598                     parametersList, parametersListWithSeparator);
599
600             CMPTemplateFormatter.addGenericMethod(
601                     m1, postCreateName, CMPTemplateFormatter.void_,
602                     body, concreteImplWriter);
603         }
604     }
605
606     /** Returns method body for EJBCreate method.
607      * @param createName the actual name of the method as String.
608      * @param exc a String[] of decleared exceptions for this method.
609      * @param parametersList the list of method parameters as String.
610      * @param parametersListWithSeparator the list of concatenated method
611      * parameters to be passed to another method as String.
612      * @return method body as String.
613      */

614     abstract String JavaDoc getEJBCreateMethodBody(String JavaDoc createName,
615             String JavaDoc[] exc, String JavaDoc parametersList,
616             String JavaDoc parametersListWithSeparator);
617
618     /** Returns method body for EJBPostCreate method.
619      * @param postCreateName the actual name of the method as String.
620      * @param parametersList the list of method parameters as String.
621      * @param parametersListWithSeparator the list of concatenated method
622      * parameters to be passed to another method as String.
623      * @return method body as String.
624      */

625     abstract String JavaDoc getEJBPostCreateMethodBody(String JavaDoc postCreateName,
626             String JavaDoc parametersList, String JavaDoc parametersListWithSeparator);
627
628     /** Returns method body for EJBRemove method.
629      * @return method body as String.
630      */

631     abstract String JavaDoc getEJBRemoveMethodBody();
632
633     /** Adds other known required methods
634      * - CMPTemplateFormatter.commonPublicMethods_
635      * - CMPTemplateFormatter.commonPrivateMethods
636      * - Other generic methods
637      * - Special methods that differ between special types (e.g. read-only
638      * beans) to be overridden if necessary
639      * - CMPTemplateFormatter.otherPublicMethods_ that differ
640      * between CMP 1.1 and 2.x types are added in subclasses.
641      */

642     void generateKnownMethods(AbstractMethodHelper methodHelper)
643                        throws IOException JavaDoc {
644
645         String JavaDoc[] exc = null;
646         String JavaDoc[] st = CMPTemplateFormatter.commonPublicMethodsArray;
647         for (int i = 0; i < st.length; i++) {
648             String JavaDoc mname = st[i];
649             exc = getExceptionList(methodHelper, mname);
650
651             String JavaDoc body = null;
652             if (mname.equals(CMPTemplateFormatter.ejbRemove_)) {
653                 body = getEJBRemoveMethodBody();
654
655             } else if (mname.equals(CMPTemplateFormatter.ejb__flush_)) {
656                 oneParam[0] = CMPTemplateFormatter.DuplicateKeyException_;
657                 exc = oneParam;
658                 body = CMPTemplateFormatter.helpers.getProperty(mname);
659
660             } else {
661                 body = CMPTemplateFormatter.helpers.getProperty(mname);
662             }
663
664             concreteImplWriter.addMethod(mname, // name
665
Modifier.PUBLIC, // modifiers
666
CMPTemplateFormatter.void_, // returnType
667
null, // parameterNames
668
null,// parameterTypes
669
exc,// exceptions
670
CMPTemplateFormatter.getBodyAsStrings(body), // body
671
null);// comments
672

673         }
674
675         // This is a cleanup method that is public, but has int param.
676
oneParam[0] = CMPTemplateFormatter.int_;
677         concreteImplWriter.addMethod(CMPTemplateFormatter.afterCompletion_, // name
678
Modifier.PUBLIC, // modifiers
679
CMPTemplateFormatter.void_, // returnType
680
param0, // parameterNames
681
oneParam,// parameterTypes
682
null,// exceptions
683
CMPTemplateFormatter.afterCompletionBody, // body
684
null);// comments
685

686         concreteImplWriter.addMethod(CMPTemplateFormatter.ejb__remove_, // name
687
Modifier.PUBLIC , // modifiers
688
CMPTemplateFormatter.void_, // returnType
689
param0, // parameterNames
690
objectType, //parameterTypes
691
null,// exceptions
692
// body is not defined for this method.
693
null, // body
694
null);// comments
695

696         String JavaDoc body;
697         st = CMPTemplateFormatter.commonPrivateMethodsArray;
698
699         for (int i = 0; i < st.length; i++) {
700             String JavaDoc mname = st[i];
701             body = CMPTemplateFormatter.helpers.getProperty(mname);
702
703             CMPTemplateFormatter.addGenericMethod(mname,
704                 CMPTemplateFormatter.getBodyAsStrings(body), concreteImplWriter);
705         }
706
707         // Add jdoArrayCopy to return byte[].
708
oneParam[0] = CMPTemplateFormatter.byte_;
709         body = CMPTemplateFormatter.jdoarraycopyformatter.format(oneParam);
710
711         oneParam[0] = CMPTemplateFormatter.byteArray_;
712         concreteImplWriter.addMethod(
713             CMPTemplateFormatter.jdoArrayCopy_, // name
714
Modifier.PRIVATE, // modifiers
715
CMPTemplateFormatter.byteArray_, // returnType
716
param0, // parameterNames
717
oneParam,// parameterTypes
718
null,// exceptions
719
CMPTemplateFormatter.getBodyAsStrings(body), // body
720
null);// comments
721

722         // Add setEntityContext
723
oneParam[0] = CMPTemplateFormatter.EntityContext_;
724         concreteImplWriter.addMethod(CMPTemplateFormatter.setEntityContext_, // name
725
Modifier.PUBLIC, // modifiers
726
CMPTemplateFormatter.void_, // returnType
727
param0, // parameterNames
728
oneParam,// parameterTypes
729
getExceptionList(methodHelper,
730                 CMPTemplateFormatter.setEntityContext_,
731                 oneParam),// exceptions
732
CMPTemplateFormatter.setEntityContextBody, // body
733
null);// comments
734

735         // Add jdoGetObjectId
736
oneParam[0] = CMPTemplateFormatter.key_;
737
738         String JavaDoc[] param = new String JavaDoc[]{concreteImplName};
739
740         concreteImplWriter.addMethod(CMPTemplateFormatter.getObjectId_, // name
741
Modifier.PRIVATE , // modifiers
742
CMPTemplateFormatter.Object_, // returnType
743
oneParam, // parameterNames
744
pkClassParam,// parameterTypes
745
null,// exceptions
746
CMPTemplateFormatter.getBodyAsStrings(
747                 CMPTemplateFormatter.goidformatter.format(param)), // body
748
null);// comments
749

750         // Add jdoGetJdoInstanceClass
751
oneParam[0] = CMPTemplateFormatter.jdoGetJdoInstanceClassTemplate;
752
753         CMPTemplateFormatter.addGenericMethod(
754                 CMPTemplateFormatter.jdoGetJdoInstanceClass_,
755                 Modifier.PUBLIC + Modifier.STATIC,
756                 CMPTemplateFormatter.Class_, oneParam,
757                 concreteImplWriter);
758
759         generateSpecialKnownMethods();
760     }
761
762     /** Adds required methods that differ between special types (e.g. read-only
763      * beans) to be overridden if necessary;
764      */

765     void generateSpecialKnownMethods() throws IOException JavaDoc {
766
767         String JavaDoc[] body = null;
768
769         // For the following methods the method body exists only for
770
// updateable beans
771

772         // jdoClosePersistenceManager
773
if (isUpdateable) {
774             body = CMPTemplateFormatter.jdoClosePersistenceManagerBody;
775         }
776
777         CMPTemplateFormatter.addGenericMethod(
778                 CMPTemplateFormatter.jdoClosePersistenceManager_,
779                 body, concreteImplWriter);
780
781         // assertPersistenceManagerIsNull
782
if (isUpdateable) {
783             body = CMPTemplateFormatter.assertPersistenceManagerIsNullBody;
784         }
785         CMPTemplateFormatter.addGenericMethod(
786                 CMPTemplateFormatter.assertPersistenceManagerIsNull_,
787                 body, concreteImplWriter);
788
789         // assertInTransaction
790
if (isUpdateable) {
791             oneParam[0] = I18NHelper.getMessage(messages, "EXC_TransactionNotActive"); // NOI18N
792
body = CMPTemplateFormatter.getBodyAsStrings(
793                 CMPTemplateFormatter.intxformatter.format(oneParam));
794         }
795         CMPTemplateFormatter.addGenericMethod(
796                 CMPTemplateFormatter.assertInTransaction_,
797                 body, concreteImplWriter);
798
799         // For the following methods the method body exists for
800
// all bean types
801

802         // Add jdoGetPersistenceManager as method returning
803
// PersistenceManager:
804
if (isUpdateable) {
805             body = CMPTemplateFormatter.jdoGetPersistenceManagerBody;
806         } else {
807             body = CMPROTemplateFormatter.jdoGetPersistenceManagerBody;
808         }
809         CMPTemplateFormatter.addGenericMethod(
810                 CMPTemplateFormatter.jdoGetPersistenceManager_,
811                 CMPTemplateFormatter.jdoPersistenceManagerClass_,
812                 body, concreteImplWriter);
813
814         // Add jdoLookupPersistenceManagerFactory as static synchronized method:
815
oneParam[0] = concreteImplName;
816         MessageFormat JavaDoc mformat = null;
817         if (isUpdateable) {
818             mformat = CMPTemplateFormatter.jdolookuppmfformatter;
819         } else {
820             mformat = CMPROTemplateFormatter.jdolookuppmfformatter;
821         }
822         CMPTemplateFormatter.addGenericMethod(
823                 CMPTemplateFormatter.jdoLookupPersistenceManagerFactory_,
824                 Modifier.PRIVATE + Modifier.STATIC + Modifier.SYNCHRONIZED, // modifiers
825
CMPTemplateFormatter.getBodyAsStrings(mformat.format(oneParam)),
826                 concreteImplWriter);
827
828         // Add jdoGetInstance
829
threeParams[0] = pkClass;
830         threeParams[1] = pcname;
831         threeParams[2] = CMPTemplateFormatter.none_; // will be ignored for updateable beans
832
if (isUpdateable) {
833             mformat = CMPTemplateFormatter.giformatter;
834         } else {
835             if (loadNonDFGBody != null) {
836                 threeParams[2] = loadNonDFGBody.toString();
837             }
838             mformat = CMPROTemplateFormatter.giformatter;
839         }
840         CMPTemplateFormatter.addGenericMethod(
841                 CMPTemplateFormatter.getInstance_,
842                 CMPTemplateFormatter.getBodyAsStrings(mformat.format(threeParams)),
843                 concreteImplWriter);
844
845         // These are methods that do have arguments.
846

847         // ejb__refresh has method body only for read-only beans
848
if (isUpdateable) {
849             body = null;
850         } else {
851             // Reuse threeParams from getInstance_
852
body = CMPTemplateFormatter.getBodyAsStrings(
853                 CMPROTemplateFormatter.ejb__refreshformatter.format(threeParams));
854         }
855         concreteImplWriter.addMethod(CMPTemplateFormatter.ejb__refresh_, // name
856
Modifier.PUBLIC , // modifiers
857
CMPTemplateFormatter.void_, // returnType
858
param0, // parameterNames
859
objectType, //parameterTypes
860
null,// exceptions
861
body, // body
862
null);// comments
863

864         // Add jdoReleasePersistenceManager as method
865
// with PersistenceManager as a param:
866
oneParam[0] = CMPTemplateFormatter.jdoPersistenceManagerClass_;
867         
868         if (isUpdateable) {
869             body = CMPTemplateFormatter.jdoReleasePersistenceManagerBody;
870         } else {
871             body = CMPROTemplateFormatter.jdoReleasePersistenceManagerBody;
872         }
873         concreteImplWriter.addMethod(CMPTemplateFormatter.jdoReleasePersistenceManager_, // name
874
Modifier.PRIVATE, // modifiers
875
CMPTemplateFormatter.void_, // returnType
876
param0, // parameterNames
877
oneParam,// parameterTypes
878
null,// exceptions
879
body, // body
880
null);// comments
881

882     }
883
884     /**
885      * Generates helper methods for the helper class.
886      */

887     void generateHelperClassMethods() throws IOException JavaDoc {
888         // Add Helper.assertInstanceOfRemoteInterfaceImpl() method for all beans.
889
oneParam[0] = CMPTemplateFormatter.assertInstanceOfRemoteInterfaceImplTemplate;
890
891         jdoHelperWriter.addMethod(CMPTemplateFormatter.assertInstanceOfRemoteInterfaceImpl_, // name
892
Modifier.PUBLIC, // modifiers
893
CMPTemplateFormatter.void_, // returnType
894
param0, // parameterNames
895
objectType,// parameterTypes
896
null,// exceptions
897
oneParam, // body
898
null);// comments
899

900         // Add Helper.getHelperInstance() method.
901
oneParam[0] = CMPTemplateFormatter.getHelperInstanceTemplate;
902         CMPTemplateFormatter.addGenericMethod(
903                 CMPTemplateFormatter.getHelperInstance_,
904                 Modifier.PUBLIC + Modifier.STATIC,
905                 helperName, oneParam,
906                 jdoHelperWriter);
907
908         // Add Helper.getContainer() method.
909
CMPTemplateFormatter.addGenericMethod(
910                 CMPTemplateFormatter.getContainer_,
911                 Modifier.PUBLIC, CMPTemplateFormatter.Object_,
912                 CMPTemplateFormatter.getContainerBody,
913                 jdoHelperWriter);
914
915         // Add getPCCLass to the helper class
916
oneParam[0] = concreteImplName;
917         CMPTemplateFormatter.addGenericMethod(
918                 CMPTemplateFormatter.getPCClass_,
919                 Modifier.PUBLIC, CMPTemplateFormatter.Class_,
920                 CMPTemplateFormatter.getBodyAsStrings(
921                     CMPTemplateFormatter.pcclassgetterformatter.format(
922                     oneParam)),
923                 jdoHelperWriter);
924     }
925
926     private String JavaDoc[] getKeyFields(PersistenceFieldElement[] fields) {
927         List returnList = new ArrayList();
928         int i, count = ((fields != null) ? fields.length : 0);
929
930         for (i = 0; i < count; i++) {
931             PersistenceFieldElement pfe = fields[i];
932
933             if (pfe.isKey())
934                 returnList.add(pfe.getName());
935         }
936
937         return (String JavaDoc[])returnList.toArray(new String JavaDoc[returnList.size()]);
938     }
939
940     /** Adds ObjectId/PrimaryKey conversion methods to the helper class.
941      */

942     private void generatePKObjectIdConversion(String JavaDoc[] keyFields)
943                        throws IOException JavaDoc{
944         int length = keyFields.length;
945         StringBuffer JavaDoc getOid = new StringBuffer JavaDoc(); // PK -> Oid
946
StringBuffer JavaDoc getPK = new StringBuffer JavaDoc(); // Oid -> PK
947
String JavaDoc[] pkfieldParam = new String JavaDoc[1];
948
949         // Add parameter validation to avoid NullPointerException and
950
// other startup lines for the conversions that do not depend
951
// on the pk type.
952
getOid.append(CMPTemplateFormatter.assertPKNotNullTemplate).
953             append(CMPTemplateFormatter.noidformatter.format(pcnameParam));
954         getPK.append(CMPTemplateFormatter.assertOidNotNullTemplate).
955             append(CMPTemplateFormatter.oidcformatter.format(pcnameParam));
956
957         boolean debug = logger.isLoggable(Logger.FINE);
958         if (length == 1) {
959             // only one key field - we don't know yet if there is a special PK class.
960

961             // RESOLVE: Find out what must be null for this case....
962
String JavaDoc pkfield = keyFields[0];
963             String JavaDoc pkfieldType = model.getFieldType(pcname, pkfield);
964             pkfieldParam[0] = pkfield;
965
966             if (debug) {
967                 logger.fine("pkfield: " + pkfield); // NOI18N
968
}
969
970             if (model.isPrimitive(pcname, pkfield) ||
971                 (!pkClass.equals(pkfieldType) &&
972                     !pkClass.equals(Object JavaDoc.class.getName()))) {
973
974                 // A single primitive PK field requires a user defined PK class for
975
// conversion between Object and primitive value. The same type of conversion
976
// is generated for a user defined PK class in case of wrapper field type.
977
// Generate conversion as key.id = objectId.id and objectId.id = key.id
978

979                 getPK.append(CMPTemplateFormatter.npkformatter.format(pkClassParam));
980                 getOid.append(CMPTemplateFormatter.pkcformatter.format(pkClassParam));
981
982                 pkfieldParam[0] = pkfield;
983
984                 getOid.append(
985                     CMPTemplateFormatter.oidformatter.format(pkfieldParam));
986                 getPK.append(
987                     CMPTemplateFormatter.pkformatter.format(pkfieldParam));
988
989                 getPK.append(CMPTemplateFormatter.returnKey_);
990
991             } else {
992                 // PK Field is of wrapper type or unknown PK Class - generate conversion
993
// as key = objectId.id and objectId.id = key.
994
oneParam[0] = pkfieldType;
995                 getOid.append(CMPTemplateFormatter.pkcformatter.format(oneParam));
996
997                 twoParams[0] = pkfield;
998                 twoParams[1] = pkfieldType;
999                 getOid.append(
1000                    requireCloneOnGetAndSet(pkfieldType) ?
1001                        CMPTemplateFormatter.oid1cloneformatter.format(twoParams) :
1002                        (requireTrimOnSet(pkfieldType) ?
1003                            CMPTemplateFormatter.oid1stringformatter.format(pkfieldParam) :
1004                            CMPTemplateFormatter.oid1formatter.format(pkfieldParam)));
1005
1006                getPK.append(
1007                    requireCloneOnGetAndSet(pkfieldType) ?
1008                        CMPTemplateFormatter.pk1cloneformatter.format(pkfieldParam) :
1009                        CMPTemplateFormatter.pk1formatter.format(pkfieldParam));
1010
1011            }
1012        } else {
1013            // pkClass declaration with more than 1 field.
1014
getPK.append(CMPTemplateFormatter.npkformatter.format(pkClassParam));
1015            getOid.append(CMPTemplateFormatter.pkcformatter.format(pkClassParam));
1016
1017            for (int i = 0; i < length; i++) {
1018                String JavaDoc pkfield = keyFields[i];
1019                pkfieldParam[0] = pkfield;
1020
1021                if (debug) {
1022                    logger.fine("pkfield: " + pkfield); // NOI18N
1023
}
1024
1025                if (!model.isPrimitive(pcname, pkfield)) {
1026                    getOid.append(
1027                        CMPTemplateFormatter.assertpkfieldformatter.format(pkfieldParam));
1028                }
1029
1030                String JavaDoc pkfieldType = model.getFieldType(pcname, pkfield);
1031                twoParams[0] = pkfield;
1032                twoParams[1] = pkfieldType;
1033                getOid.append(
1034                    requireCloneOnGetAndSet(pkfieldType) ?
1035                        CMPTemplateFormatter.oidcloneformatter.format(twoParams) :
1036                        (requireTrimOnSet(pkfieldType) ?
1037                            CMPTemplateFormatter.oidstringformatter.format(pkfieldParam) :
1038                            CMPTemplateFormatter.oidformatter.format(pkfieldParam)));
1039                getPK.append(
1040                    requireCloneOnGetAndSet(pkfieldType) ?
1041                        CMPTemplateFormatter.pkcloneformatter.format(twoParams) :
1042                        CMPTemplateFormatter.pkformatter.format(pkfieldParam));
1043            }
1044
1045            getPK.append(CMPTemplateFormatter.returnKey_);
1046        }
1047        getOid.append(CMPTemplateFormatter.returnOid_);
1048
1049
1050        // Add ones that can be used for Collection conversion.
1051
jdoHelperWriter.addMethod(CMPTemplateFormatter.convertPrimaryKeyToObjectId_, // name
1052
Modifier.PUBLIC, // modifiers
1053
CMPTemplateFormatter.Object_, // returnType
1054
param0, // parameterNames
1055
objectType,// parameterTypes
1056
null,// exceptions
1057
CMPTemplateFormatter.getBodyAsStrings(getOid.toString()), // body
1058
null);// comments
1059

1060        jdoHelperWriter.addMethod(CMPTemplateFormatter.convertObjectIdToPrimaryKey_, // name
1061
Modifier.PUBLIC, // modifiers
1062
CMPTemplateFormatter.Object_, // returnType
1063
param0, // parameterNames
1064
objectType,// parameterTypes
1065
null,// exceptions
1066
CMPTemplateFormatter.getBodyAsStrings(getPK.toString()), // body
1067
null);// comments
1068

1069    }
1070
1071    /**
1072     * Returns the name of the concrete bean class for the specified name of
1073     * the persistence capable class.
1074     * @param pcClass the name of the persistence capable class
1075     * @return the name of the corresponding concrete bean class
1076     */

1077    String JavaDoc getConcreteBeanForPCClass(String JavaDoc pcClass) {
1078        return nameMapper.getConcreteBeanClassForEjbName(
1079            nameMapper.getEjbNameForPersistenceClass(pcClass));
1080    }
1081
1082    /**
1083     * Generates conversion methods from PC to EJBObject and back
1084     * to the helper class.
1085     */

1086    void generateConversions() throws IOException JavaDoc {
1087        String JavaDoc[] pcParams = new String JavaDoc[] {CMPTemplateFormatter.pc_,
1088                    CMPTemplateFormatter.jdoPersistenceManager_};
1089        String JavaDoc[] pcParamTypes = new String JavaDoc[] {CMPTemplateFormatter.Object_,
1090                    CMPTemplateFormatter.jdoPersistenceManagerClass_};
1091
1092        String JavaDoc[] collParamTypes = new String JavaDoc[] {CMPTemplateFormatter.Collection_,
1093                    CMPTemplateFormatter.jdoPersistenceManagerClass_};
1094
1095        // For PC - PK conversion.
1096
String JavaDoc[] body = null;
1097
1098        // Generate for Remote object conversion.
1099
if (hasRemoteInterface == false) {
1100            body = CMPTemplateFormatter.getBodyAsStrings(
1101                CMPTemplateFormatter.returnNull_ );
1102
1103            jdoHelperWriter.addMethod(CMPTemplateFormatter.convertPCToEJBObject_, // name
1104
Modifier.PUBLIC, // modifiers
1105
CMPTemplateFormatter.ejbObject_, // returnType
1106
pcParams, // parameterNames
1107
pcParamTypes,// parameterTypes
1108
null,// exceptions
1109
body, // body
1110
null);// comments
1111

1112            twoParams[0] = CMPTemplateFormatter.ejbObject_;
1113            twoParams[1] = CMPTemplateFormatter.jdoPersistenceManagerClass_;
1114            jdoHelperWriter.addMethod(CMPTemplateFormatter.convertEJBObjectToPC_, // name
1115
Modifier.PUBLIC, // modifiers
1116
CMPTemplateFormatter.Object_, // returnType
1117
param0PM, // parameterNames
1118
twoParams,// parameterTypes
1119
null,// exceptions
1120
body, // body
1121
null);// comments
1122
}
1123
1124    }
1125
1126    /**
1127     * Verifies if expected exception is part of the throws clause of the
1128     * corresponding method in the abstract class.
1129     * @param exc the list of the Exceptions to check.
1130     * @param checkExc the Exception to check for as String.
1131     * @return <code>true</code> if the passed Exception is declared.
1132     */

1133    boolean containsException(String JavaDoc[] exc, String JavaDoc checkExc) {
1134        boolean rc = false;
1135        if (exc != null) {
1136            for (int i = 0; i < exc.length; i++) {
1137                if (exc[i].equals(checkExc)) {
1138                    rc = true;
1139                    break;
1140                }
1141            }
1142        }
1143        return rc;
1144    }
1145
1146    /**
1147     * Verifies if expected exception is part of the throws clause of the
1148     * corresponding method in the abstract class. Returns EJBException
1149     * if the requested one is not found.
1150     * @param exc the list of the Exceptions to check.
1151     * @param checkExc the Exception to check for as String.
1152     * @return Exception to be thrown in the try-catch block.
1153     */

1154    String JavaDoc getException(String JavaDoc[] exc, String JavaDoc checkExc) {
1155        return (containsException(exc, checkExc)? checkExc :
1156            CMPTemplateFormatter.ejbException_);
1157    }
1158
1159    /**
1160     * Verifies if expected exception or its superclass are part of the
1161     * throws clause of the corresponding method in the abstract class.
1162     * Returns EJBException if none of the requested exceptions is not found.
1163     * @param exc the list of the Exceptions to check.
1164     * @param checkExc the Exception to check for as String.
1165     * @param superExc the known superclass for the Exception to check for as String.
1166     * @return Exception to be thrown in the try-catch block.
1167     */

1168    String JavaDoc getException(String JavaDoc[] exc, String JavaDoc checkExc, String JavaDoc superExc) {
1169        String JavaDoc rc = CMPTemplateFormatter.ejbException_;
1170        if (exc != null) {
1171            for (int i = 0; i < exc.length; i++) {
1172                if (exc[i].equals(checkExc) || exc[i].equals(superExc)) {
1173                    rc = checkExc;
1174                    break;
1175                }
1176            }
1177        }
1178        return rc;
1179    }
1180
1181    // helper methods to generate finder/selector method bodies
1182

1183    /**
1184     * Checks if the finder method is a single-object or multi-object finder.
1185     * @param finder Method object of the finder
1186     * @return <code>true</code> if it is a single-object finder
1187     */

1188    private boolean isSingleObjectFinder(Method JavaDoc finder) {
1189        return (!(finder.getReturnType().equals(java.util.Collection JavaDoc.class) ||
1190                  finder.getReturnType().equals(java.util.Enumeration JavaDoc.class)));
1191    }
1192
1193    /**
1194     * Generates the body of the Entity-Bean finder methods.
1195     * @param methodHelper the AbstractMethodHelper instance that contains
1196     * all categorized methods and some other convenience methods for this bean
1197     * @param jdoqlElements Result of the JDOQL-Compiler
1198     * @param mname name of the findermethod in
1199     * the concrete entity bean implementation
1200     * @param m method instance
1201     * @param returnType the returnType of this findermethod
1202     * @param index index of finder method in finders list
1203     * @return the generated body
1204     * @exception IOException
1205     */

1206    private String JavaDoc generateFinderMethodBody(AbstractMethodHelper methodHelper,
1207                                            JDOQLElements jdoqlElements,
1208                                            String JavaDoc mname,
1209                                            Method JavaDoc m,
1210                                            String JavaDoc returnType,
1211                                            int index) throws IOException JavaDoc {
1212
1213        StringBuffer JavaDoc body = new StringBuffer JavaDoc();
1214        body.append(CMPTemplateFormatter.assertPersistenceManagerIsNullTemplate);
1215        body.append(CMPTemplateFormatter.endLine_);
1216        body.append(generateFinderSelectorCommonBody(methodHelper,
1217                                                     jdoqlElements,
1218                                                     mname,
1219                                                     m,
1220                                                     returnType,
1221                                                     index));
1222
1223        // getting the catch-clause body from the properties
1224
oneParam[0] = mname;
1225
1226        // testing if this is a single-object finder
1227
if (isSingleObjectFinder(m)) {
1228            // generating the specific single finder method result set handling
1229
fourParams[0] = mname;
1230            fourParams[1] = pkClass;
1231            fourParams[2] = concreteImplName;
1232            fourParams[3] = CMPTemplateFormatter.catchClauseTemplate;
1233            body.append(CMPTemplateFormatter.singlefinderformatter.format(fourParams));
1234        } else {
1235            // generating the specific multi-object finder method result set handling
1236
// if CMP11 and the returntype is Enumeration, convert resultCollection
1237
// to Enumeration else leave Collection
1238
twoParams[0] = concreteImplName;
1239            twoParams[1] = CMPTemplateFormatter.catchClauseTemplate;
1240            if (isFinderReturningEnumeration(m)) {
1241                body.append(CMPTemplateFormatter.multifinderenumerationformatter.format(twoParams));
1242            } else {
1243                body.append(CMPTemplateFormatter.multifinderformatter.format(twoParams));
1244            }
1245        }
1246
1247        return body.toString();
1248    }
1249
1250    /**
1251     * JDOQuery Codegeneration for the common part of the
1252     * selecter and the finder methods. That consists of:
1253     * 1. create JDO Query object
1254     * 2. setting JDO Query elements (declare parameters, set variables etc.)
1255     * 3. convert parameter values (if available and necessary)
1256     * 4. execute the JDO Query
1257     * @param methodHelper the AbstractMethodHelper instance that contains
1258     * all categorized methods and some other convenience methods for this bean
1259     * @param jdoqlElements Result of the JDOQL-Compiler
1260     * @param methodName name of the finder/selector method in
1261     * the concrete entitybean implementation
1262     * @param m the method instance
1263     * @param returnType the return type of the finder/selectormethod
1264     * @param index index of finder/selector in corresponding list
1265     * @return the body as a string
1266     * @exception IOException
1267     */

1268    String JavaDoc generateFinderSelectorCommonBody(AbstractMethodHelper methodHelper,
1269                                                    JDOQLElements jdoqlElements,
1270                                                    String JavaDoc methodName,
1271                                                    Method JavaDoc m,
1272                                                    String JavaDoc returnType,
1273                                                    int index) throws IOException JavaDoc{
1274        // unique identifier across finders/selectors
1275
String JavaDoc queryVariableQualifier = m.getName() + '_' + index;
1276
1277        // add private static query variables and their monitors
1278
// no need to check ejbFindByPrimaryKey here
1279
oneParam[0] = queryVariableQualifier;
1280        CMPTemplateFormatter.addPrivateField(
1281            CMPTemplateFormatter.finderselectorstaticvformatter.format(oneParam),
1282            Modifier.STATIC,
1283            concreteImplWriter);
1284        CMPTemplateFormatter.addPrivateField(
1285            CMPTemplateFormatter.finderselectorstaticfinalvformatter.format(oneParam),
1286            Modifier.STATIC + Modifier.FINAL,
1287            concreteImplWriter);
1288
1289        StringBuffer JavaDoc body = new StringBuffer JavaDoc();
1290
1291        String JavaDoc[] parameterEjbNames = jdoqlElements.getParameterEjbNames();
1292
1293        // common param check for finder/selector
1294
body.append(generateFinderSelectorParamCheck(m, parameterEjbNames));
1295        
1296        // generating the querydeclaration
1297
String JavaDoc pcClassName = jdoqlElements.getCandidateClassName();
1298        String JavaDoc concreteBeanClassName = getConcreteBeanForPCClass(pcClassName);
1299        queryParams[0] = returnType;
1300        queryParams[1] = queryVariableQualifier;
1301        queryParams[2] = concreteBeanClassName;
1302        queryParams[3] = StringHelper.escape(jdoqlElements.getFilter());
1303        queryParams[4] = StringHelper.escape(jdoqlElements.getParameters());
1304        queryParams[5] = StringHelper.escape(jdoqlElements.getVariables());
1305        queryParams[6] = StringHelper.escape(jdoqlElements.getResult());
1306        queryParams[7] = StringHelper.escape(jdoqlElements.getOrdering());
1307        queryParams[8] = Boolean.toString(methodHelper.isQueryPrefetchEnabled(m));
1308        queryParams[9] = StringHelper.escape(generateQueryIgnoreCache());
1309        body.append(CMPTemplateFormatter.finderselectorformatter.format(queryParams));
1310
1311        // now generate the query execution
1312
// two cases: w/ and w/o query parameters
1313
String JavaDoc queryParam = generateParamConvBody(m, parameterEjbNames);
1314
1315        if (jdoqlElements.isAggregate()) {
1316            if (queryParam == null) {
1317               oneParam[0] = CMPTemplateFormatter.none_;
1318               body.append(CMPTemplateFormatter.aggqueryexecformatter.format(oneParam));
1319            } else {
1320               oneParam[0] = queryParam;
1321               body.append(
1322                 CMPTemplateFormatter.aggqueryexecparamconvformatter.format(oneParam));
1323            }
1324        } else {
1325            if (queryParam == null) {
1326               oneParam[0] = CMPTemplateFormatter.none_;
1327               body.append(CMPTemplateFormatter.queryexecformatter.format(oneParam));
1328            } else {
1329               oneParam[0] = queryParam;
1330               body.append(
1331                 CMPTemplateFormatter.queryexecparamconvformatter.format(oneParam));
1332            }
1333        }
1334
1335        return body.toString();
1336    }
1337
1338    /**
1339     * Generates code that check the finder/selector parameters for the
1340     * Query.execute call (if necessary).
1341     * @param m Method instance of the specific finder/selector method
1342     * @param parameterEjbNames array of ejb names
1343     * @return the codefragment for the checking local/remote parameters
1344     * for method if EJB name is known from ejbql.
1345     */

1346    String JavaDoc generateFinderSelectorParamCheck(Method JavaDoc m,
1347            String JavaDoc[] parameterEjbNames) {
1348        StringBuffer JavaDoc checkBody = new StringBuffer JavaDoc();
1349
1350        return checkBody.toString();
1351    }
1352
1353    /**
1354     * Generates a setIgnoreCache(true) call for a JDOQL query,
1355     * if necessary.
1356     * @return the codefragment to set the ignoreCache flag of a JDOQL query.
1357     */

1358    String JavaDoc generateQueryIgnoreCache()
1359    {
1360        return CMPTemplateFormatter.none_;
1361    }
1362
1363    /**
1364     * Checks if the finder returns an Enumeration.
1365     * @param finder Methodobject of the finder
1366     * @return <code>true</code> if the finder returns a Enumeration
1367     */

1368    abstract boolean isFinderReturningEnumeration(Method JavaDoc finder);
1369
1370    /**
1371     * Generates code that converts the finder/selector parameters for the
1372     * Query.execute call (if necessary). It maps local and remote interface
1373     * values to their corresponding pc instance using JDOHelper methods
1374     * provided by the concrete entity bean. Primitive type values are wrapped.
1375     * @param m Method instance of the specific finder/selector method
1376     * @param parameterEjbNames array of ejb names
1377     * @return the codefragment for the conversions as a string or null if there
1378     * aren't any parameters
1379     */

1380    private String JavaDoc generateParamConvBody(Method JavaDoc m, String JavaDoc[] parameterEjbNames) {
1381
1382        StringBuffer JavaDoc paramString = new StringBuffer JavaDoc();
1383        Class JavaDoc[] paramTypes = m.getParameterTypes();
1384        int paramLength = paramTypes.length;
1385        MessageFormat JavaDoc mformat = null;
1386        String JavaDoc paramClassName = null;
1387
1388        if (paramLength > 0) {
1389            // iterate over all paramclasses
1390
for (int i = 0; i < paramLength; i++) {
1391                paramClassName = paramTypes[i].getName();
1392
1393                // if local interface
1394
if (nameMapper.isLocalInterface(paramClassName) ||
1395                        nameMapper.isRemoteInterface(paramClassName)) {
1396
1397                    if (parameterEjbNames[i] != null) {
1398                        mformat = CMPTemplateFormatter.queryexecparamconvargumentformatter;
1399                        String JavaDoc concreteImplName =
1400                            nameMapper.getConcreteBeanClassForEjbName(
1401                            parameterEjbNames[i]);
1402                        threeParams[0] = concreteImplName;
1403                        threeParams[1] = String.valueOf(i);
1404                        threeParams[2] =
1405                            nameMapper.isLocalInterface(paramClassName) ?
1406                            CMPTemplateFormatter.convertEJBLocalObjectToPC_ :
1407                            CMPTemplateFormatter.convertEJBObjectToPC_;
1408                        paramString.append(mformat.format(threeParams));
1409                    } else {
1410                        paramString.append(CMPTemplateFormatter.param_ + i);
1411                    }
1412
1413                // if primitive type, do some wrapping
1414
} else if(paramTypes[i].isPrimitive()) {
1415                    paramString.append(
1416                          JavaClassWriterHelper.getWrapperExpr(
1417                                             paramTypes[i],
1418                                             JavaClassWriterHelper.param_ + i
1419                                             ));
1420
1421                // else take the param as it is
1422
} else {
1423                    paramString.append(CMPTemplateFormatter.param_ + i);
1424                }
1425                // normal delimiter
1426
if (i < paramLength - 1) paramString.append(
1427                                          CMPTemplateFormatter.paramSeparator_);
1428            }
1429        } else return null;
1430
1431        return paramString.toString();
1432    }
1433
1434    /**
1435     * Returns list of the declared exceptions for the method with this name
1436     * in the abstract bean. Returns null if such method does not exist
1437     * or does not have checked exceptions.
1438     * @param methodHelper the AbstractMethodHelper instance that contains
1439     * all categorized methods and some other convenience methods for this bean.
1440     * @param mname method name to check.
1441     * @param paramTypeNames list of parameter types to the method
1442     * @return list of the declared exceptions as String[].
1443     */

1444    String JavaDoc[] getExceptionList(AbstractMethodHelper methodHelper,
1445                                      String JavaDoc mname,
1446                                      String JavaDoc[] paramTypeNames) {
1447        String JavaDoc[] rc = null;
1448        Class JavaDoc[] paramTypes = null;
1449
1450        Map methodNames = methodHelper.getMethodNames();
1451        Method JavaDoc m = (Method JavaDoc) methodNames.get(mname);
1452
1453        boolean debug = logger.isLoggable(Logger.FINE);
1454        if (debug) {
1455            logger.fine("Processing method: " + mname);
1456            logger.fine("Known method: " + m);
1457        }
1458
1459        if (m == null) {
1460            // Check the bean class:
1461
if( paramTypeNames != null ) {
1462                paramTypes = new Class JavaDoc[ paramTypeNames.length ];
1463                try {
1464                    for( int i = paramTypeNames.length - 1; i >= 0; i-- ) {
1465                        paramTypes[i] = Class.forName( paramTypeNames[i], true, loader );
1466                    }
1467                } catch( Exception JavaDoc e ) {
1468                    // Ignore
1469
}
1470            }
1471
1472            try {
1473                Class JavaDoc beanClass = Class.forName(abstractBean, true, loader);
1474                m = beanClass.getMethod(mname, paramTypes);
1475                if (debug) {
1476                    logger.fine("Found method: " + m);
1477                }
1478
1479            } catch (Exception JavaDoc e) {
1480                // Ignore. Generate what we know.
1481
}
1482        }
1483
1484        if (m != null) {
1485            rc = CMPTemplateFormatter.getExceptionNames(m);
1486        }
1487
1488        return rc;
1489    }
1490
1491    /**
1492     * Returns list of the declared exceptions for the method with this name
1493     * in the abstract bean. Returns null if such method does not exist
1494     * or does not have checked exceptions.
1495     * @param methodHelper the AbstractMethodHelper instance that contains
1496     * all categorized methods and some other convenience methods for this bean.
1497     * @param mname method name to check.
1498     * @return list of the declared exceptions as String[].
1499     */

1500    String JavaDoc[] getExceptionList( AbstractMethodHelper methodHelper, String JavaDoc mname ) {
1501        return getExceptionList( methodHelper, mname, null );
1502    }
1503
1504    /**
1505     * This method will return the given string or "" if it is null or
1506     * empty string.
1507     * @param st input string
1508     */

1509    private String JavaDoc makeLiteral(String JavaDoc st) {
1510        return (StringHelper.isEmpty(st)) ?
1511            CMPTemplateFormatter.escapedEmptyString_ :
1512            CMPTemplateFormatter.paramInitializer_ + st;
1513    }
1514
1515    /**
1516     * Returns the signatures of the classes and properties which are
1517     * involved in the codegen.
1518     * @return The signatures as a string.
1519     */

1520    String JavaDoc getSignaturesOfGeneratorClasses()
1521    {
1522        StringBuffer JavaDoc signatures = new StringBuffer JavaDoc().
1523
1524            // adding signature of JDOConcreteBeanGenerator
1525
append(JDOConcreteBeanGenerator.SIGNATURE).
1526            append(CMPTemplateFormatter.signatureDelimiter_).
1527
1528            // adding signature of CMPTemplates.properties
1529
append(CMPTemplateFormatter.signatureTemplate).
1530            append(CMPTemplateFormatter.signatureDelimiter_).
1531                
1532            // adding signature of DeploymentDescriptorModel
1533
append(DeploymentDescriptorModel.SIGNATURE);
1534        
1535        return signatures.toString();
1536    }
1537
1538    /** Verifies if this field type requires clone for copy-in, copy-out
1539     * semantics.
1540     * @param fieldType the field type as String.
1541     * @return <code>true</code> if field type requires clone.
1542     */

1543    boolean requireCloneOnGetAndSet(String JavaDoc fieldType) {
1544        return (CMPTemplateFormatter.Date_.equals(fieldType) ||
1545            CMPTemplateFormatter.SqlDate_.equals(fieldType) ||
1546            CMPTemplateFormatter.SqlTime_.equals(fieldType) ||
1547            CMPTemplateFormatter.SqlTimestamp_.equals(fieldType));
1548    }
1549
1550    /** Verifies if this field type requires trim on set operation.
1551     * @param fieldType the field type as String.
1552     * @return <code>true</code> if field type is java.lang.String.
1553     */

1554    boolean requireTrimOnSet(String JavaDoc fieldType) {
1555        return CMPTemplateFormatter.String_.equals(fieldType);
1556    }
1557
1558    /** Generates code that preloads non-DFG fields for read-only beans.
1559     * @param fieldInfo the FieldInfo instance for this CMP field.
1560     */

1561    void loadNonDFGField(FieldInfo fieldInfo) {
1562        if( !isUpdateable && !fieldInfo.isDFG ) {
1563            oneParam[0] = fieldInfo.getter;
1564            loadNonDFGBody.append(
1565                    CMPROTemplateFormatter.loadNonDFGformatter.format(oneParam));
1566        }
1567    }
1568
1569    /*
1570     * This class contains the field information to generate get/set methods.
1571     *
1572     */

1573    class FieldInfo {
1574    
1575        final PersistenceFieldElement pfe;
1576    
1577        final String JavaDoc name;
1578        final String JavaDoc type;
1579        final String JavaDoc getter;
1580        final String JavaDoc setter;
1581    
1582        final boolean isKey;
1583        final boolean isPrimitive;
1584        final boolean isByteArray;
1585        final boolean isSerializable;
1586        final boolean requireCloneOnGetAndSet;
1587        final boolean isGeneratedField;
1588        final boolean isDFG;
1589    
1590        FieldInfo(Model model, NameMapper nameMapper,
1591                PersistenceFieldElement pfe,
1592                String JavaDoc beanName, String JavaDoc pcname) {
1593    
1594            this.pfe = pfe;
1595    
1596            String JavaDoc pfn = pfe.getName();
1597            name = nameMapper.getEjbFieldForPersistenceField(pcname, pfn);
1598    
1599            String JavaDoc fname = StringHelper.getCapitalizedString(name);
1600            getter = CMPTemplateFormatter.get_ + fname;
1601            setter = CMPTemplateFormatter.set_ + fname;
1602    
1603            boolean debug = logger.isLoggable(Logger.FINE);
1604            if (debug) {
1605                logger.fine("-Methods: " + getter + " " + setter); // NOI18N
1606
}
1607    
1608            isKey = pfe.isKey();
1609            isPrimitive = model.isPrimitive(pcname, pfn);
1610            isByteArray = model.isByteArray(beanName, name);
1611            isSerializable = model.isByteArray(pcname, pfn);
1612
1613            if (isSerializable) {
1614                // Replace '$' with '.' if it's an inner class.
1615
type = model.getFieldType(beanName, name).replace('$', '.');
1616            } else {
1617                type = model.getFieldType(beanName, name);
1618            }
1619
1620            if (debug) {
1621                logger.fine("Field: " + name + " " + type); // NOI18N
1622
}
1623    
1624            requireCloneOnGetAndSet = requireCloneOnGetAndSet(type);
1625            isGeneratedField = nameMapper.isGeneratedField(beanName, name);
1626
1627            // Check if the field is in DFG.
1628
MappingClassElement mce = model.getMappingClass(pcname);
1629            MappingFieldElement mfe = mce.getField(name);
1630            isDFG = (mfe.getFetchGroup() == MappingFieldElement.GROUP_DEFAULT);
1631        }
1632    }
1633
1634}
1635
1636
Popular Tags