FileDocCategorySizeDatePackage
JDOConcreteBean20Generator.javaAPI DocGlassfish v2 API44910Fri May 04 22:34:48 BST 2007com.sun.jdo.spi.persistence.support.ejb.ejbc

JDOConcreteBean20Generator

public class JDOConcreteBean20Generator extends JDOConcreteBeanGenerator

Fields Summary
private com.sun.jdo.spi.persistence.support.ejb.ejbqlc.EJBQLC
ejbqlc
private Map
jdoqlElementsMap
Map that holds EJBQL compilation results for CMP 2.x beans queries. key is java.lang.reflect.Method object for the bean's finder or selector and the value is JDOQLElements object that represents EJBQL compilation results.
private StringBuffer
cascadeDelete
private String
gbody
private String
sbody
static final String
SIGNATURE
Signature with CVS keyword substitution for identifying the generated code
Constructors Summary
JDOConcreteBean20Generator(ClassLoader loader, com.sun.jdo.api.persistence.model.Model model, com.sun.jdo.spi.persistence.support.ejb.model.util.NameMapper nameMapper)

 //NOI18N
    
     
                              
                              
                               

        super(loader, model, nameMapper);
        CMP20TemplateFormatter.initHelpers();

        // Add the code generation signature of the generic and 2.x-specific 
        // generator classes.
        addCodeGeneratorClassSignature(getSignaturesOfGeneratorClasses());

        // init EJBQL compiler
        ejbqlc = new EJBQLC(model, nameMapper);
    
Methods Summary
voidaddImportStatements(JavaFileWriter concreteImplFileWriter, JavaFileWriter helperFileWriter)
Add import statements for for the generated classes.


        super.addImportStatements(concreteImplFileWriter, helperFileWriter);
        concreteImplFileWriter.addImport(
                CMP20TemplateFormatter.ejbHashSetImport_, null);
    
voidaddInterfaces()
Add interfaces to the class declarations.

        super.addInterfaces();
        jdoHelperWriter.addInterface(CMP20TemplateFormatter.helper20Interface_);
    
private voidgenerateCMPGetSetBodies(FieldInfo fieldInfo)
Generate bodies of getters and setters for CMP field

param
fieldInfo the field information as FieldInfo instance.


        // For read-only beans it will be the same. For updateable
        // beans it will be generated per field type.
        sbody = CMPROTemplateFormatter.updateNotAllowedTemplate;

        // Add code to load non-DFG field if necessary.
        loadNonDFGField(fieldInfo);

        if( fieldInfo.requireCloneOnGetAndSet ) {
            // CMP field should have copy-in, copy-out semantics
            // via clone.
            twoParams[0] = fieldInfo.getter;
            twoParams[1] = fieldInfo.type;
            gbody = CMP20TemplateFormatter.copygformatter.format(twoParams);

            if (isUpdateable) {
                twoParams[0] = fieldInfo.setter;
                if (!fieldInfo.isKey) {
                    sbody = CMP20TemplateFormatter.copysformatter.format(twoParams);
                } else {
                    String[] params = new String[] {concreteImplName, fieldInfo.name};
                    sbody = CMP20TemplateFormatter.assertpksformatter.format(params) +
                        CMP20TemplateFormatter.pkcopysformatter.format(twoParams);
                }
            }

        } else if( fieldInfo.isByteArray ) {
            // A byte[] CMP field should have copy-in, copy-out semantics
            // via System.arraycopy.
            oneParam[0] = fieldInfo.getter;
            gbody = CMP20TemplateFormatter.arraygformatter.format(oneParam);

            if (isUpdateable) {
                oneParam[0] = fieldInfo.setter;
                sbody = CMP20TemplateFormatter.arraysformatter.format(oneParam);
            }
        } else if( fieldInfo.isSerializable ) {
            // A special case for a Serializable CMP field (but not byte[]) -
            // it should be serialized to/from a byte[] in PC instance.
            
            threeParams[0] = fieldInfo.getter;
            threeParams[1] = fieldInfo.type;
            threeParams[2] = concreteImplName;
            gbody = CMP20TemplateFormatter.sfldgformatter.format(threeParams);

            if (isUpdateable) {
                twoParams[0] = fieldInfo.setter;
                twoParams[1] = concreteImplName;
                sbody = CMP20TemplateFormatter.sfldsformatter.format(twoParams);
            }
        } else {
            oneParam[0] = fieldInfo.getter;
            gbody = CMP20TemplateFormatter.gformatter.format(oneParam);

            if (isUpdateable) {
                oneParam[0] = fieldInfo.setter;
                if (!fieldInfo.isKey) {
                    sbody = CMP20TemplateFormatter.sformatter.format(oneParam);

                } else {
                    StringBuffer sb = new StringBuffer();
                    if (!fieldInfo.isPrimitive) {
                        twoParams[0] = concreteImplName;
                        twoParams[1] = fieldInfo.name;
                        sb.append(
                            CMP20TemplateFormatter.assertpksformatter.format(twoParams));
                    }
    
                    sb.append(requireTrimOnSet(fieldInfo.type) ? 
                        CMP20TemplateFormatter.pkstringsformatter.format(oneParam) :
                        CMP20TemplateFormatter.pksformatter.format(oneParam));

                    sbody = sb.toString();
                }
            }
        }

    
