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

JDOCodeGenerator

public class JDOCodeGenerator extends Object implements com.sun.ejb.codegen.CMPGenerator, com.sun.jdo.spi.persistence.utility.database.DatabaseConstants

Fields Summary
public static final String
SIGNATURE
Signature with CVS keyword substitution for identifying the generated code
private static final String
MAPPING_EXTENSION
private static final com.sun.jdo.spi.persistence.utility.logging.Logger
logger
The logger
private static final ResourceBundle
validationBundle
The resource bundle used for validation
private ArrayList
files
private com.sun.ejb.codegen.EjbcContext
ejbcContext
private ClassLoader
loader
private JDOConcreteBeanGenerator
cmp11Generator
private JDOConcreteBeanGenerator
cmp20Generator
private com.sun.enterprise.deployment.EjbBundleDescriptor
bundle
private NameMapper
nameMapper
private com.sun.jdo.api.persistence.model.Model
model
private com.sun.jdo.spi.persistence.support.ejb.enhancer.meta.EJBMetaDataModelImpl
ejbModel
private static com.sun.enterprise.deployment.interfaces.QueryParser
jdoqlParamDeclParser
private String
inputFilesPath
private String
generatedXmlsPath
private File
classout
private MappingGenerator
mappingGenerator
private static final boolean
ignoreValidationResults
Flag set to true if code generation should proceed even if model validation fails
private static String
signatures
String representing the signatures of generic code-gen files
Constructors Summary
Methods Summary
private voidaddSignatures(JDOConcreteBeanGenerator cmpGenerator)
Add required signatures to the generator instance.


        // Add the code generation signature of the input files
        // Note, this is per bundle, so it needs to be set per
        // cmpGenerator instance.
        cmpGenerator.addCodeGenInputFilesSignature(getSignaturesOfInputFiles());
    
        // Add the code generation signature of the S1AS-specific generator classes.
        cmpGenerator.addCodeGeneratorClassSignature(
                getS1ASSpecificGeneratorClassesSignature());
    
public java.util.Collectioncleanup()

 
        // Remove the strong references to MappingClassElements
        // needed during deployment. The mapping class cache
        // can now be cleaned up by the garbage collector.
        // It is done by mappingGenerator.
        mappingGenerator.cleanup();

        // Reset cmp generators.
        cmp11Generator = null;
        cmp20Generator = null;

        return files;
    
private voidcreateDDLs(org.netbeans.modules.dbschema.SchemaElement schema, java.lang.String dbVendorName, java.sql.Connection conn)
Generates DDLs for specified database vendor name.

param
schema a schema representing database in memory
param
dbVendorName a string for database vendor name
param
conn a database connection
throws
IOException
throws
DBException


        // Make sure that generatedXmlsPath directory is created
        // before writing *.sql files to this location.
        File fileDir = new File(generatedXmlsPath);

        if (!fileDir.exists()) {
            fileDir.mkdirs();
        }

        // Can't use schema name as at the time of the event listener
        // processing, the name will be recalculated again, and it might
        // not match.
        String namePrefix = DeploymentHelper.getDDLNamePrefix(bundle);

        // sql generation file names.
        OutputStream createDDLSql = new FileOutputStream(new File(generatedXmlsPath,
                namePrefix + NAME_SEPARATOR + dbVendorName + CREATE_SQL_FILE_SUFFIX));
        OutputStream dropDDLSql = new FileOutputStream(new File(generatedXmlsPath,
                namePrefix + NAME_SEPARATOR + dbVendorName + DROP_SQL_FILE_SUFFIX));

        OutputStream dropDDLTxt = new FileOutputStream(new File(classout,
                namePrefix + DROP_DDL_JDBC_FILE_SUFFIX));
        OutputStream createDDLTxt = new FileOutputStream(new File(classout,
                namePrefix + CREATE_DDL_JDBC_FILE_SUFFIX));

        try {
            // XXX This code might be used in the future with the create
            // and drop flags to be set appropriately.
            // If we have a live connection, we'll need to add flags that
            // specify if it's necessary to create and drop tables at deploy.
            // For now it's never executed so we set those booleans to false.
            OutputStream dbStream = null;
            boolean createTablesAtDeploy = false;
            boolean dropTablesAtDeploy = false;
            if ((conn != null) && (createTablesAtDeploy || dropTablesAtDeploy)) {
                dbStream = new DatabaseOutputStream(conn);
            }
            // XXX This is the end of the code that might be used in the future.

            DDLGenerator.generateDDL(schema, dbVendorName, createDDLSql,
                dropDDLSql, dropDDLTxt, createDDLTxt, dbStream, dropTablesAtDeploy);
        } catch (SQLException ex) {
            if (logger.isLoggable(Logger.WARNING))
                logger.warning(ex.toString());
        }
    
