tomee-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rickmcgu...@apache.org
Subject svn commit: r674853 - in /openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb: assembler/classic/ config/ core/cmp/cmp2/
Date Tue, 08 Jul 2008 15:13:24 GMT
Author: rickmcguire
Date: Tue Jul  8 08:13:24 2008
New Revision: 674853

URL: http://svn.apache.org/viewvc?rev=674853&view=rev
Log:
GERONIMO-842 CMP2Generator is not generating "is" methods. 


Modified:
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/CmpJarBuilder.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/CmpJpaConversion.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/Cmp1Generator.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/Cmp2Generator.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/CmpField.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/PostCreateGenerator.java

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java?rev=674853&r1=674852&r2=674853&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
(original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
Tue Jul  8 08:13:24 2008
@@ -424,6 +424,8 @@
 
         logger.info("createApplication.start", appInfo.jarPath);
 
+        // To start out, ensure we don't already have any beans deployed with duplicate IDs.
 This 
+        // is a conflict we can't handle. 
         List<String> used = new ArrayList<String>();
         for (EjbJarInfo ejbJarInfo : appInfo.ejbJars) {
             for (EnterpriseBeanInfo beanInfo : ejbJarInfo.enterpriseBeans) {
@@ -443,7 +445,7 @@
         }
 
         try {
-            // Generate the cmp2 concrete subclasses
+            // Generate the cmp2/cmp1 concrete subclasses
             CmpJarBuilder cmpJarBuilder = new CmpJarBuilder(appInfo, classLoader);
             File generatedJar = cmpJarBuilder.getJarFile();
             if (generatedJar != null) {

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/CmpJarBuilder.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/CmpJarBuilder.java?rev=674853&r1=674852&r2=674853&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/CmpJarBuilder.java
(original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/CmpJarBuilder.java
Tue Jul  8 08:13:24 2008
@@ -55,9 +55,20 @@
         return jarFile;
     }
 
+    /**
+     * Generate the CMP jar file associated with this 
+     * deployed application.  The generated jar file will 
+     * contain generated classes and metadata that will 
+     * allow the JPA engine to manage the bean persistence. 
+     * 
+     * @exception IOException
+     */
     private void generate() throws IOException {
-        // Don't generate an empty jar
-        if (!hasCmpBeans()) return;
+        // Don't generate an empty jar.  If there are no container-managed beans defined
in this 
+        // application deployment, there's nothing to do. 
+        if (!hasCmpBeans()) {
+            return;
+        }
 
         boolean threwException = false;
         JarOutputStream jarOutputStream = openJarFile();
@@ -89,6 +100,16 @@
         }
     }
 
+    /**
+     * Test if an application contains and CMP beans that 
+     * need to be mapped to the JPA persistence engine.  This 
+     * will search all of the ejb jars contained within 
+     * the application looking for Entity beans with 
+     * a CONTAINER persistence type. 
+     * 
+     * @return true if the application uses container managed beans, 
+     *         false if none are found.
+     */
     private boolean hasCmpBeans() {
         for (EjbJarInfo ejbJar : appInfo.ejbJars) {
             for (EnterpriseBeanInfo beanInfo : ejbJar.enterpriseBeans) {
@@ -103,6 +124,18 @@
         return false;
     }
 
+    /**
+     * Generate a class file for a CMP bean, writing the 
+     * byte data for the generated class into the jar file 
+     * we're constructing. 
+     * 
+     * @param jarOutputStream
+     *               The target jarfile.
+     * @param entityBeanInfo
+     *               The descriptor for the entity bean we need to wrapper.
+     * 
+     * @exception IOException
+     */
     private void generateClass(JarOutputStream jarOutputStream, EntityBeanInfo entityBeanInfo)
throws IOException {
         // don't generate if there is aleady an implementation class
         String cmpImplClass = CmpUtil.getCmpImplClassName(entityBeanInfo.abstractSchemaName,
entityBeanInfo.ejbClass);
@@ -119,6 +152,7 @@
             throw (IOException)new IOException("Could not find entity bean class " + beanClass).initCause(e);
         }
 
+        // and the primary key class, if defined.  
         Class<?> primKeyClass = null;
         if (entityBeanInfo.primKeyClass != null) {
             try {
@@ -128,22 +162,28 @@
             }
         }
 
+        // now generate a class file using the appropriate level of CMP generator.  
         byte[] bytes;
+        // NB:  We'll need to change this test of CMP 3 is ever defined!
         if (entityBeanInfo.cmpVersion != 2) {
             Cmp1Generator cmp1Generator = new Cmp1Generator(cmpImplClass, beanClass);
+            // A primary key class defined as Object is an unknown key.  Mark it that 
+            // way so the generator will create the automatically generated key. 
             if ("java.lang.Object".equals(entityBeanInfo.primKeyClass)) {
                 cmp1Generator.setUnknownPk(true);
             }
             bytes = cmp1Generator.generate();
         } else {
 
-            // generte the implementation class
+            // generate the implementation class
             Cmp2Generator cmp2Generator = new Cmp2Generator(cmpImplClass,
                     beanClass,
                     entityBeanInfo.primKeyField,
                     primKeyClass,
                     entityBeanInfo.cmpFieldNames.toArray(new String[entityBeanInfo.cmpFieldNames.size()]));
 
+            // we need to have a complete set of the defined CMR fields available for the

+            // generation process as well. 
             for (CmrFieldInfo cmrFieldInfo : entityBeanInfo.cmrFields) {
                 EntityBeanInfo roleSource = cmrFieldInfo.mappedBy.roleSource;
                 CmrField cmrField = new CmrField(cmrFieldInfo.fieldName,
@@ -161,6 +201,17 @@
         addJarEntry(jarOutputStream, entryName, bytes);
     }
 
+    
+    /**
+     * Insert a file resource into the generated jar file. 
+     * 
+     * @param jarOutputStream
+     *                 The target jar file.
+     * @param fileName The name we're inserting.
+     * @param bytes    The file byte data.
+     * 
+     * @exception IOException
+     */
     private void addJarEntry(JarOutputStream jarOutputStream, String fileName, byte[] bytes)
throws IOException {
         // add all missing directory entried
         String path = "";

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/CmpJpaConversion.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/CmpJpaConversion.java?rev=674853&r1=674852&r2=674853&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/CmpJpaConversion.java
(original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/CmpJpaConversion.java
Tue Jul  8 08:13:24 2008
@@ -102,8 +102,7 @@
 
         // todo scan existing persistence module for all entity mappings and don't generate
mappings for them
 
-
-        // create mappings
+        // create mappings if no mappings currently exist 
         EntityMappings cmpMappings = appModule.getCmpMappings();
         if (cmpMappings == null) {
             cmpMappings = new EntityMappings();
@@ -111,9 +110,12 @@
             appModule.setCmpMappings(cmpMappings);
         }
 
+        // we process this one jar-file at a time...each contributing to the 
+        // app mapping data 
         for (EjbModule ejbModule : appModule.getEjbModules()) {
             EjbJar ejbJar = ejbModule.getEjbJar();
 
+            // scan for CMP entity beans and merge the data into the collective set 
             for (EnterpriseBean enterpriseBean : ejbJar.getEnterpriseBeans()) {
                 if (isCmpEntity(enterpriseBean)) {
                     processEntityBean(ejbModule, cmpMappings, (EntityBean) enterpriseBean);
@@ -404,8 +406,10 @@
             return;
         }
 
+        // get the real bean class 
         Class ejbClass = loadClass(ejbModule.getClassLoader(), bean.getEjbClass());
-
+        // and generate a name for the subclass that will be generated and handed to the
JPA 
+        // engine as the managed class. 
         String jpaEntityClassName = CmpUtil.getCmpImplClassName(bean.getAbstractSchemaName(),
ejbClass.getName());
 
         // We don't use this mapping directly, instead we pull entries from it
@@ -604,11 +608,18 @@
 
                 String name = method.getName();
 
-
                 if (name.startsWith("get")){
                     name = name.substring("get".length(), name.length());
                 } else if (name.startsWith("is")){
-                    name = name.substring("is".length(), name.length());
+                    // Only add this if the return type from an "is" method 
+                    // boolean. 
+                    if (method.getReturnType() == Boolean.TYPE) {
+                        name = name.substring("is".length(), name.length());
+                    }
+                    else { 
+                        // not an acceptable "is" method. 
+                        continue; 
+                    }
                 } else continue;
 
                 name = Strings.lcfirst(name);

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/Cmp1Generator.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/Cmp1Generator.java?rev=674853&r1=674852&r2=674853&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/Cmp1Generator.java
(original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/Cmp1Generator.java
Tue Jul  8 08:13:24 2008
@@ -22,6 +22,10 @@
 import org.objectweb.asm.Type;
 import org.objectweb.asm.FieldVisitor;
 
+/**
+ * Class for generating a class file that implements 
+ * CMP1 type of persistence. 
+ */
 public class Cmp1Generator implements Opcodes {
     private String implClassName;
     private String beanClassName;
@@ -29,6 +33,13 @@
     private boolean unknownPk;
     private final PostCreateGenerator postCreateGenerator;
 
+    /**
+     * Constructor for a CMP1 class generator. 
+     * 
+     * @param cmpImplClass
+     *                  The name of the generated implementation class.
+     * @param beanClass The source Bean class we're wrappering.
+     */
     public Cmp1Generator(String cmpImplClass, Class beanClass) {
         beanClassName = Type.getInternalName(beanClass);
         implClassName = cmpImplClass.replace('.', '/');
@@ -38,7 +49,15 @@
         postCreateGenerator = new PostCreateGenerator(beanClass, cw);
     }
 
+    /**
+     * Generate the class for implementing CMP 1 level of
+     * persistence.
+     * 
+     * @return The generated byte-array containing the class data.
+     */
     public byte[] generate() {
+        // We're creating a superclass for the implementation.  We force this to implement
+        // EntityBean to allow POJOs to be used as the bean class. 
         cw.visit(V1_5, ACC_PUBLIC + ACC_SUPER, implClassName, null, beanClassName, new String[]{"javax/ejb/EntityBean"});
 
         // if we have an unknown pk, we need to add a field for the pk
@@ -48,8 +67,10 @@
             fv.visitEnd();
         }
 
+        // there's not much to generate here.  We create a default constructor, then generate
the 
+        // post create methods.  A lot of the work is done by having mapped superclass information
that 
+        // we pass to the JPA engine. 
         createConstructor();
-
         postCreateGenerator.generate();
         
         cw.visitEnd();
@@ -57,6 +78,12 @@
         return cw.toByteArray();
     }
 
+    /**
+     * Create a default constructor for our bean super 
+     * class.  This is just a forwarding constructor that 
+     * calls the superclass (the bean implementation class) 
+     * default constructor. 
+     */
     private void createConstructor() {
         MethodVisitor mv = mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
         mv.visitCode();

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/Cmp2Generator.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/Cmp2Generator.java?rev=674853&r1=674852&r2=674853&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/Cmp2Generator.java
(original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/Cmp2Generator.java
Tue Jul  8 08:13:24 2008
@@ -73,7 +73,8 @@
      * @param cmpFields The list of fields that are managed using cmp.
      */
     public Cmp2Generator(String cmpImplClass, Class beanClass, String pkField, Class<?>
primKeyClass, String[] cmpFields) {
-            
+
+        this.beanClass = beanClass;
         beanClassName = Type.getInternalName(beanClass);
         implClassName = cmpImplClass.replace('.', '/');
         
@@ -89,15 +90,14 @@
         // a getter defined and b) that we know the field return type.  The created CmpField

         // list will feed into the generation process. 
         for (String cmpFieldName : cmpFields) {
-            String getterName = getterName(cmpFieldName);
-            try {
-                Method getter = beanClass.getMethod(getterName);
-                Type type = Type.getType(getter.getReturnType());
-                CmpField cmpField = new CmpField(cmpFieldName, type);
-                this.cmpFields.put(cmpFieldName, cmpField);
-            } catch (NoSuchMethodException e) {
-                throw new IllegalArgumentException("No such property " + cmpFieldName + "
defined on bean class " + beanClassName, e);
+            Method getter = getterMethod(cmpFieldName);
+            if (getter == null) {
+                throw new IllegalArgumentException("No such property " + cmpFieldName + "
defined on bean class " + beanClassName);
             }
+            
+            Type type = Type.getType(getter.getReturnType());
+            CmpField cmpField = new CmpField(cmpFieldName, type, getter); 
+            this.cmpFields.put(cmpFieldName, cmpField);
         }
 
         // if a pkField is defined, it MUST be a CMP field.  Make sure it really exists 
@@ -118,8 +118,6 @@
             }
         }
 
-        this.beanClass = beanClass;
-
         // The class writer will be used for all generator activies, while the 
         // postCreateGenerator will be used to add the ejbPostCreatexxxx methods as a 
         // last step. 
@@ -448,7 +446,7 @@
      * @param cmpField The CMP field backing this getter method.
      */
     private void createGetter(CmpField cmpField) {
-        String methodName = getterName(cmpField.getName());
+        String methodName = cmpField.getGetterMethod().getName();
         MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, methodName, "()" + cmpField.getDescriptor(),
null, null);
         mv.visitCode();
         mv.visitVarInsn(ALOAD, 0);
@@ -458,12 +456,59 @@
         mv.visitEnd();
     }
 
+    /**
+     * Generate the getter name for a CMR property. 
+     * 
+     * @param propertyName
+     *               The name of the CMR property.
+     * 
+     * @return The string name of the getter method for the 
+     *         property.
+     */
     private static String getterName(String propertyName) {
         return "get" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
     }
 
     
     /**
+     * Get the getter method for this CMP field.  This 
+     * will be either get<Name> or is<Name> depending on 
+     * what abstract method is defined on the base bean
+     * class. 
+     * 
+     * @param propertyName The name of the CMP field. 
+     * 
+     * @return The name to be used for generating this method. 
+     */
+    private Method getterMethod(String propertyName) {
+        String getterName = "get" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
+        try {
+            // check to see if we have the getter as an abstract class.  This might be an
"is" method. 
+            Method method = beanClass.getMethod(getterName, new Class[0]); 
+            if (Modifier.isAbstract(method.getModifiers())) {
+                // this is a getter 
+                return method;     
+            }
+        } catch (NoSuchMethodException e) {
+        }
+        
+        // we're just going to assume this is the valid name.  Other validation should already
have been 
+        // performed prior to this. 
+        getterName = "is" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
+        try {
+            // check to see if we have the getter as an abstract class.  This might be an
"is" method. 
+            Method method = beanClass.getMethod(getterName, new Class[0]); 
+            if (Modifier.isAbstract(method.getModifiers())) {
+                // this is a getter 
+                return method;     
+            }
+        } catch (NoSuchMethodException e) {
+        }
+        return null; 
+    }
+
+    
+    /**
      * Generate a concrete setter field for a CMP field.  
      * At this point, we're just generating a simple 
      * accessor for the field, given the type.  The 

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/CmpField.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/CmpField.java?rev=674853&r1=674852&r2=674853&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/CmpField.java
(original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/CmpField.java
Tue Jul  8 08:13:24 2008
@@ -17,15 +17,19 @@
  */
 package org.apache.openejb.core.cmp.cmp2;
 
+import java.lang.reflect.Method; 
+
 import org.objectweb.asm.Type;
 
 public class CmpField {
     private final String name;
     private final Type type;
+    private final Method getter; 
 
-    public CmpField(String name, Type type) {
+    public CmpField(String name, Type type, Method getter) {
         this.name = name;
         this.type = type;
+        this.getter = getter; 
     }
 
     public String getName() {
@@ -39,4 +43,8 @@
     public String getDescriptor() {
         return type.getDescriptor();
     }
+    
+    public Method getGetterMethod() {
+        return getter; 
+    }
 }

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/PostCreateGenerator.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/PostCreateGenerator.java?rev=674853&r1=674852&r2=674853&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/PostCreateGenerator.java
(original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/PostCreateGenerator.java
Tue Jul  8 08:13:24 2008
@@ -26,7 +26,8 @@
 
 /**
  * Generate concrete implementations of EjbPostCreatexxx
- * methods for a bean class. 
+ * methods for a bean class.  This is implemented in a separate  
+ * class because it is used by both the CMP1 and CMP2 generators. 
  * @version $Rev$ $Date$
  */
 public class PostCreateGenerator {



Mime
View raw message