private voidgenerateCMRGetSetBodies(FieldInfo fieldInfo, java.lang.StringBuffer cmrcleanbodyBuf)
Generate bodies of getters and setters for CMR field

param
fieldInfo the field information as FieldInfo instance.
param
cmrcleanbodyBuf the StringBuffer to append code for CMR cleanup if necessary.


        RelationshipElement rel = (RelationshipElement)fieldInfo.pfe;

        String otherPC = model.getRelatedClass(rel);
        boolean manySide = model.isCollection(fieldInfo.type);

        if (logger.isLoggable(Logger.FINE)) {
            RelationshipElement otherField = rel.getInverseRelationship(model);
            String otherFieldName = ((otherField != null) ?
                    nameMapper.getEjbFieldForPersistenceField(otherPC, 
                            otherField.getName()) :
                    null);

            logger.fine("manySide: " + manySide); // NOI18N
            logger.fine("Field: " + otherFieldName); // NOI18N
        }

        String otherEJB = nameMapper.getEjbNameForPersistenceClass(otherPC);
        String otherImpl = nameMapper.getConcreteBeanClassForEjbName(otherEJB);
        MessageFormat mformat = null;

        if (manySide) {
            threeParams[0] = fieldInfo.getter;
            threeParams[1] = fieldInfo.name;
            threeParams[2] = otherImpl;
            gbody = CMP20TemplateFormatter.cmrCgformatter.format(threeParams);

            fourParams[0] = otherImpl;
            fourParams[1] = fieldInfo.setter;
            fourParams[2] = fieldInfo.getter;
            fourParams[3] = fieldInfo.name;
            sbody = CMP20TemplateFormatter.cmrCsformatter.format(fourParams);

            mformat = CMP20TemplateFormatter.cmrcdCformatter;

            twoParams[0] = fieldInfo.type;
            twoParams[1] = fieldInfo.name;
            CMP20TemplateFormatter.addPrivateField(
                CMP20TemplateFormatter.cmrvformatter.format(twoParams),
                0, concreteImplWriter);

            oneParam[0] = fieldInfo.name;
            cmrcleanbodyBuf.append(CMP20TemplateFormatter.cleancmrformatter.format(oneParam));

        } else { // 1 side
            fourParams[0] = otherPC;
            fourParams[1] = fieldInfo.getter;
            fourParams[2] = fieldInfo.type;
            fourParams[3] = otherImpl;
            gbody = CMP20TemplateFormatter.cmrgformatter.format(fourParams);

            threeParams[0] = otherPC;
            threeParams[1] = otherImpl;
            threeParams[2] = fieldInfo.setter;
            sbody = CMP20TemplateFormatter.cmrsformatter.format(threeParams);

            mformat = CMP20TemplateFormatter.cmrcdformatter;

        }

        if (rel.getDeleteAction() == RelationshipElement.CASCADE_ACTION) {
            twoParams[0] = fieldInfo.getter;
            twoParams[1] = otherImpl;
            cascadeDelete.append(mformat.format(twoParams));
            try {
                // Reset DeleteAction to NONE to suppress it in PM.deletePersistent().
                rel.setDeleteAction(RelationshipElement.NONE_ACTION);
            } catch (ModelException me) {
                logger.log(Logger.SEVERE, I18NHelper.getMessage(messages,
                        "CMG.ModelExceptionOnDeleteAction", me)); //NOI18N
            }
        }

    