public voidgenerate(com.sun.enterprise.deployment.IASEjbCMPEntityDescriptor ejbcmp, java.io.File srcout, java.io.File classout)

see
CMPGenerator#generate(IASEjbCMPEntityDescriptor, File, File)


        String beanName = ejbcmp.getName();

        // StringBuffer to store validation exception messages if there are any.
        // If there are no validation exceptions, the reference will be null.
        StringBuffer validateex = null;
    
        boolean debug = logger.isLoggable(Logger.FINE);
        if (debug)
            logger.fine("gen file in " + srcout.getAbsolutePath()); // NOI18N
    
        // We need to create a new ArrayList because model validation 
        // returns an unmodifiable list.  This may be a place to look 
        // for a performance improvement later for the case of empty 
        // or singleton collection (extra copies).
        Collection c = new ArrayList(validateModel(ejbcmp));

        // if the mapping info is not present, throw the exception and 
        // stop the generation process 
        GeneratorException mappingMissingEx = getMappingMissingException(c);
        if (mappingMissingEx != null)
            throw mappingMissingEx;

        c.addAll(validateSupported(ejbcmp));

        JDOConcreteBeanGenerator cmpGenerator = getCMPGenerator(ejbcmp);
        MethodHelper mh = new MethodHelper(ejbcmp);
        c.addAll(cmpGenerator.validate(mh, beanName));

        if (!c.isEmpty()) {
            // Validation failed the test. We will try to display all the
            // exceptions in a concatenated message and a GeneratorException 
            // is thrown.
            validateex = new StringBuffer();
            Iterator iter = c.iterator();
    
            while (iter.hasNext()) {
                Exception ex = (Exception)iter.next();
                if (debug)
                    logger.log(Logger.FINE,"validation exception: " , ex); //NOI18N
                validateex.append(ex.getMessage()).append('\n"); //NOI18N
            }
    
            if (!ignoreValidationResults)
                throw JDOCodeGeneratorHelper.createGeneratorException(
                        "CMG.ExceptionInValidate", //NOI18N
                        beanName, bundle, validateex.toString());    
        }

        try {
            Collection newfiles = null;
    
            if (!ejbcmp.isEJB20())
                ejbcmp.setQueryParser(jdoqlParamDeclParser);
    
            // IMPORTANT:
            // Concrete impl class generation must happen before generation of 
            // PC class as cmpGenerator will override cascadeDelete (DeleteAction)
            // property if it is set, and generatePC() saves .mapping file.
            newfiles = cmpGenerator.generate(mh, beanName, srcout, classout);
            files.addAll(newfiles);

            newfiles = generatePC(ejbcmp, srcout, classout);
            files.addAll(newfiles);

            if (validateex != null)
                throw JDOCodeGeneratorHelper.createGeneratorException(
                        "CMG.ExceptionInValidate", //NOI18N
                        beanName, bundle, validateex.toString());
        } catch (JDOUserException e) {
            // User error found. Append this exception's message to validation
            // messages if there are any.
            throw JDOCodeGeneratorHelper.createGeneratorException(
                    "CMG.ExceptionInGenerate", //NOI18N
                    beanName, bundle, e, validateex); 

        } catch (EJBQLException e) {
            // EJBQL parsing error found. Append this exception's message to
            // validation messages if there are any.
            throw JDOCodeGeneratorHelper.createGeneratorException(
                    "CMG.ExceptionInGenerate", //NOI18N
                    beanName, bundle, e, validateex); 

        } catch (IOException e) {
            // Problems generating file(s). Append this exception's message to 
            // validation messages if there are any.
            throw JDOCodeGeneratorHelper.createGeneratorException(
                    "CMG.IOExceptionInGenerate", //NOI18N
                    beanName, bundle, e, validateex); 
        }

    
private java.util.CollectiongeneratePC(com.sun.enterprise.deployment.IASEjbCMPEntityDescriptor ejbcmp, java.io.File srcout, java.io.File classout)
Generate PC class for the ConcreteImpl bean.

see
CMPGenerator#generate(IASEjbCMPEntityDescriptor, File, File)


        ArrayList fileList = new ArrayList();
        Main gen = new Main(ejbModel, srcout);
        String className = nameMapper.getPersistenceClassForEjbName(ejbcmp.getName());

        if (className != null) {
            // generate PC class
            //@olsen, 4653156: the enhancer-generator deals with class names
            // in JVM format, i.e., with '/' for '.' as separator
            String jvmClassName = className.replace('.", '/");
            File file = gen.generate(jvmClassName);
            fileList.add(file);

            // write mapping file
            MappingClassElement mappingClass
                = model.getMappingClass(className);
            BufferedOutputStream mapOut = null;
            try {
                String mapPath = className.replace('.", File.separatorChar);
                String mappingFile = mapPath + MAPPING_EXTENSION;
                mapOut = new BufferedOutputStream(
                    new FileOutputStream(new File(classout, mappingFile)));
                //"touch" need to create the output stream first since the
                //classout directory is not in the classpath and
                //therefore the standard storeMappingClass can't be used
                model.storeMappingClass(mappingClass, mapOut);
            } finally {
                if (mapOut != null) {
                    try {
                        mapOut.close();
                    } catch(Exception ex) {
                        if (logger.isLoggable(Logger.FINE))
                            logger.fine(ex.getMessage());  
                    }
                }
            }
            
        }
        return fileList;
    
private JDOConcreteBeanGeneratorgetCMP11Generator()
Returns instance of generator for CMP1.1 beans in this module.

        if (cmp11Generator == null) {
            cmp11Generator = new JDOConcreteBean11Generator(loader, model,
                    nameMapper);

            addSignatures(cmp11Generator);
        }

        return cmp11Generator;
    
private JDOConcreteBeanGeneratorgetCMP20Generator()
Returns instance of generator for CMP2.x beans in this module.

        if (cmp20Generator == null) {
            cmp20Generator = new JDOConcreteBean20Generator(loader, model,
                    nameMapper);

            addSignatures(cmp20Generator);
        }

        return cmp20Generator;
    
private JDOConcreteBeanGeneratorgetCMPGenerator(com.sun.enterprise.deployment.IASEjbCMPEntityDescriptor descr)
Returns CMP bean classes generator of the appropriate type.

param
descr the bean descriptor as IASEjbCMPEntityDescriptor.
return
instance of JDOConcreteBeanGenerator.


        JDOConcreteBeanGenerator cmpGenerator = null;
        try {
            if (descr.isEJB20()) {
                cmpGenerator = getCMP20Generator();
            } else {
                cmpGenerator = getCMP11Generator();
            }

            cmpGenerator.setUpdateable(
                    !descr.getIASEjbExtraDescriptors().isIsReadOnlyBean());

        } catch (IOException e) {
            // Problems reading file(s)
            throw JDOCodeGeneratorHelper.createGeneratorException(
                    "CMG.IOExceptionInInit", bundle, e); //NOI18N
        }

        return cmpGenerator;
    
private java.lang.StringgetFileInfoOfInputFile(java.lang.String pathname)
Returns a string consisting of the fully path and name of the input file and its length in bytes.

param
pathname The path and file name of the input file.
return
A string consisting of the fully path and name of the input file and its length in bytes.
throws
IOException

   
        File inputFile = new File(pathname);
        
        StringBuffer inputFileInfo = new StringBuffer().
            append(inputFile.getCanonicalPath().replace('\\", '/")).
            append(CMPTemplateFormatter.space_).
            append(String.valueOf(inputFile.length())).
            append(" bytes");

        return inputFileInfo.toString();               
    
private com.sun.ejb.codegen.GeneratorExceptiongetMappingMissingException(java.util.Collection c)
Checks a collection as returned by {@link #validateModel(IASEjbCMPEntityDescriptor)} to see if it contains (only) the {@link GeneratorException} used when the entire mapping definition is missing. In that case, we will want to skip other checks.

param
c a collection of validation exceptions as returned by validateModel.
return
if the collection contains exactly one GeneratorException return it, otherwise return null

        if (c.size() == 1) {
            Object firstElement = c.iterator().next();

            if (firstElement instanceof GeneratorException)
                return (GeneratorException)firstElement;
        }

        return null;
    
private static synchronized java.lang.StringgetS1ASSpecificGeneratorClassesSignature()
Returns the signatures of the classes and properties which are involved in the codegen for S1AS specific part.

return
The signatures as a string.

        if (signatures == null) {
            StringBuffer sb = new StringBuffer().
        
            // adding signature of JDOCodeGenerator
            append(JDOCodeGenerator.SIGNATURE).
            append(CMPTemplateFormatter.signatureDelimiter_).
        
            // adding signature of NameMapper
            append(NameMapper.SIGNATURE);
        
            signatures = sb.toString();       
        }
        return signatures;
    
private java.lang.StringgetSignaturesOfInputFiles()
Returns the signatures (file length) of the input files for the codegen. Inputfiles are ejb-jar.xml, sun-ejb-jar.xml, sun-cmp-mappings.xml.

return
The signatures as a string.
throws
IOException

        StringBuffer sb = new StringBuffer().
                       
            append(getFileInfoOfInputFile(inputFilesPath +
                File.separator + DescriptorConstants.EJB_JAR_ENTRY)).
            append(CMPTemplateFormatter.signatureDelimiter_).
               
            append(getFileInfoOfInputFile(inputFilesPath +
                File.separator + DescriptorConstants.S1AS_EJB_JAR_ENTRY)).
            append(CMPTemplateFormatter.signatureDelimiter_).

            append(getFileInfoOfInputFile(inputFilesPath +
                File.separator + DescriptorConstants.S1AS_CMP_MAPPING_JAR_ENTRY));               
               
        return sb.toString();        
    
public voidinit(com.sun.enterprise.deployment.EjbBundleDescriptor bundle, com.sun.ejb.codegen.EjbcContext ejbcContext, java.lang.String bundlePathName, java.lang.String generatedXmlsPathName)

see
CMPGenerator#init(EjbBundleDescriptor, EjbcContext, String)


             
         
            
          

        if (logger.isLoggable(Logger.FINE))
            logger.fine("cmp gen init"); // NOI18N

        this.ejbcContext = ejbcContext;
        this.generatedXmlsPath = generatedXmlsPathName;
        this.inputFilesPath = bundlePathName;
        this.classout = ejbcContext.getStubsDir(); 

        init(bundle, ejbcContext.getDescriptor().getClassLoader(), 
            bundlePathName, false);
    
public voidinit(com.sun.enterprise.deployment.EjbBundleDescriptor bundle, java.lang.ClassLoader loader, java.lang.String bundlePathName)

see
CMPGenerator#init(EjbBundleDescriptor, ClassLoader, String) This method should be merged with {@link #init(EjbBundleDescriptor, EjbcContext, String)} when TestFramework is fixed for optional pm-descriptors and java2db support.
deprecated


        init(bundle, loader, bundlePathName, false);
    
public voidinit(com.sun.enterprise.deployment.EjbBundleDescriptor bundle, java.lang.ClassLoader loader, java.lang.String bundlePathName, boolean ignoreSunDeploymentDescriptors)
Called by static verifier to bypass mapping validation or internally by other init() methods. Will force java2db generation if ignoreSunDeploymentDescriptors is true.

see
CMPGenerator#init(EjbBundleDescriptor, ClassLoader, String)

        if (logger.isLoggable(Logger.FINE))
            logger.fine("cmp gen init"); // NOI18N

        this.bundle = bundle;
        this.loader = loader;

        inputFilesPath = bundlePathName;

        try {
            nameMapper = new NameMapper(bundle);
            model = new DeploymentDescriptorModel(nameMapper, loader);
            mappingGenerator = new MappingGenerator(bundle, model, nameMapper, loader);
            loadOrCreateMappingClasses(ignoreSunDeploymentDescriptors);

            ejbModel = new EJBMetaDataModelImpl(model);

        } catch (IOException e) {
            // Problems storing properties file(s)
            throw JDOCodeGeneratorHelper.createGeneratorException(
                    "CMG.IOExceptionInInit", bundle, e); //NOI18N
        }
    
private voidloadOrCreateMappingClasses(boolean ignoreSunDeploymentDescriptors)
It will load mapping classes if there is sun-cmp-mappings.xml, otherwise it will call database generation backend to create mapping classes and schema. Generates *.dbschema and sun-cmp-mappings.xml in application dir if it is in creating mapping classes mode

param
ignoreSunDeploymentDescriptors Will force java2db generation if true.


        try {
            SchemaElement schema = mappingGenerator.generateMapping(
                    ejbcContext, inputFilesPath, generatedXmlsPath, classout,
                    ignoreSunDeploymentDescriptors);
            // If this is from verify, do not create DDL.
            if (ejbcContext != null 
                    && mappingGenerator.isJavaToDatabase()) {
                createDDLs(schema, mappingGenerator.getDatabaseVendorName(), null);
            }
        } catch (SQLException ex) {
            // Problems talking to the database.
            throw JDOCodeGeneratorHelper.createGeneratorException(
                    "CMG.SQLException", bundle, ex);
        } catch (DBException ex) {
            // Problems reading or creating DBModel.
            throw JDOCodeGeneratorHelper.createGeneratorException(
                    "CMG.DBException", bundle, ex); //NOI18N

        } catch (ModelException ex) {
            // Problems reading or creating model.
            throw JDOCodeGeneratorHelper.createGeneratorException(
                    "CMG.ModelException", bundle, ex); //NOI18N

        } catch (Schema2BeansException ex) {
            // Problems reading or creating sun-cmp-mapping.xml
            throw JDOCodeGeneratorHelper.createGeneratorException(
                    "CMG.Schema2BeansException", bundle, ex); //NOI18N
        } catch (ConversionException ex) {
            // Problems converting between sun-cmp-mappings and mapping model
            throw JDOCodeGeneratorHelper.createGeneratorException(
                    "CMG.MappingConversionException", bundle, ex); //NOI18N
        }
    
public java.util.Collectionvalidate(com.sun.enterprise.deployment.IASEjbCMPEntityDescriptor descr)

see
CMPGenerator#validate(IASEjbCMPEntityDescriptor descr)


        Collection c = new ArrayList();

        c.addAll(validateModel(descr));

        // only do EJBQL validation if the mapping info is present
        if (getMappingMissingException(c) == null)
            c.addAll(validateEJB(descr));

        if (logger.isLoggable(Logger.FINE)) {
            for (Iterator i = c.iterator(); i.hasNext();) {
                logger.log(Logger.FINE, "validation exception: ", //NOI18N
                        (Exception)i.next()); 
            }
        }

        return c;
    
private java.util.CollectionvalidateEJB(com.sun.enterprise.deployment.IASEjbCMPEntityDescriptor descr)
Validate the bean. For now, validate EJBQL for all finders and selectors of this bean.

param
descr the IASEjbCMPEntityDescriptor for this CMP bean.
return
a Collection of Exception instances for each found validation error.

        Collection c = null;
        try {
            JDOConcreteBeanGenerator cmpGenerator = getCMPGenerator(descr);
            c = cmpGenerator.validate(new MethodHelper(descr), descr.getName());
        } catch (GeneratorException e) {
            c = new ArrayList();
            c.add(e);
        }

        return c;
    
private java.util.CollectionvalidateModel(com.sun.enterprise.deployment.IASEjbCMPEntityDescriptor descr)
Validate the mapping file for the given class. First check if the mapping for the class exists in the sun-cmp-mappings. If so, continue to validate using {@link Model#validate(String, ClassLoader, ResourceBundle)}. If the resulting collection returned is not empty, it means it failed the test. The user should edit the mapping information, either in the IDE or the deploytool, or directly update the sun-cmp-mapping file.

param
descr the IASEjbCMPEntityDescriptor for this CMP bean.
return
a Collection of one GeneratorException if the mapping is totally missing or Collection of ModelException instances for each found validation error.

        String beanName = descr.getName();
        String className = nameMapper.getPersistenceClassForEjbName(beanName);

        if (model.getPersistenceClass(className) == null) {
           return Collections.singletonList(
               JDOCodeGeneratorHelper.createGeneratorException(
               "CMG.MissingBeanMapping", beanName, bundle)); //NOI18N
        }

        return model.validate(className, loader, validationBundle);
    
private java.util.CollectionvalidateSupported(com.sun.enterprise.deployment.IASEjbCMPEntityDescriptor descr)
Validate if this bean is of a supported type.

param
descr the IASEjbCMPEntityDescriptor for this CMP bean.
return
a Collection of Exception instances for each found validation error.

        Collection rc = new ArrayList();
        /*
         * XXX Add validation of read-only configuration?
         */

        return rc;