voidgenerateConversions()
Generates conversion methods from PC to EJBObject and back to the helper class.


        super.generateConversions();

        // For EJBLocalObject.
        if (hasLocalInterface == false) {
            String[] pcParams = new String[] {CMP20TemplateFormatter.pc_,
                    CMP20TemplateFormatter.jdoPersistenceManager_};
            String[] pcParamTypes = new String[] {CMP20TemplateFormatter.Object_,
                    CMP20TemplateFormatter.jdoPersistenceManagerClass_};

            String[] body = CMP20TemplateFormatter.getBodyAsStrings(
                    CMP20TemplateFormatter.returnNull_);

            jdoHelperWriter.addMethod(CMP20TemplateFormatter.convertPCToEJBLocalObject_, // name
                Modifier.PUBLIC, // modifiers
                CMP20TemplateFormatter.ejbLocalObject_, // returnType
                pcParams, // parameterNames
                pcParamTypes,// parameterTypes
                null,// exceptions
                body, // body
                null);// comments

            String[] pcParamsX = new String[] {CMP20TemplateFormatter.pc_,
                    CMP20TemplateFormatter.jdoPersistenceManager_,
                    CMP20TemplateFormatter.context_};
            String[] pcParamTypesX = new String[] {CMP20TemplateFormatter.Object_,
                    CMP20TemplateFormatter.jdoPersistenceManagerClass_,
                    CMP20TemplateFormatter.ejbContext_};
            jdoHelperWriter.addMethod(CMP20TemplateFormatter.convertPCToEJBLocalObject_, // name
                Modifier.PUBLIC, // modifiers
                CMP20TemplateFormatter.ejbLocalObject_, // returnType
                pcParamsX, // parameterNames
                pcParamTypesX,// parameterTypes
                null,// exceptions
                body, // body
                null);// comments


            twoParams[0] = CMP20TemplateFormatter.ejbLocalObject_;
            twoParams[1] = CMP20TemplateFormatter.jdoPersistenceManagerClass_;
            jdoHelperWriter.addMethod(CMP20TemplateFormatter.convertEJBLocalObjectToPC_, // name
                Modifier.PUBLIC, // modifiers
                CMP20TemplateFormatter.Object_, // returnType
                param0PM, // parameterNames
                twoParams,// parameterTypes
                null,// exceptions
                body, // body
                null);// comments
        }
    
java.lang.StringgenerateFinderSelectorParamCheck(java.lang.reflect.Method m, java.lang.String[] parameterEjbNames)
Generates code that check the finder/selector parameters for the Query.execute call (if necessary).

param
m Method instance of the specific finder/selector method
param
parameterEjbNames array of ejb names
return
the codefragment for the checking local/remote parameters for method if EJB name is known from ejbql.

        StringBuffer checkBody = new StringBuffer();

        Class[] paramTypes = m.getParameterTypes();
        int paramLength = paramTypes.length;
        String paramClassName = null;
        for (int i = 0; i < paramLength; i++) {
            if (parameterEjbNames[i] != null) {
                paramClassName = paramTypes[i].getName();
                String concreteImplName =
                    nameMapper.getConcreteBeanClassForEjbName(
                    parameterEjbNames[i]);
                twoParams[0] = concreteImplName;
                twoParams[1] = CMP20TemplateFormatter.param_ + i;

                if (nameMapper.isLocalInterface(paramClassName)) {
                    checkBody.append(CMP20TemplateFormatter.finderselectorchecklocalformatter.format(twoParams));
                } else { // Remote
                    checkBody.append(CMP20TemplateFormatter.finderselectorcheckremoteformatter.format(twoParams));
                }
            }
        }

        return checkBody.toString();
    
private voidgenerateGetSetMethods(PersistenceFieldElement[] fields)
Adds getters and setters.

        int i, count = ((fields != null) ? fields.length : 0);
        setPKField = null; // reset to null to clean it up.
        cascadeDelete = new StringBuffer();

        // jdoCleanCollectionRef() body
        StringBuffer cmrcleanbodyBuf = new StringBuffer(CMP20TemplateFormatter.none_);

        for (i = 0; i < count; i++) {
            PersistenceFieldElement pfe = fields[i];

            if (PersistenceFieldElement.PERSISTENT == pfe.getPersistenceType()) {

                // Reset the strings.
                gbody = null;
                sbody = null;

                FieldInfo fieldInfo = new FieldInfo(model, nameMapper, pfe, beanName, pcname);

                if (fieldInfo.isGeneratedField) {
                // Skip generated fields as they are not present in the bean class.
                // A field is generated for the unknown PK class, version consistency, or 
                // a 2 way managed relationship.
                    if (fieldInfo.isKey) {
                        // This is an extra field for the unknown PK class.
                        // PK setter name is used to generate the line for ejbCreate
                        // to set the PK value in _JDOState.
                        setPKField = fieldInfo.setter;
                    }
                    continue;
                }

                if (!(pfe instanceof RelationshipElement)) {
                    generateCMPGetSetBodies(fieldInfo);

                } else { // CMR
                    if (isUpdateable) {
                        generateCMRGetSetBodies(fieldInfo, cmrcleanbodyBuf);

                    } else {
                        logger.log(Logger.WARNING, I18NHelper.getMessage(messages,
                                "CMG.CMRAccessNotAllowed", beanName, fieldInfo.name)); // NOI18N

                        gbody = CMPROTemplateFormatter.accessNotAllowedTemplate;
                        sbody = CMPROTemplateFormatter.updateNotAllowedTemplate;
                    }
                }

                // Now generate getter and setter:
                CMPTemplateFormatter.addGenericMethod(
                    fieldInfo.getter, Modifier.PUBLIC, fieldInfo.type, 
                    CMP20TemplateFormatter.getBodyAsStrings(gbody),
                    concreteImplWriter);

                oneParam[0] = fieldInfo.type;
                concreteImplWriter.addMethod(fieldInfo.setter, // name
                    Modifier.PUBLIC, // modifiers
                    CMP20TemplateFormatter.void_, // returnType
                    param0, // parameterNames
                    oneParam,// parameterTypes
                    null,// exceptions
                    CMP20TemplateFormatter.getBodyAsStrings(sbody), // body
                    null);// comments
            }
        }

        // Now generate jdoCleanCollectionRef method
        CMPTemplateFormatter.addGenericMethod(
               CMP20TemplateFormatter.jdoCleanCollectionRef_,
               CMP20TemplateFormatter.getBodyAsStrings(cmrcleanbodyBuf.toString()),
               concreteImplWriter);
    
voidgenerateHelperClassMethods()
Generates helper methods for the helper class.


        super.generateHelperClassMethods();
        // Add Helper.assertInstanceOfLocalInterfaceImpl() method for cmp2.0 only.
        oneParam[0] = CMP20TemplateFormatter.assertInstanceOfLocalInterfaceImplTemplate;

        jdoHelperWriter.addMethod(CMP20TemplateFormatter.assertInstanceOfLocalInterfaceImpl_, // name
                Modifier.PUBLIC, // modifiers
                CMP20TemplateFormatter.void_, // returnType
                param0, // parameterNames
                objectType,// parameterTypes
                null,// exceptions
                oneParam, // body
                null);// comments
    
voidgenerateKnownMethods(AbstractMethodHelper methodHelper)
Adds other known required methods identified by properties that do not need formatting but differ between CMP types. CMP20TemplateFormatter.otherPublicMethods_ differ between CMP types.


        super.generateKnownMethods(methodHelper);

        String[] exc = null;
        String[] st = CMP20TemplateFormatter.otherPublicMethodsArray;
        for (int i = 0; i < st.length; i++) {
            String mname = st[i];
            exc = getExceptionList(methodHelper, mname);

            String body = CMPROTemplateFormatter.updateNotAllowedTemplate;
            // Only ejbLoad from this list doesn't differ for read-only beans.
            if (isUpdateable || mname.equals(CMPTemplateFormatter.ejbLoad_)) {
                body = CMP20TemplateFormatter.helpers.getProperty(mname);
            } else if (mname.equals(CMPTemplateFormatter.jdoCleanAllRefs_)) {
                body = CMPROTemplateFormatter.jdoCleanAllRefsTemplate;
            }

            concreteImplWriter.addMethod(mname, // name
                Modifier.PUBLIC, // modifiers
                CMP20TemplateFormatter.void_, // returnType
                null, // parameterNames
                null,// parameterTypes
                exc,// exceptions
                CMP20TemplateFormatter.getBodyAsStrings(body), // body
                null);// comments
        }

    
private java.lang.StringgenerateResultHandlingForMultiSelector(com.sun.jdo.spi.persistence.support.ejb.ejbqlc.JDOQLElements jdoqlElements, java.lang.reflect.Method m, AbstractMethodHelper methodHelper)
Generates the result handling for a multi-value selector method. The generated code converts the JDO query result set into the appropriate selector result.

param
jdoqlElements the result of the JDOQL compiler
param
m selector method object
param
methodHelper the AbstractMethodHelper instance that contains all categorized methods and some other convenience methods for this bean
return
the generated result set handling


        boolean convertToSet = false;
        String body = null;
        MessageFormat mformat = null;
        // getting the catch-clause body from the properties
        oneParam[0] = m.getName();

        // depending of the kind of returntype a different convertermethodcall
        // is generated
        if (isSelectorReturningSet(m)) convertToSet = true;

        int queryReturnType = methodHelper.getQueryReturnType(m);
        if ((queryReturnType == AbstractMethodHelper.NO_RETURN) && 
            jdoqlElements.isPCResult()) {
            // Use LOCAL_RETURN as default, 
            // if there is no result-type-mapping specified and 
            // the JDOQL query returns a collection of pc instances 
            queryReturnType = AbstractMethodHelper.LOCAL_RETURN;
        }

        switch (queryReturnType) {
        case (AbstractMethodHelper.LOCAL_RETURN):
            mformat = CMP20TemplateFormatter.multiselectorconvformatter;
            threeParams[0] =
                getConcreteBeanForPCClass(jdoqlElements.getResultType());
            threeParams[1] = convertToSet ?
                CMP20TemplateFormatter.convertCollectionPCToEJBLocalObjectSet_ :
                CMP20TemplateFormatter.convertCollectionPCToEJBLocalObject_;
            threeParams[2] = CMP20TemplateFormatter.catchClauseTemplate;
            body = mformat.format(threeParams);
            break;
        case (AbstractMethodHelper.REMOTE_RETURN):
            mformat = CMP20TemplateFormatter.multiselectorconvformatter;
            threeParams[0] =
                getConcreteBeanForPCClass(jdoqlElements.getResultType());
            threeParams[1] = convertToSet ?
                CMP20TemplateFormatter.convertCollectionPCToEJBObjectSet_ :
                CMP20TemplateFormatter.convertCollectionPCToEJBObject_;
            threeParams[2] = CMP20TemplateFormatter.catchClauseTemplate;
            body = mformat.format(threeParams);
            break;
        case (AbstractMethodHelper.NO_RETURN):
        default:
            mformat = convertToSet ?
                CMP20TemplateFormatter.multiselectorsetformatter :
                CMP20TemplateFormatter.multiselectorformatter;
            oneParam[0] = CMP20TemplateFormatter.catchClauseTemplate;
            body = mformat.format(oneParam);
            break;
        }

        return body;
    
private java.lang.StringgenerateResultHandlingForSingleSelector(com.sun.jdo.spi.persistence.support.ejb.ejbqlc.JDOQLElements jdoqlElements, java.lang.String mname, java.lang.reflect.Method m, AbstractMethodHelper methodHelper, java.lang.String returnType)
Generates the result handling for a single-object selector method. The generated code converts the JDO query result set into the appropriate selector result.

param
jdoqlElements the result of the JDOQL compiler
param
mname name of the selector method in the concrete entity bean implementation
param
m selector method object
param
methodHelper the AbstractMethodHelper instance that contains all categorized methods and some other convenience methods for this bean
param
returnType the returntype of the selectormethod
return
the generated result set handling


        StringBuffer body = new StringBuffer();
        MessageFormat mformat = null;
        String jdoResultType = jdoqlElements.getResultType();
        String ejbName = null;
        // generated code that tests the cardinality of the JDO query
        // a JDOQL aggregate query returns a single object => no check needed
        if (!jdoqlElements.isAggregate()) {
            mformat = CMP20TemplateFormatter.singleselectorformatter;
            oneParam[0] = mname;
            body.append(mformat.format(oneParam));
        }

        // getting the catch-clause body from the properties
        oneParam[0] = CMP20TemplateFormatter.none_;

        int queryReturnType = methodHelper.getQueryReturnType(m);
        if ((queryReturnType == AbstractMethodHelper.NO_RETURN) && 
            jdoqlElements.isPCResult()) {
            // Use LOCAL_RETURN as default, 
            // if there is no result-type-mapping specified and 
            // the JDOQL query returns a collection of pc instances 
            queryReturnType = AbstractMethodHelper.LOCAL_RETURN;
        }

        // generate different converter method call depending on return type
        switch (queryReturnType) {
        case (AbstractMethodHelper.LOCAL_RETURN):
            ejbName = nameMapper.getEjbNameForPersistenceClass(jdoResultType);
            mformat = CMP20TemplateFormatter.singleselectorreturnconvformatter;
            fourParams[0] = nameMapper.getLocalInterfaceForEjbName(ejbName);
            fourParams[1] = nameMapper.getConcreteBeanClassForEjbName(ejbName);
            fourParams[2] = CMP20TemplateFormatter.convertPCToEJBLocalObject_;
            fourParams[3] = CMP20TemplateFormatter.catchClauseTemplate;
            body.append(mformat.format(fourParams));
            break;
        case (AbstractMethodHelper.REMOTE_RETURN):
            ejbName = nameMapper.getEjbNameForPersistenceClass(jdoResultType);
            mformat = CMP20TemplateFormatter.singleselectorreturnconvformatter;
            fourParams[0] = nameMapper.getRemoteInterfaceForEjbName(ejbName);
            fourParams[1] = nameMapper.getConcreteBeanClassForEjbName(ejbName);
            fourParams[2] = CMP20TemplateFormatter.convertPCToEJBObject_;
            fourParams[3] = CMP20TemplateFormatter.catchClauseTemplate;
            body.append(mformat.format(fourParams));
            break;
        case (AbstractMethodHelper.NO_RETURN):
        default:
            Class returnTypeClass = m.getReturnType();
            // tests if it is aggregate function and proceed it first
            if (jdoqlElements.isAggregate()) {
                if (returnTypeClass.isPrimitive()) {
                    mformat = CMP20TemplateFormatter.aggregateselectorprimitivereturnformatter;
                    fourParams[0] = mname;
                    fourParams[1] = jdoResultType;
                    fourParams[2] = CMP20TemplateFormatter.dot_ +
                        CMP20TemplateFormatter.getUnwrapMethodName(returnTypeClass);
                    fourParams[3] = CMP20TemplateFormatter.catchClauseTemplate;
                    body.append(mformat.format(fourParams));
                } else if (returnTypeClass.getName().equals(jdoResultType)) {
                    mformat = CMP20TemplateFormatter.aggregateselectorreturnformatter;
                    twoParams[0] = jdoResultType;
                    twoParams[1] = CMP20TemplateFormatter.catchClauseTemplate;
                    body.append(mformat.format(twoParams));
                } else if (returnTypeClass.isAssignableFrom(
                    java.math.BigDecimal.class)) {
                    mformat = CMP20TemplateFormatter.aggregateselectorreturnbigdecimalconvformatter;
                    twoParams[0] = jdoResultType;
                    twoParams[1] = CMP20TemplateFormatter.catchClauseTemplate;
                    body.append(mformat.format(twoParams));
                } else if (returnTypeClass.isAssignableFrom(
                    java.math.BigInteger.class)) {
                    mformat = CMP20TemplateFormatter.aggregateselectorreturnbigintegerconvformatter;
                    twoParams[0] = jdoResultType;
                    twoParams[1] = CMP20TemplateFormatter.catchClauseTemplate;
                    body.append(mformat.format(twoParams));

                } else {
                    mformat = CMP20TemplateFormatter.aggregateselectorreturnconvformatter;
                    fourParams[0] = returnType;
                    fourParams[1] = jdoResultType;
                    fourParams[2] = CMP20TemplateFormatter.dot_ +
                        CMP20TemplateFormatter.getUnwrapMethodName(
                        CMP20TemplateFormatter.getPrimitiveClass(
                        CMP20TemplateFormatter.getPrimitiveName(returnTypeClass)));
                    fourParams[3] = CMP20TemplateFormatter.catchClauseTemplate;
                    body.append(mformat.format(fourParams));
                }
            } else {
                // tests if the returntype is a primitive java type
                // if so, the cast parameter is the wrapperclass of the
                // primitive type and the getterMethod for the primitive
                // value of the wrapper class is added.
                // This is necessary because the JDOQuery returns collections
                // of objects only, but the selector returns a primitive type.
                mformat = CMP20TemplateFormatter.singleselectorreturnformatter;
                if (returnTypeClass.isPrimitive()) {
                    threeParams[0] = CMP20TemplateFormatter.getWrapperName(returnType);
                    threeParams[1] = CMP20TemplateFormatter.dot_ +
                       CMP20TemplateFormatter.getUnwrapMethodName(returnTypeClass);
                    threeParams[2] = CMP20TemplateFormatter.catchClauseTemplate;
                } else {
                    threeParams[0] = returnType;
                    threeParams[1] = CMP20TemplateFormatter.none_;
                    threeParams[2] = CMP20TemplateFormatter.catchClauseTemplate;
                }
                body.append(mformat.format(threeParams));
            }

            break;
        }

        return body.toString();
    
private java.lang.StringgenerateSelectorMethodBody(AbstractMethodHelper methodHelper, com.sun.jdo.spi.persistence.support.ejb.ejbqlc.JDOQLElements jdoqlElements, java.lang.String mname, java.lang.reflect.Method m, java.lang.String returnType, int index)
Generates the body of the Entity-Bean selector methods. This is the special result set handling.

param
methodHelper the AbstractMethodHelper instance that contains all categorized methods and some other convenience methods for this bean
param
jdoqlElements the result of the EJBQL-Compiler
param
mname name of the selector method in the concrete entity bean implementation
param
m selector method object
param
index index of selector method in selectors list
param
returnType the returntype of the selectormethod
return
the generated body
exception
IOException


        StringBuffer body = new StringBuffer();

        // add preSelect callback
        oneParam[0] = concreteImplName;
        body.append(CMP20TemplateFormatter.preselectformatter.format(oneParam));

        // common body for finder/selectors
        body.append(generateFinderSelectorCommonBody(methodHelper,
                                                     jdoqlElements,
                                                     mname,
                                                     m,
                                                     returnType,
                                                     index));

        // body with resulthandling depending on the type of the selector
        // (single or multivalue)
        if (isSingleObjectSelector(m)) {
            body.append(generateResultHandlingForSingleSelector(
                jdoqlElements, mname, m, methodHelper, returnType));
        } else {
            body.append(generateResultHandlingForMultiSelector(
                jdoqlElements, m, methodHelper));
        }

        return body.toString();
    
private voidgenerateSelectors(AbstractMethodHelper methodHelper)
Adds ejbSelectBy methods.

        List selectors = methodHelper.getSelectors();
        boolean debug = logger.isLoggable(Logger.FINE);
        if (debug) {
            logger.fine("Selectors: " + selectors.size()); // NOI18N
        }

        for (int i = 0; i < selectors.size(); i++) {
            Method m = (Method)selectors.get(i);
            String mname = m.getName();

            if (debug) {
                logger.fine("Selector: " + mname); // NOI18N
            }

            JDOQLElements rs = (JDOQLElements)jdoqlElementsMap.get(m);
            if (rs == null) {
                if (debug) {
                    logger.fine("JDOQLElements NOT FOUND for: " + mname);
                }

                // calling EJBQL compiler
                rs = ejbqlc.compile(methodHelper.getQueryString(m), m,
                    methodHelper.getQueryReturnType(m), false, beanName);
            }

            String returnType = m.getReturnType().getName();
            CMP20TemplateFormatter.addGenericMethod(
                m, mname, returnType,
                generateSelectorMethodBody(methodHelper, rs, mname, m, returnType, i),
                concreteImplWriter);
        }
    
voidgenerateTypeSpecificMethods(PersistenceFieldElement[] allFields, AbstractMethodHelper methodHelper)
Generate CMP2.0 specific methods.


        super.generateTypeSpecificMethods(allFields, methodHelper);

        // Print getters and setters for CMP2.0 only.
        generateGetSetMethods(allFields);

        // Add selectors.
        generateSelectors(methodHelper);

    
java.lang.StringgetEJBCreateMethodBody(java.lang.String createName, java.lang.String[] exc, java.lang.String parametersList, java.lang.String parametersListWithSeparator)
Returns method body for EJBCreate method.

param
createName the actual name of the method as String.
param
exc a String[] of decleared exceptions for this method.
param
parametersList the list of method parameters as String.
param
parametersListWithSeparator the list of concatenated method parameters to be passed to another method as String.
return
method body as String.


        // ejbCreate in the superclass will have the same suffix, so we need
        // to pass the actual name to the formatter - see 'createName' parameter.
        if (!containsException(exc, CMP20TemplateFormatter.CreateException_)) {
            throw new JDOUserException(I18NHelper.getMessage(messages,
                    "EXC_NoCreateException", createName, abstractBean)); // NOI18N
        }

        // For read-only beans it will be the same. For updateable
        // beans it will be generated as required.
        String body = CMPROTemplateFormatter.accessNotAllowedTemplate;
        if (isUpdateable) {
            sixParams[0] = pcname;
            sixParams[1] = createName;
            sixParams[2] = parametersList;
            sixParams[4] = concreteImplName;
            sixParams[5] = parametersListWithSeparator;

            if (pkClass.equals(Object.class.getName())) {
                sixParams[3] = setPKField;

                body = CMP20TemplateFormatter.cunpkformatter.format(sixParams);
            } else {
                sixParams[3] = pkClass;
                body = CMP20TemplateFormatter.cformatter.format(sixParams);
            }
        }

        return body;
    
java.lang.StringgetEJBPostCreateMethodBody(java.lang.String postCreateName, java.lang.String parametersList, java.lang.String parametersListWithSeparator)
Returns method body for EJBPostCreate method.

param
postCreateName the actual name of the method as String.
param
parametersList the list of method parameters as String.
param
parametersListWithSeparator the list of concatenated method parameters to be passed to another method as String.
return
method body as String.


        // For read-only beans it will be the same. For updateable
        // beans it will be generated as required.
        String body = CMPTemplateFormatter.none_;

        if (isUpdateable) {
            twoParams[0] = postCreateName;
            twoParams[1] = parametersList;

            body = CMP20TemplateFormatter.postcformatter.format(twoParams);
        }

        return body;
    
java.lang.StringgetEJBRemoveMethodBody()
Returns method body for EJBRemove method.

return
method body as String.

        // For read-only beans it will throw an exception. For updateable
        // beans it will be generated as required.
        String body = CMPROTemplateFormatter.updateNotAllowedTemplate;
        if (isUpdateable) {
            // CMP2.0 might have cascade-delete requirement.
            if (cascadeDelete.length() > 0) {
                oneParam[0] = CMP20TemplateFormatter.startCascadeDeleteTemplate +
                        cascadeDelete.append(
                        CMP20TemplateFormatter.endCascadeDeleteTemplate).
                        toString();
            } else {
                oneParam[0] = CMP20TemplateFormatter.none_;
            }

            body = CMP20TemplateFormatter.rmformatter.format(oneParam);
         }

        return body;
    
com.sun.jdo.spi.persistence.support.ejb.ejbqlc.JDOQLElementsgetJDOQLElements(java.lang.reflect.Method m, AbstractMethodHelper methodHelper)
Returns JDOQLElements instance for this finder method.

param
m the finder method as a java.lang.reflect.Method
param
methodHelper the AbstractMethodHelper instance that contains all categorized methods and some other convenience methods for this bean.
return
JDOQLElements instance.

        // Call the EJBQL compiler if there is no known result
        // from validate call.
        JDOQLElements rs  = (JDOQLElements)jdoqlElementsMap.get(m);
        if (rs == null) {
            if (logger.isLoggable(Logger.FINE)) {
                logger.fine("JDOQLElements NOT FOUND for: " + m.getName());
            }

            rs = ejbqlc.compile(methodHelper.getQueryString(m), m, 
                    methodHelper.getQueryReturnType(m), true, beanName);
        }

        return rs;
    
java.lang.StringgetSignaturesOfGeneratorClasses()
Returns the signatures of the classes and properties which are involved in the codegen.

return
The signatures as a string.

        StringBuffer signatures = new StringBuffer().

            // adding signature of JDOConcreteBeanGenerator
            append(super.getSignaturesOfGeneratorClasses()).
            append(CMPTemplateFormatter.signatureDelimiter_).

            // adding signature of JDOConcreteBean20Generator
            append(JDOConcreteBean20Generator.SIGNATURE).
            append(CMPTemplateFormatter.signatureDelimiter_).

            // adding signature of CMP20Templates.properties
            append(CMP20TemplateFormatter.signature2_0Template).
            append(CMPTemplateFormatter.signatureDelimiter_).

            // adding signature of EJBQLC
            append(EJBQLC.SIGNATURE);

        return signatures.toString();
    
booleanisFinderReturningEnumeration(java.lang.reflect.Method finder)
Checks if the finder returns an Enumeration. Returns false for CMP2.0.

param
finder Methodobject of the finder
return
true if the finder returns a Enumeration

        return false;
    
private booleanisSelectorReturningSet(java.lang.reflect.Method selector)
Checks if the a selector returns a Set (for CMP2.0)

param
selector Methodobject of the selector
return
true if the selector returns a Set

        return (selector.getReturnType().equals(java.util.Set.class));
    
private booleanisSingleObjectSelector(java.lang.reflect.Method finder)
Checks if the selector method is a single-object or multi-object selector.

param
finder Method object of the finder
return
true if it is a single-object-value selector

        return (!(finder.getReturnType().equals(java.util.Collection.class) ||
                  finder.getReturnType().equals(java.util.Set.class)));
    
voidsetHelperSuperclass()
Set super class for the helper class.

        jdoHelperWriter.setSuperclass(CMP20TemplateFormatter.helper20Impl_);
    
java.util.Collectionvalidate(AbstractMethodHelper methodHelper, java.lang.String beanName)
Validate this CMP bean. At this point, only EJBQL validation is done for 2.0 CMP beans. Adds validation result to that of the super class.

param
methodHelper the AbstractMethodHelper instance that contains all categorized methods and some other convenience methods for this bean.
param
beanName the ejb name for this bean.
return
a Collection of Exception instances with a separate instance for each failed validation.

        Collection rc = super.validate(methodHelper, beanName);

        this.beanName = beanName;
        rc.addAll(validateEJBQL(methodHelper)); 

        return rc;
    
private java.util.CollectionvalidateEJBQL(AbstractMethodHelper methodHelper)
Validate EJBQL for ejbFind and ejbSelect methods by calling compilation. The method stores compilation results in the {@link #jdoqlElementsMap} map. This method is called only for CMP 2.x beans as there is no validation of CMP 1.1 queries at the deployment time.

param
methodHelper the AbstractMethodHelper instance that contains all categorized methods and some other convenience methods for this bean.
return
a Collection of found exceptions.

        Collection rc = new ArrayList();
        jdoqlElementsMap = new HashMap();

        List methods = new ArrayList(methodHelper.getFinders());
        methods.addAll(methodHelper.getSelectors());
        for (int i = 0; i < methods.size(); i++) {
            Method m = (Method)methods.get(i);
            String mname = m.getName();
            if (mname.equals(CMP20TemplateFormatter.findByPrimaryKey_)) {
                // No EJBQL is defined for findByPrimaryKey.
                continue;
            }

            try {
                // EJBQLC needs to know if we are processing a finder or a selector.
                jdoqlElementsMap.put(m,
                        ejbqlc.compile(methodHelper.getQueryString(m), m, 
                               methodHelper.getQueryReturnType(m), 
                               mname.startsWith(CMP20TemplateFormatter.find_), 
                               beanName)); 
            } catch (EJBQLException e) {
                rc.add(e);
            }
        }

        return rc;