You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by da...@apache.org on 2007/01/04 05:23:10 UTC

svn commit: r492404 [2/3] - in /incubator/openejb/trunk/openejb3: container/openejb-core/ container/openejb-core/src/main/java/org/apache/openejb/ container/openejb-core/src/main/java/org/apache/openejb/alt/assembler/ container/openejb-core/src/main/ja...

Added: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/Cmp2Generator.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/Cmp2Generator.java?view=auto&rev=492404
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/Cmp2Generator.java (added)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/Cmp2Generator.java Wed Jan  3 20:23:04 2007
@@ -0,0 +1,511 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openejb.core.cmp.cmp2;
+
+import java.lang.reflect.Method;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+public class Cmp2Generator implements Opcodes {
+    private String implClassName;
+    private String beanClassName;
+    private ClassWriter cw;
+    private final Map<String, CmpField> cmpFields = new LinkedHashMap<String, CmpField>();
+    private final Map<String, CmrField> cmrFields = new LinkedHashMap<String, CmrField>();
+    private CmpField pkField;
+
+    public Cmp2Generator(Class beanClass, String pkField, String[] cmrFields) {
+        beanClassName = Type.getInternalName(beanClass);
+        implClassName = beanClassName + "_JPA";
+
+        for (String cmpFieldName : cmrFields) {
+            String getterName = getterName(cmpFieldName);
+            try {
+                Method getter = beanClass.getMethod(getterName);
+                Type type = Type.getType(getter.getReturnType());
+                CmpField cmpField = new CmpField(cmpFieldName, type);
+                cmpFields.put(cmpFieldName, cmpField);
+            } catch (NoSuchMethodException e) {
+                throw new IllegalArgumentException("No such property " + cmpFieldName + " defined on bean class " + beanClassName);
+            }
+        }
+
+        this.pkField = cmpFields.get(pkField);
+        if (this.pkField == null) {
+            throw new IllegalArgumentException("No such property " + pkField + " defined on bean class " + beanClassName);
+        }
+
+        cw = new ClassWriter(true);
+    }
+
+    public void addCmrField(CmrField cmrField) {
+        cmrFields.put(cmrField.getName(), cmrField);
+    }
+
+    public byte[] generate() {
+        cw.visit(V1_5, ACC_PUBLIC + ACC_SUPER, implClassName, null, beanClassName, new String[]{"org/apache/openejb/core/cmp/cmp2/Cmp2Entity"});
+
+        // public static Object deploymentInfo;
+        {
+            FieldVisitor fv = cw.visitField(ACC_PUBLIC + ACC_STATIC, "deploymentInfo", "Ljava/lang/Object;", null, null);
+            fv.visitEnd();
+        }
+
+        // private transient boolean deleted;
+        {
+            FieldVisitor fv = cw.visitField(ACC_PRIVATE + ACC_TRANSIENT, "deleted", "Z", null, null);
+            fv.visitEnd();
+        }
+
+        // private ${cmpField.type} ${cmpField.name};
+        for (CmpField cmpField : cmpFields.values()) {
+            createField(cmpField);
+        }
+
+        for (CmrField cmrField : cmrFields.values()) {
+            createCmrFields(cmrField);
+        }
+
+        createConstructor();
+
+        for (CmpField cmpField : cmpFields.values()) {
+            // public ${cmpField.type} get${cmpField.name}() {
+            //     return this.${cmpField.name};
+            // }
+            createGetter(cmpField);
+
+            // public void setId(${cmpField.type} ${cmpField.name}) {
+            //    this.${cmpField.name} = ${cmpField.name};
+            // }
+            createSetter(cmpField);
+        }
+
+        for (CmrField cmrField : cmrFields.values()) {
+            createCmrGetter(cmrField);
+            createCmrSetter(cmrField);
+        }
+
+        createSimplePrimaryKeyGetter(pkField);
+
+        createOpenEJB_deleted();
+
+        createOpenEJB_addCmr();
+
+        createOpenEJB_removeCmr();
+
+        cw.visitEnd();
+
+        return cw.toByteArray();
+    }
+
+    private void createConstructor() {
+        MethodVisitor mv = mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+        mv.visitCode();
+        mv.visitVarInsn(ALOAD, 0);
+        mv.visitMethodInsn(INVOKESPECIAL, beanClassName, "<init>", "()V");
+
+        for (CmrField cmrField : cmrFields.values()) {
+            initCmrFields(mv, cmrField);
+        }
+
+        mv.visitInsn(RETURN);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+    }
+
+    private void createOpenEJB_deleted() {
+        MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "OpenEJB_deleted", "()V", null, null);
+        mv.visitCode();
+
+        // if (deleted) return;
+        mv.visitVarInsn(ALOAD, 0);
+        mv.visitFieldInsn(GETFIELD, implClassName, "deleted", "Z");
+        Label notDeleted = new Label();
+        mv.visitJumpInsn(IFEQ, notDeleted);
+        mv.visitInsn(RETURN);
+        mv.visitLabel(notDeleted);
+
+        // deleted = true;
+        mv.visitVarInsn(ALOAD, 0);
+        mv.visitInsn(ICONST_1);
+        mv.visitFieldInsn(PUTFIELD, implClassName, "deleted", "Z");
+
+        for (CmrField cmrField : cmrFields.values()) {
+            // ${cmrField.accessor}.delete(${cmrField.name});
+            createOpenEJB_deleted(mv, cmrField);
+        }
+
+        // return;
+        mv.visitInsn(RETURN);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+    }
+
+    private void createOpenEJB_addCmr() {
+        MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "OpenEJB_addCmr", "(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;", null, null);
+        mv.visitCode();
+
+        // if (deleted) return null;
+        mv.visitVarInsn(ALOAD, 0);
+        mv.visitFieldInsn(GETFIELD, implClassName, "deleted", "Z");
+        Label notDeleted = new Label();
+        mv.visitJumpInsn(IFEQ, notDeleted);
+        mv.visitInsn(ACONST_NULL);
+        mv.visitInsn(ARETURN);
+        mv.visitLabel(notDeleted);
+
+        for (CmrField cmrField : cmrFields.values()) {
+            // if ("${cmrField.name}".equals(name)) {
+            //     ${cmrField.name}.add((${cmrField.type})value);
+            //     return null;
+            // }
+            //
+            // OR
+            //
+            // if ("${cmrField.name}".equals(name)) {
+            //     Object oldValue = ${cmrField.name};
+            //     ${cmrField.name} = (${cmrField.type}) bean;
+            //     return oldValue;
+            // }
+            createOpenEJB_addCmr(mv, cmrField);
+        }
+
+        // throw new IllegalArgumentException("Unknown cmr field " + name + " on entity bean of type " + getClass().getName());
+        mv.visitTypeInsn(NEW, "java/lang/IllegalArgumentException");
+        mv.visitInsn(DUP);
+        mv.visitTypeInsn(NEW, "java/lang/StringBuilder");
+        mv.visitInsn(DUP);
+        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "()V");
+        mv.visitLdcInsn("Unknown cmr field ");
+        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
+        mv.visitVarInsn(ALOAD, 1);
+        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
+        mv.visitLdcInsn(" on entity bean of type ");
+        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
+        mv.visitVarInsn(ALOAD, 0);
+        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;");
+        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getName", "()Ljava/lang/String;");
+        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
+        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;");
+        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalArgumentException", "<init>", "(Ljava/lang/String;)V");
+        mv.visitInsn(ATHROW);
+
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+    }
+
+    private void createOpenEJB_removeCmr() {
+        MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "OpenEJB_removeCmr", "(Ljava/lang/String;Ljava/lang/Object;)V", null, null);
+        mv.visitCode();
+
+        // if (deleted) return;
+        mv.visitVarInsn(ALOAD, 0);
+        mv.visitFieldInsn(GETFIELD, implClassName, "deleted", "Z");
+        Label notDeleted = new Label();
+        mv.visitJumpInsn(IFEQ, notDeleted);
+        mv.visitInsn(RETURN);
+        mv.visitLabel(notDeleted);
+
+        for (CmrField cmrField : cmrFields.values()) {
+            // if ("${cmrField.name}".equals(name)) {
+            //     ${cmrField.name}.remove(value);
+            //     return;
+            // }
+            //
+            // OR
+            //
+            // if ("${cmrField.name}".equals(name)) {
+            //     ${cmrField.name} = null;
+            //     return;
+            // }
+            createOpenEJB_removeCmr(mv, cmrField);
+        }
+
+        // throw new IllegalArgumentException("Unknown cmr field " + name + " on entity bean of type " + getClass().getName());
+        mv.visitTypeInsn(NEW, "java/lang/IllegalArgumentException");
+        mv.visitInsn(DUP);
+        mv.visitTypeInsn(NEW, "java/lang/StringBuilder");
+        mv.visitInsn(DUP);
+        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "()V");
+        mv.visitLdcInsn("Unknown cmr field ");
+        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
+        mv.visitVarInsn(ALOAD, 1);
+        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
+        mv.visitLdcInsn(" on entity bean of type ");
+        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
+        mv.visitVarInsn(ALOAD, 0);
+        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;");
+        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getName", "()Ljava/lang/String;");
+        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
+        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;");
+        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalArgumentException", "<init>", "(Ljava/lang/String;)V");
+        mv.visitInsn(ATHROW);
+
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+    }
+
+    private void createField(CmpField cmpField) {
+        FieldVisitor fv = cw.visitField(ACC_PRIVATE,
+                cmpField.getName(),
+                cmpField.getDescriptor(),
+                null,
+                null);
+        fv.visitEnd();
+    }
+
+    private void createGetter(CmpField cmpField) {
+        String methodName = getterName(cmpField.getName());
+        MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, methodName, "()" + cmpField.getDescriptor(), null, null);
+        mv.visitVarInsn(ALOAD, 0);
+        mv.visitFieldInsn(GETFIELD, implClassName, cmpField.getName(), cmpField.getDescriptor());
+        mv.visitInsn(cmpField.getType().getOpcode(IRETURN));
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+    }
+
+    private static String getterName(String propertyName) {
+        return "get" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
+    }
+
+    private void createSetter(CmpField cmpField) {
+        String methodName = setterName(cmpField.getName());
+        MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, methodName, "(" + cmpField.getDescriptor() + ")V", null, null);
+        mv.visitVarInsn(ALOAD, 0);
+        mv.visitVarInsn(cmpField.getType().getOpcode(ILOAD), 1);
+        mv.visitFieldInsn(PUTFIELD, implClassName, cmpField.getName(), cmpField.getDescriptor());
+        mv.visitInsn(RETURN);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+    }
+
+    private String setterName(String propertyName) {
+        return "set" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
+    }
+
+    private void createSimplePrimaryKeyGetter(CmpField pkField) {
+        String descriptor = pkField.getType().getDescriptor();
+
+        String methodName = "OpenEJB_getPrimaryKey";
+        MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, methodName, "()Ljava/lang/Object;", null, null);
+        mv.visitVarInsn(ALOAD, 0);
+        mv.visitFieldInsn(GETFIELD, implClassName, pkField.getName(), descriptor);
+        mv.visitInsn(pkField.getType().getOpcode(IRETURN));
+        mv.visitMaxs(0, 0);
+    }
+
+
+    private void createCmrFields(CmrField cmrField) {
+        FieldVisitor fv = cw.visitField(ACC_PRIVATE,
+                cmrField.getName(),
+                cmrField.getDescriptor(),
+                cmrField.getGenericSignature(),
+                null);
+        fv.visitEnd();
+
+        fv = cw.visitField(ACC_PRIVATE + ACC_TRANSIENT,
+                cmrField.getName() + "Cmr",
+                cmrField.getAccessorDescriptor(),
+                cmrField.getAccessorGenericSignature(),
+                null);
+        fv.visitEnd();
+    }
+
+    private void initCmrFields(MethodVisitor mv, CmrField cmrField) {
+        // this.${cmrField.name} = new ${cmrField.initialValueType}();
+        Type initialValueType = cmrField.getInitialValueType();
+        if (initialValueType != null) {
+            mv.visitVarInsn(ALOAD, 0);
+            mv.visitTypeInsn(NEW, initialValueType.getInternalName());
+            mv.visitInsn(DUP);
+            mv.visitMethodInsn(INVOKESPECIAL, initialValueType.getInternalName(), "<init>", "()V");
+            mv.visitFieldInsn(PUTFIELD, implClassName, cmrField.getName(), cmrField.getDescriptor());
+        }
+
+        // this.${cmrField.name}Cmr = new ${cmrField.accessorType}<${cmrField.type}, ${cmrField.proxyType}>(this,
+        //         ${cmrField.name},
+        //         ${cmrField.type},
+        //         ${cmrField.relatedName});
+        mv.visitVarInsn(ALOAD, 0);
+        mv.visitTypeInsn(NEW, cmrField.getAccessorInternalName());
+        mv.visitInsn(DUP);
+
+        // arg0: EntityBean source = this
+        mv.visitVarInsn(ALOAD, 0);
+
+        // arg1: String sourceProperty - "b"
+        mv.visitLdcInsn(cmrField.getName());
+
+        // arg2: Class<Bean> relatedType = BBean_JPA
+        mv.visitLdcInsn(cmrField.getType());
+
+        // arg3: String relatedProperty
+        mv.visitLdcInsn(cmrField.getRelatedName());
+
+        // invoke
+        mv.visitMethodInsn(INVOKESPECIAL,
+                cmrField.getAccessorInternalName(),
+                "<init>",
+                "(Ljavax/ejb/EntityBean;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/String;)V");
+
+        // bCmr = result
+        mv.visitFieldInsn(PUTFIELD,
+                implClassName,
+                cmrField.getName() + "Cmr",
+                cmrField.getAccessorDescriptor());
+    }
+
+    private void createCmrGetter(CmrField cmrField) {
+        String methodName = getterName(cmrField.getName());
+        MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, methodName, "()" + cmrField.getProxyDescriptor(), null, null);
+        mv.visitCode();
+        mv.visitVarInsn(ALOAD, 0);
+        mv.visitFieldInsn(GETFIELD, implClassName, cmrField.getName() + "Cmr", cmrField.getAccessorDescriptor());
+        mv.visitVarInsn(ALOAD, 0);
+        mv.visitFieldInsn(GETFIELD, implClassName, cmrField.getName(), cmrField.getDescriptor());
+        mv.visitMethodInsn(INVOKEVIRTUAL, cmrField.getAccessorInternalName(), "get", cmrField.getCmrStyle().getGetterDescriptor());
+        if (cmrField.getCmrStyle() == CmrStyle.SINGLE) {
+            mv.visitTypeInsn(CHECKCAST, cmrField.getProxyType().getInternalName());
+        }
+        mv.visitInsn(ARETURN);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+    }
+
+    private void createCmrSetter(CmrField cmrField) {
+        String methodName = setterName(cmrField.getName());
+        MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, methodName, "(" + cmrField.getProxyDescriptor() + ")V", null, null);
+        mv.visitCode();
+        if (cmrField.getCmrStyle() != CmrStyle.SINGLE) {
+            mv.visitVarInsn(ALOAD, 0);
+            mv.visitFieldInsn(GETFIELD, implClassName, cmrField.getName() + "Cmr", cmrField.getAccessorDescriptor());
+            mv.visitVarInsn(ALOAD, 0);
+            mv.visitFieldInsn(GETFIELD, implClassName, cmrField.getName(), cmrField.getDescriptor());
+            mv.visitVarInsn(ALOAD, 1);
+            mv.visitMethodInsn(INVOKEVIRTUAL, cmrField.getAccessorInternalName(), "set", cmrField.getCmrStyle().getSetterDescriptor());
+            mv.visitInsn(RETURN);
+        } else {
+            mv.visitVarInsn(ALOAD, 0);
+            mv.visitVarInsn(ALOAD, 0);
+            mv.visitFieldInsn(GETFIELD, implClassName, cmrField.getName() + "Cmr", cmrField.getAccessorDescriptor());
+            mv.visitVarInsn(ALOAD, 0);
+            mv.visitFieldInsn(GETFIELD, implClassName, cmrField.getName(), cmrField.getDescriptor());
+            mv.visitVarInsn(ALOAD, 1);
+            mv.visitMethodInsn(INVOKEVIRTUAL, cmrField.getAccessorInternalName(), "set", cmrField.getCmrStyle().getSetterDescriptor());
+            mv.visitTypeInsn(CHECKCAST, cmrField.getType().getInternalName());
+            mv.visitFieldInsn(PUTFIELD, implClassName, cmrField.getName(), cmrField.getDescriptor());
+            mv.visitInsn(RETURN);
+        }
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+    }
+
+    private void createOpenEJB_deleted(MethodVisitor mv, CmrField cmrField) {
+        mv.visitVarInsn(ALOAD, 0);
+        mv.visitFieldInsn(GETFIELD, implClassName, cmrField.getName() + "Cmr", cmrField.getAccessorDescriptor());
+        mv.visitVarInsn(ALOAD, 0);
+        mv.visitFieldInsn(GETFIELD, implClassName, cmrField.getName(), cmrField.getDescriptor());
+        mv.visitMethodInsn(INVOKEVIRTUAL, cmrField.getAccessorInternalName(), "deleted", cmrField.getCmrStyle().getDeletedDescriptor());
+    }
+
+    private void createOpenEJB_addCmr(MethodVisitor mv, CmrField cmrField) {
+        // if (${cmrField.name}.equals(arg1))
+        mv.visitLdcInsn(cmrField.getName());
+        mv.visitVarInsn(ALOAD, 1);
+        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z");
+        // if not equal jump to end
+        Label end = new Label();
+        mv.visitJumpInsn(IFEQ, end);
+
+        if (cmrField.getCmrStyle() != CmrStyle.SINGLE) {
+            // ${cmrField.name}.add(arg2)
+            mv.visitVarInsn(ALOAD, 0);
+            mv.visitFieldInsn(GETFIELD, implClassName, cmrField.getName(), cmrField.getDescriptor());
+            mv.visitVarInsn(ALOAD, 2);
+            mv.visitTypeInsn(CHECKCAST, cmrField.getType().getInternalName());
+            mv.visitMethodInsn(INVOKEINTERFACE,
+                    cmrField.getCmrStyle().getCollectionType().getInternalName(),
+                    "add",
+                    "(Ljava/lang/Object;)Z");
+            mv.visitInsn(POP);
+
+            // return null;
+            mv.visitInsn(ACONST_NULL);
+            mv.visitInsn(ARETURN);
+        } else {
+            // push: this.${cmrField.name};
+            mv.visitVarInsn(ALOAD, 0);
+            mv.visitFieldInsn(GETFIELD, implClassName, cmrField.getName(), cmrField.getDescriptor());
+
+            // this.${cmrField.name} = (${cmrField.type}) bean;
+            mv.visitVarInsn(ALOAD, 0);
+            mv.visitVarInsn(ALOAD, 2);
+            mv.visitTypeInsn(CHECKCAST, cmrField.getType().getInternalName());
+            mv.visitFieldInsn(PUTFIELD, implClassName, cmrField.getName(), cmrField.getDescriptor());
+
+            // return pushed value above
+            mv.visitInsn(ARETURN);
+        }
+
+        // end of if statement
+        mv.visitLabel(end);
+    }
+
+    private void createOpenEJB_removeCmr(MethodVisitor mv, CmrField cmrField) {
+        // if (${cmrField.name}.equals(arg1))
+        mv.visitLdcInsn(cmrField.getName());
+        mv.visitVarInsn(ALOAD, 1);
+        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z");
+        // if not equal jump to end
+        Label end = new Label();
+        mv.visitJumpInsn(IFEQ, end);
+
+        if (cmrField.getCmrStyle() != CmrStyle.SINGLE) {
+            // ${cmrField.name}.remove(arg2)
+            mv.visitVarInsn(ALOAD, 0);
+            mv.visitFieldInsn(GETFIELD, implClassName, cmrField.getName(), cmrField.getDescriptor());
+            mv.visitVarInsn(ALOAD, 2);
+            mv.visitMethodInsn(INVOKEINTERFACE,
+                    cmrField.getCmrStyle().getCollectionType().getInternalName(),
+                    "remove",
+                    "(Ljava/lang/Object;)Z");
+            mv.visitInsn(POP);
+
+            // return;
+            mv.visitInsn(RETURN);
+        } else {
+            // this.${cmrField.name} = null;
+            mv.visitVarInsn(ALOAD, 0);
+            mv.visitInsn(ACONST_NULL);
+            mv.visitFieldInsn(PUTFIELD, implClassName, cmrField.getName(), cmrField.getDescriptor());
+
+            // return;
+            mv.visitInsn(RETURN);
+        }
+
+        // end of if statement
+        mv.visitLabel(end);
+    }
+}

Added: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/Cmp2KeyGenerator.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/Cmp2KeyGenerator.java?view=auto&rev=492404
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/Cmp2KeyGenerator.java (added)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/Cmp2KeyGenerator.java Wed Jan  3 20:23:04 2007
@@ -0,0 +1,30 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openejb.core.cmp.cmp2;
+
+import javax.ejb.EntityBean;
+
+import org.apache.openejb.core.cmp.KeyGenerator;
+
+public class Cmp2KeyGenerator implements KeyGenerator {
+    public Object getPrimaryKey(EntityBean entity) {
+        Cmp2Entity cmp2Entity = (Cmp2Entity) entity;
+        Object primaryKey = cmp2Entity.OpenEJB_getPrimaryKey();
+        return primaryKey;
+    }
+}

Copied: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/Cmp2Util.java (from r491148, incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/CmpUtil.java)
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/Cmp2Util.java?view=diff&rev=492404&p1=incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/CmpUtil.java&r1=491148&p2=incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/Cmp2Util.java&r2=492404
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/CmpUtil.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/Cmp2Util.java Wed Jan  3 20:23:04 2007
@@ -15,13 +15,14 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
-package org.apache.openejb.core.cmp;
+package org.apache.openejb.core.cmp.cmp2;
 
 import org.apache.openejb.core.ivm.EjbObjectProxyHandler;
 import org.apache.openejb.core.CoreDeploymentInfo;
+import org.apache.openejb.core.cmp.CmpContainer;
+import org.apache.openejb.core.cmp.KeyGenerator;
 import org.apache.openejb.core.entity.EntityEjbHomeHandler;
 import org.apache.openejb.util.proxy.ProxyManager;
-import org.apache.openejb.alt.containers.castor_cmp11.KeyGenerator;
 import org.apache.openejb.ProxyInfo;
 
 import javax.ejb.EJBLocalObject;
@@ -29,7 +30,7 @@
 import javax.ejb.EJBLocalHome;
 import java.lang.reflect.Field;
 
-public class CmpUtil {
+public class Cmp2Util {
     public static Object getPrimaryKey(CoreDeploymentInfo deploymentInfo, EntityBean entity){
         if (entity == null) return null;
 
@@ -39,7 +40,7 @@
         return primaryKey;
     }
 
-    public static EntityBean getEntityBean(EJBLocalObject proxy) {
+    public static <Bean extends EntityBean> Bean getEntityBean(EJBLocalObject proxy) {
         if (proxy == null) return null;
 
         EjbObjectProxyHandler handler = (EjbObjectProxyHandler) ProxyManager.getInvocationHandler(proxy);
@@ -50,11 +51,11 @@
             throw new IllegalArgumentException("Proxy is not connected to a CMP container but is conect to " + handler.container.getClass().getName());
         }
         CmpContainer container = (CmpContainer) handler.container;
-        EntityBean entity = (EntityBean) container.getEjbInstance(handler.deploymentInfo, handler.primaryKey);
+        Bean entity = (Bean) container.getEjbInstance(handler.deploymentInfo, handler.primaryKey);
         return entity;
     }
 
-    public static EJBLocalObject getEjbProxy(CoreDeploymentInfo deploymentInfo, EntityBean entity){
+    public static <Proxy extends EJBLocalObject> Proxy getEjbProxy(CoreDeploymentInfo deploymentInfo, EntityBean entity){
         if (entity == null) return null;
 
         // build the primary key
@@ -77,7 +78,7 @@
         EntityEjbHomeHandler handler = (EntityEjbHomeHandler) ProxyManager.getInvocationHandler(homeProxy);
 
         // create the proxy
-        EJBLocalObject proxy = (EJBLocalObject) handler.createProxy(proxyInfo);
+        Proxy proxy = (Proxy) handler.createProxy(proxyInfo);
         return proxy;
     }
 

Added: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/CmpField.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/CmpField.java?view=auto&rev=492404
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/CmpField.java (added)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/CmpField.java Wed Jan  3 20:23:04 2007
@@ -0,0 +1,42 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openejb.core.cmp.cmp2;
+
+import org.objectweb.asm.Type;
+
+public class CmpField {
+    private final String name;
+    private final Type type;
+
+    public CmpField(String name, Type type) {
+        this.name = name;
+        this.type = type;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public Type getType() {
+        return type;
+    }
+
+    public String getDescriptor() {
+        return type.getDescriptor();
+    }
+}

Added: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/CmrField.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/CmrField.java?view=auto&rev=492404
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/CmrField.java (added)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/CmrField.java Wed Jan  3 20:23:04 2007
@@ -0,0 +1,130 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openejb.core.cmp.cmp2;
+
+import org.objectweb.asm.Type;
+
+public class CmrField {
+    private final String name;
+    private final CmrStyle cmrStyle;
+    private final Type type;
+    private final Type proxyType;
+    private final String relatedName;
+
+    public CmrField(String name, CmrStyle cmrStyle, Type type, Type proxyType, String relatedName) {
+        this.name = name;
+        this.cmrStyle = cmrStyle;
+        this.type = type;
+        this.proxyType = proxyType;
+        this.relatedName = relatedName;
+    }
+
+    public CmrField(String fieldName, String fieldType, String ejbClass, String local, String relatedName) {
+        this.name = fieldName;
+        if (fieldType == null) {
+            cmrStyle = CmrStyle.SINGLE;
+        } else if ("java.util.Collection".equals(fieldType)) {
+            cmrStyle = CmrStyle.COLLECTION;
+        } else if ("java.util.Set".equals(fieldType)) {
+            cmrStyle = CmrStyle.SET;
+        } else {
+            throw new IllegalArgumentException("Unsupported fieldType " + fieldType);
+        }
+        type = Type.getType("L" + ejbClass.replace('.', '/') + "_JPA;");
+        proxyType = Type.getType("L" + local.replace('.', '/') + ";");
+        this.relatedName = relatedName;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public CmrStyle getCmrStyle() {
+        return cmrStyle;
+    }
+
+    public Type getType() {
+        return type;
+    }
+
+    public Type getProxyType() {
+        return proxyType;
+    }
+
+    public Type getInitialValueType() {
+        return cmrStyle.getIntiCollectionType();
+    }
+
+    public String getRelatedName() {
+        return relatedName;
+    }
+
+    public String getDescriptor() {
+        Type collectionType = cmrStyle.getCollectionType();
+        if (collectionType == null) {
+            return type.getDescriptor();
+        }
+        return collectionType.getDescriptor();
+    }
+
+    public String getGenericSignature() {
+        Type collectionType = cmrStyle.getCollectionType();
+        if (collectionType == null) {
+            return null;
+        }
+        return createSignature(collectionType, type);
+    }
+
+    public String getProxyDescriptor() {
+        Type collectionType = cmrStyle.getCollectionType();
+        if (collectionType == null) {
+            return proxyType.getDescriptor();
+        }
+        return collectionType.getDescriptor();
+    }
+
+    public String getAccessorInternalName() {
+        return cmrStyle.getAccessorType().getInternalName();
+    }
+
+    public String getAccessorDescriptor() {
+        return cmrStyle.getAccessorType().getDescriptor();
+    }
+
+    public String getAccessorGenericSignature() {
+        Type collectionType = cmrStyle.getCollectionType();
+        if (collectionType == null) {
+            return null;
+        }
+        return createSignature(cmrStyle.getAccessorType(), type, proxyType);
+    }
+
+    private static String createSignature(Type type, Type... genericTypes) {
+        StringBuilder builder = new StringBuilder();
+        builder.append("L").append(type.getInternalName());
+        if (genericTypes.length > 0) {
+            builder.append("<");
+            for (Type genericType : genericTypes) {
+                builder.append(genericType.getDescriptor());
+            }
+            builder.append(">");
+        }
+        builder.append(";");
+        return builder.toString();
+    }
+}

Copied: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/CmrSet.java (from r491148, incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/CmrSet.java)
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/CmrSet.java?view=diff&rev=492404&p1=incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/CmrSet.java&r1=491148&p2=incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/CmrSet.java&r2=492404
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/CmrSet.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/CmrSet.java Wed Jan  3 20:23:04 2007
@@ -15,10 +15,9 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
-package org.apache.openejb.core.cmp.jpa;
+package org.apache.openejb.core.cmp.cmp2;
 
 import org.apache.openejb.core.CoreDeploymentInfo;
-import org.apache.openejb.core.cmp.CmpUtil;
 
 import javax.ejb.EJBException;
 import javax.ejb.EJBLocalObject;
@@ -32,26 +31,18 @@
 
 public class CmrSet<Bean extends EntityBean, Proxy extends EJBLocalObject> extends AbstractSet<Proxy> {
     private final EntityBean source;
-    private final Class<? extends EntityBean> sourceType;
     private final String sourceProperty;
-    private final CmpWrapperFactory sourceWrapperFactory;
     private final CoreDeploymentInfo relatedInfo;
-    private final Class<Bean> relatedType;
     private final String relatedProperty;
-    private final CmpWrapperFactory relatedWrapperFactory;
     private final CollectionRef<Bean> relatedBeanRef;
     private Class relatedLocal;
 
-    public CmrSet(EntityBean source, String sourceProperty, CmpWrapperFactory sourceWrapperFactory, CoreDeploymentInfo relatedInfo, Class<Bean> relatedType, String relatedProperty, CmpWrapperFactory relatedWrapperFactory, CollectionRef<Bean> relatedBeanRef) {
+    public CmrSet(EntityBean source, String sourceProperty, CoreDeploymentInfo relatedInfo, String relatedProperty, CollectionRef<Bean> relatedBeanRef) {
         this.source = source;
         this.sourceProperty = sourceProperty;
-        this.sourceWrapperFactory = sourceWrapperFactory;
         this.relatedInfo = relatedInfo;
-        this.relatedType = relatedType;
         this.relatedProperty = relatedProperty;
-        this.relatedWrapperFactory = relatedWrapperFactory;
         this.relatedBeanRef = relatedBeanRef;
-        this.sourceType = source.getClass();
 
         relatedLocal = relatedInfo.getLocalInterface();
     }
@@ -73,10 +64,10 @@
     }
 
     public boolean addAll(Collection<? extends Proxy> c) {
-        Set entityBeans = getEntityBeans(c, relatedLocal);
+        Set<Bean> entityBeans = getEntityBeans(c, relatedLocal);
         boolean changed = false;
-        for (Iterator iterator = entityBeans.iterator(); iterator.hasNext();) {
-            Bean bean = (Bean) iterator.next();
+        for (Iterator<Bean> iterator = entityBeans.iterator(); iterator.hasNext();) {
+            Bean bean = iterator.next();
             changed = add(bean) || changed;
         }
         return changed;
@@ -100,12 +91,12 @@
         boolean changed = getRelatedBeans(true).add(newEntity);
         if (changed) {
             // set the back reference in the new related bean
-            Object oldBackRef = getCmpWrapper(newEntity).addCmr(relatedProperty, source);
+            Object oldBackRef = toCmp2Entity(newEntity).OpenEJB_addCmr(relatedProperty, source);
 
             // if the new related beas was related to another bean, we need
             // to clear the back reference in that old bean
             if (oldBackRef != null) {
-                getCmpWrapper(oldBackRef).removeCmr(sourceProperty, newEntity);
+                toCmp2Entity(oldBackRef).OpenEJB_removeCmr(sourceProperty, newEntity);
             }
         }
         return changed;
@@ -119,7 +110,7 @@
         Bean entity = getEntityBean((EJBLocalObject) o);
         boolean changed = entity != null && getRelatedBeans(false).remove(entity);
         if (changed) {
-            getCmpWrapper(entity).removeCmr(relatedProperty, source);
+            toCmp2Entity(entity).OpenEJB_removeCmr(relatedProperty, source);
         }
         return changed;
     }
@@ -132,7 +123,7 @@
             Bean entity = iterator.next();
             if (!entityBeans.contains(entity)) {
                 iterator.remove();
-                getCmpWrapper(entity).removeCmr(relatedProperty, source);
+                toCmp2Entity(entity).OpenEJB_removeCmr(relatedProperty, source);
                 changed = true;
             }
         }
@@ -155,7 +146,7 @@
 
             public void remove() {
                 iterator.remove();
-                getCmpWrapper(currentEntity).removeCmr(relatedProperty, source);
+                toCmp2Entity(currentEntity).OpenEJB_removeCmr(relatedProperty, source);
             }
         };
     }
@@ -163,27 +154,27 @@
     private Proxy getEjbProxy(Bean entity) throws EJBException {
         if (entity == null) return null;
 
-        Proxy ejbProxy = (Proxy) CmpUtil.getEjbProxy(relatedInfo, entity);
+        Proxy ejbProxy = Cmp2Util.<Proxy>getEjbProxy(relatedInfo, entity);
         return ejbProxy;
     }
 
     private Bean getEntityBean(EJBLocalObject proxy) {
         if (proxy == null) return null;
 
-        Bean bean = (Bean) CmpUtil.getEntityBean(proxy);
+        Bean bean = Cmp2Util.<Bean>getEntityBean(proxy);
         return bean;
     }
 
-    private static Set<Object> getEntityBeans(Collection<?> proxies, Class type) {
+    private static <Bean extends EntityBean> Set<Bean> getEntityBeans(Collection<?> proxies, Class type) {
         if (proxies == null) return null;
 
-        Set<Object> entities = new HashSet<Object>();
+        Set<Bean> entities = new HashSet<Bean>();
         for (Object value : proxies) {
             if (type != null && !type.isInstance(value)) {
                 throw new IllegalArgumentException("Object is not an instance of " + type.getName() +
                                     ": " + (value == null ? "null" : value.getClass().getName()));
             }
-            EntityBean entity = CmpUtil.getEntityBean((EJBLocalObject) value);
+            Bean entity = Cmp2Util.<Bean>getEntityBean((EJBLocalObject) value);
             if (entity == null) {
                 throw new IllegalArgumentException("Entity has been deleted");
             }
@@ -192,14 +183,8 @@
         return entities;
     }
 
-    private CmpWrapper getCmpWrapper(Object object) {
-        if (object == null) return null;
-        if (sourceType.isInstance(object)) {
-            return sourceWrapperFactory.createCmpEntityBean(object);
-        } else if (relatedType.isInstance(object)) {
-            return relatedWrapperFactory.createCmpEntityBean(object);
-        }
-        throw new IllegalArgumentException("Unknown cmp bean type " + object.getClass().getName());
+    private Cmp2Entity toCmp2Entity(Object object) {
+        return (Cmp2Entity) object;
     }
 
     private Collection<Bean> getRelatedBeans(boolean mustExist) {

Added: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/CmrStyle.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/CmrStyle.java?view=auto&rev=492404
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/CmrStyle.java (added)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/CmrStyle.java Wed Jan  3 20:23:04 2007
@@ -0,0 +1,109 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openejb.core.cmp.cmp2;
+
+import java.util.Set;
+import java.util.HashSet;
+import java.lang.reflect.Method;
+
+import org.objectweb.asm.Type;
+
+public enum CmrStyle {
+    SINGLE(SingleValuedCmr.class, null, null),
+    COLLECTION(SetValuedCmr.class, Set.class, HashSet.class),
+    SET(SetValuedCmr.class, Set.class, HashSet.class);
+
+    private final Type accessorType;
+    private final Type collectionType;
+    private final Type intiCollectionType;
+    private final String getterDescriptor;
+    private final String setterDescriptor;
+    private final String deletedDescriptor;
+
+    CmrStyle(Class accessorClass, Class collectionClass, Class initCollectionClass) {
+        this.accessorType = Type.getType(accessorClass);
+        if (collectionClass != null) {
+            this.collectionType = Type.getType(collectionClass);
+            this.intiCollectionType = Type.getType(initCollectionClass);
+        } else {
+            this.collectionType = null;
+            this.intiCollectionType = null;
+        }
+
+        String getterDescriptor = null;
+        String setterDescriptor = null;
+        String deletedDescriptor = null;
+        for (Method method : accessorClass.getMethods()) {
+            if ("get".equals(method.getName())) {
+                getterDescriptor = Type.getMethodDescriptor(method);
+            }
+            if ("set".equals(method.getName())) {
+                setterDescriptor = Type.getMethodDescriptor(method);
+            }
+            if ("deleted".equals(method.getName())) {
+                deletedDescriptor = Type.getMethodDescriptor(method);
+            }
+        }
+        if (getterDescriptor == null) {
+            throw new AssertionError("No get method found in cmr accessor class " + accessorClass.getName());
+        }
+        if (setterDescriptor == null) {
+            throw new AssertionError("No set method found in cmr accessor class " + accessorClass.getName());
+        }
+        if (deletedDescriptor == null) {
+            throw new AssertionError("No deleted method found in cmr accessor class " + accessorClass.getName());
+        }
+        this.getterDescriptor = getterDescriptor;
+        this.setterDescriptor = setterDescriptor;
+        this.deletedDescriptor = deletedDescriptor;
+    }
+
+    public String getCmrFieldDescriptor(Type relatedType) {
+        String relatedDescriptor = relatedType.getDescriptor();
+        if (collectionType != null) {
+            return collectionType.getDescriptor() +
+                    "<" + relatedDescriptor + ">";
+        } else {
+            return relatedDescriptor;
+        }
+    }
+
+    public Type getAccessorType() {
+        return accessorType;
+    }
+
+    public Type getCollectionType() {
+        return collectionType;
+    }
+
+    public Type getIntiCollectionType() {
+        return intiCollectionType;
+    }
+
+    public String getGetterDescriptor() {
+        return getterDescriptor;
+    }
+
+    public String getSetterDescriptor() {
+        return setterDescriptor;
+    }
+
+    public String getDeletedDescriptor() {
+        return deletedDescriptor;
+    }
+}

Copied: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/CollectionRef.java (from r491148, incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/CollectionRef.java)
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/CollectionRef.java?view=diff&rev=492404&p1=incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/CollectionRef.java&r1=491148&p2=incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/CollectionRef.java&r2=492404
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/CollectionRef.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/CollectionRef.java Wed Jan  3 20:23:04 2007
@@ -15,11 +15,11 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
-package org.apache.openejb.core.cmp.jpa;
+package org.apache.openejb.core.cmp.cmp2;
 
 import java.util.Collection;
 
-public class CollectionRef<E> {
+public final class CollectionRef<E> {
     private Collection<E> collection;
 
     public Collection<E> get() {

Copied: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/SetValuedCmr.java (from r491148, incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/MultiValuedCmr.java)
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/SetValuedCmr.java?view=diff&rev=492404&p1=incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/MultiValuedCmr.java&r1=491148&p2=incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/SetValuedCmr.java&r2=492404
==============================================================================
--- incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/MultiValuedCmr.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/SetValuedCmr.java Wed Jan  3 20:23:04 2007
@@ -15,16 +15,93 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
-package org.apache.openejb.test.entity;
+package org.apache.openejb.core.cmp.cmp2;
 
 import javax.ejb.EJBLocalObject;
 import javax.ejb.EntityBean;
 import java.util.Set;
 
-public interface MultiValuedCmr<Bean extends EntityBean, Proxy extends EJBLocalObject> {
-    Set<Proxy> get(Set<Bean> others);
+import org.apache.openejb.core.CoreDeploymentInfo;
 
-    void set(Set<Bean> oldValue, Set<Proxy> newValue);
+//
+// WARNING: Do not refactor this class.  It is used by the Cmp2Generator.
+//
+public class SetValuedCmr<Bean extends EntityBean, Proxy extends EJBLocalObject> {
+    private final EntityBean source;
+    private final String sourceProperty;
+    private final String relatedProperty;
+    private final CoreDeploymentInfo relatedInfo;
+    private final CollectionRef<Bean> collectionRef = new CollectionRef<Bean>();
 
-    void deleted(Set<Bean> relatedBeans);
+    public SetValuedCmr(EntityBean source, String sourceProperty, Class<Bean> relatedType, String relatedProperty) {
+        if (source == null) {
+            throw new NullPointerException("source is null");
+        }
+        if (sourceProperty == null) {
+            throw new NullPointerException("sourceProperty is null");
+        }
+        if (relatedType == null) {
+            throw new NullPointerException("relatedType is null");
+        }
+        if (relatedProperty == null) {
+            throw new NullPointerException("relatedProperty is null");
+        }
+        this.source = source;
+        this.sourceProperty = sourceProperty;
+        this.relatedProperty = relatedProperty;
+
+        this.relatedInfo = Cmp2Util.getDeploymentInfo(relatedType);
+    }
+
+    public Set<Proxy> get(Set<Bean> others) {
+        if (others == null) {
+            throw new NullPointerException("others is null");
+        }
+        collectionRef.set(others);
+        Set<Proxy> cmrSet = new CmrSet<Bean, Proxy>(source, sourceProperty, relatedInfo, relatedProperty, collectionRef);
+        return cmrSet;
+    }
+
+    public void set(Set<Bean> relatedBeans, Set<Proxy> newProxies) {
+        // clear back reference in the old related beans
+        for (Bean oldBean : relatedBeans) {
+            if (oldBean != null) {
+                toCmp2Entity(oldBean).OpenEJB_removeCmr(relatedProperty, source);
+            }
+        }
+        relatedBeans.clear();
+
+        for (Proxy newProxy : newProxies) {
+            Bean newBean = Cmp2Util.<Bean>getEntityBean(newProxy);
+
+            if (newProxy != null) {
+                // set the back reference in the new related bean
+                Object oldBackRef = toCmp2Entity(newBean).OpenEJB_addCmr(relatedProperty, source);
+
+                // add the bean to our value map
+                relatedBeans.add(newBean);
+
+                // if the new related beas was related to another bean, we need
+                // to clear the back reference in that old bean
+                if (oldBackRef != null) {
+                    toCmp2Entity(oldBackRef).OpenEJB_removeCmr(sourceProperty, newBean);
+                }
+            }
+        }
+    }
+
+    public void deleted(Set<Bean> relatedBeans) {
+        collectionRef.set(null);
+
+        // clear back reference in the old related beans
+        for (Bean oldBean : relatedBeans) {
+            if (oldBean != null) {
+                toCmp2Entity(oldBean).OpenEJB_removeCmr(relatedProperty, source);
+            }
+        }
+    }
+
+    private Cmp2Entity toCmp2Entity(Object object) {
+        return (Cmp2Entity) object;
+    }
 }

Copied: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/SingleValuedCmr.java (from r491148, incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/SingleValuedCmr.java)
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/SingleValuedCmr.java?view=diff&rev=492404&p1=incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/SingleValuedCmr.java&r1=491148&p2=incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/SingleValuedCmr.java&r2=492404
==============================================================================
--- incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/SingleValuedCmr.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/SingleValuedCmr.java Wed Jan  3 20:23:04 2007
@@ -15,13 +15,68 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
-package org.apache.openejb.test.entity;
+package org.apache.openejb.core.cmp.cmp2;
+
+import org.apache.openejb.core.CoreDeploymentInfo;
 
-import javax.ejb.EntityBean;
-import javax.ejb.EJBLocalObject;
 import javax.ejb.EJBException;
+import javax.ejb.EJBLocalObject;
+import javax.ejb.EntityBean;
+
+//
+// WARNING: Do not refactor this class.  It is used by the Cmp2Generator.
+//
+public class SingleValuedCmr<Bean extends EntityBean, Proxy extends EJBLocalObject> {
+    private final EntityBean source;
+    private final String sourceProperty;
+    private final String relatedProperty;
+    private final CoreDeploymentInfo relatedInfo;
+
+    public SingleValuedCmr(EntityBean source, String sourceProperty, Class<Bean> relatedType, String relatedProperty) {
+        if (source == null) throw new NullPointerException("source is null");
+        if (sourceProperty == null) throw new NullPointerException("sourceProperty is null");
+        if (relatedType == null) throw new NullPointerException("relatedType is null");
+        if (relatedProperty == null) throw new NullPointerException("relatedProperty is null");
+        this.source = source;
+        this.sourceProperty = sourceProperty;
+        this.relatedProperty = relatedProperty;
+
+        this.relatedInfo = Cmp2Util.getDeploymentInfo(relatedType);
+    }
+
+    public Proxy get(Bean entity) throws EJBException {
+        if (entity == null) return null;
+
+        Proxy ejbProxy = Cmp2Util.<Proxy>getEjbProxy(relatedInfo, entity);
+        return ejbProxy;
+    }
+
+    public void deleted(Bean oldBean) throws EJBException {
+        set(oldBean, null);
+    }
+
+    public Bean set(Bean oldBean, Proxy newValue) throws EJBException {
+        Bean newBean = Cmp2Util.<Bean>getEntityBean(newValue);
+
+        // clear back reference in the old related bean
+        if (oldBean != null) {
+            toCmp2Entity(oldBean).OpenEJB_removeCmr(relatedProperty, source);
+        }
+
+        if (newValue != null) {
+            // set the back reference in the new related bean
+            Object oldBackRef = toCmp2Entity(newBean).OpenEJB_addCmr(relatedProperty, source);
+
+            // if the new related beas was related to another bean, we need
+            // to clear the back reference in that old bean
+            if (oldBackRef != null) {
+                toCmp2Entity(oldBackRef).OpenEJB_removeCmr(sourceProperty, newBean);
+            }
+        }
+        return newBean;
+    }
 
-public interface SingleValuedCmr<Bean extends EntityBean, Proxy extends EJBLocalObject> {
-    public Proxy get(Bean entity) throws EJBException;
-    public Bean set(Bean oldValue, Proxy newValue) throws EJBException;
-}
\ No newline at end of file
+    private Cmp2Entity toCmp2Entity(Object object) {
+        return (Cmp2Entity) object;
+    }
+}

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/jpa/JpaCmpEngine.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/jpa/JpaCmpEngine.java?view=diff&rev=492404&r1=492403&r2=492404
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/jpa/JpaCmpEngine.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/jpa/JpaCmpEngine.java Wed Jan  3 20:23:04 2007
@@ -20,6 +20,8 @@
 import java.util.List;
 import java.util.Map;
 import java.util.WeakHashMap;
+import java.util.Set;
+import java.util.HashSet;
 import javax.ejb.CreateException;
 import javax.ejb.EJBObject;
 import javax.ejb.EntityBean;
@@ -32,13 +34,15 @@
 import javax.transaction.Transaction;
 import javax.transaction.TransactionManager;
 
-import org.apache.openejb.SystemException;
-import org.apache.openejb.alt.containers.castor_cmp11.KeyGenerator;
-import org.apache.openejb.alt.containers.castor_cmp11.KeyGeneratorFactory;
+import org.apache.openejb.OpenEJBException;
+import org.apache.openejb.core.cmp.KeyGenerator;
 import org.apache.openejb.core.CoreDeploymentInfo;
 import org.apache.openejb.core.ThreadContext;
 import org.apache.openejb.core.cmp.CmpCallback;
 import org.apache.openejb.core.cmp.CmpEngine;
+import org.apache.openejb.core.cmp.SimpleKeyGenerator;
+import org.apache.openejb.core.cmp.ComplexKeyGenerator;
+import org.apache.openejb.core.cmp.cmp2.Cmp2KeyGenerator;
 import org.apache.openejb.util.Logger;
 import org.apache.openjpa.event.AbstractLifecycleListener;
 import org.apache.openjpa.event.LifecycleEvent;
@@ -53,12 +57,32 @@
 
     private final Map<Transaction, EntityManager> transactionData = new WeakHashMap<Transaction, EntityManager>();
 
+    private final ThreadLocal<Set<EntityBean>> creating = new ThreadLocal<Set<EntityBean>>() {
+        protected Set<EntityBean> initialValue() {
+            return new HashSet<EntityBean>();
+        }
+    };
+
     public JpaCmpEngine(CmpCallback cmpCallback, TransactionManager transactionManager, String connectorName, ClassLoader classLoader) {
         this.cmpCallback = cmpCallback;
         this.transactionManager = transactionManager;
     }
 
-    public void deploy(CoreDeploymentInfo deploymentInfo) throws SystemException {
+    public void deploy(CoreDeploymentInfo deploymentInfo) throws OpenEJBException {
+        Class beanClass = deploymentInfo.getBeanClass();
+        if (deploymentInfo.isCmp2()) {
+            String beanClassName = beanClass.getName();
+            String cmpBeanImplName = beanClassName + "_JPA";
+            ClassLoader classLoader = deploymentInfo.getClassLoader();
+            try {
+                Class<?> cmpBeanImpl = classLoader.loadClass(cmpBeanImplName);
+                deploymentInfo.setCmpBeanImpl(cmpBeanImpl);
+            } catch (ClassNotFoundException e) {
+                throw new OpenEJBException("CMP 2.x implementation class not found " + cmpBeanImplName);
+            }
+        } else {
+            deploymentInfo.setCmpBeanImpl(beanClass);
+        }
         configureKeyGenerator(deploymentInfo);
     }
 
@@ -88,9 +112,14 @@
         EntityManager entityManager = getEntityManager(deploymentInfo);
 
         // TODO verify that extract primary key requires a flush followed by a merge
-        entityManager.persist(bean);
-        entityManager.flush();
-        bean = entityManager.merge(bean);
+        creating.get().add(bean);
+        try {
+            entityManager.persist(bean);
+            entityManager.flush();
+            bean = entityManager.merge(bean);
+        } finally {
+            creating.get().remove(bean);
+        }
 
         // extract the primary key from the bean
         KeyGenerator kg = deploymentInfo.getKeyGenerator();
@@ -101,7 +130,7 @@
 
     public Object loadBean(ThreadContext callContext, Object primaryKey) {
         CoreDeploymentInfo deploymentInfo = callContext.getDeploymentInfo();
-        Class<?> beanClass = deploymentInfo.getBeanClass();
+        Class<?> beanClass = deploymentInfo.getCmpBeanImpl();
         EntityManager entityManager = getEntityManager(deploymentInfo);
         Object bean = entityManager.find(beanClass, primaryKey);
         return bean;
@@ -109,7 +138,7 @@
 
     public void removeBean(ThreadContext callContext) {
         CoreDeploymentInfo deploymentInfo = callContext.getDeploymentInfo();
-        Class<?> beanClass = deploymentInfo.getBeanClass();
+        Class<?> beanClass = deploymentInfo.getCmpBeanImpl();
 
         EntityManager entityManager = getEntityManager(deploymentInfo);
         Object bean = entityManager.find(beanClass, callContext.getPrimaryKey());
@@ -153,13 +182,17 @@
         return results;
     }
 
-    private void configureKeyGenerator(CoreDeploymentInfo di) throws SystemException {
-        try {
-            KeyGenerator kg = KeyGeneratorFactory.createKeyGenerator(di);
-            di.setKeyGenerator(kg);
-        } catch (Exception e) {
-            logger.error("Unable to create KeyGenerator for deployment id = " + di.getDeploymentID(), e);
-            throw new SystemException("Unable to create KeyGenerator for deployment id = " + di.getDeploymentID(), e);
+    private void configureKeyGenerator(CoreDeploymentInfo di) throws OpenEJBException {
+        if (di.isCmp2()) {
+            di.setKeyGenerator(new Cmp2KeyGenerator());
+        } else {
+            String primaryKeyField = di.getPrimaryKeyField();
+            Class cmpBeanImpl = di.getCmpBeanImpl();
+            if (primaryKeyField != null) {
+                di.setKeyGenerator(new SimpleKeyGenerator(cmpBeanImpl, primaryKeyField));
+            } else {
+                di.setKeyGenerator(new ComplexKeyGenerator(cmpBeanImpl, di.getPrimaryKeyClass()));
+            }
         }
     }
 
@@ -242,8 +275,10 @@
 
         public void beforeStore(LifecycleEvent lifecycleEvent) {
             eventOccurred(lifecycleEvent);
-            Object bean = lifecycleEvent.getSource();
-            cmpCallback.ejbStore((EntityBean) bean);
+            EntityBean bean = (EntityBean) lifecycleEvent.getSource();
+            if (!creating.get().contains(bean)) {
+                cmpCallback.ejbStore(bean);
+            }
         }
 
         public void afterAttach(LifecycleEvent lifecycleEvent) {

Added: incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/test/entity/cmr/onetomany/ExampleABean_JPA.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/test/entity/cmr/onetomany/ExampleABean_JPA.java?view=auto&rev=492404
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/test/entity/cmr/onetomany/ExampleABean_JPA.java (added)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/test/entity/cmr/onetomany/ExampleABean_JPA.java Wed Jan  3 20:23:04 2007
@@ -0,0 +1,112 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openejb.test.entity.cmr.onetomany;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.openejb.core.cmp.cmp2.Cmp2Entity;
+import org.apache.openejb.core.cmp.cmp2.SetValuedCmr;
+
+public class ExampleABean_JPA extends ABean implements Cmp2Entity {
+    public static Object deploymentInfo;
+    private transient boolean deleted;
+    private Integer field1;
+    private String field2;
+    private Set<ExampleBBean_JPA> b = new HashSet<ExampleBBean_JPA>();
+    private SetValuedCmr bCmr = new SetValuedCmr(this, "b", ExampleBBean_JPA.class, "a");
+
+    private Set<ExampleBBean_JPA> bNonCascade = new HashSet<ExampleBBean_JPA>();
+    private SetValuedCmr bNonCascadeCmr = new SetValuedCmr(this, "bNonCascade", ExampleBBean_JPA.class, "aNonCascade");
+
+    public Integer getField1() {
+        return field1;
+    }
+
+    public void setField1(Integer field1) {
+        this.field1 = field1;
+    }
+
+    public String getField2() {
+        return field2;
+    }
+
+    public void setField2(String field2) {
+        this.field2 = field2;
+    }
+
+    public Set getB() {
+        return bCmr.get(b);
+    }
+
+    public void setB(Set b) {
+        bCmr.set(this.b, b);
+    }
+
+    public Set getBNonCascade() {
+        return bNonCascadeCmr.get(bNonCascade);
+    }
+
+    public void setBNonCascade(Set bNonCascade) {
+        bNonCascadeCmr.set(this.bNonCascade, bNonCascade);
+    }
+
+    public Object OpenEJB_getPrimaryKey() {
+        return field1;
+    }
+
+    public void OpenEJB_deleted() {
+        if (deleted) return;
+        deleted = true;
+
+        bCmr.deleted(b);
+        bNonCascadeCmr.deleted(bNonCascade);
+    }
+
+    public Object OpenEJB_addCmr(String name, Object bean) {
+        if (deleted) return null;
+
+        if ("b".equals(name)) {
+            b.add((ExampleBBean_JPA) bean);
+            return null;
+        }
+
+        if ("bNonCascade".equals(name)) {
+            bNonCascade.add((ExampleBBean_JPA) bean);
+            return null;
+        }
+
+        throw new IllegalArgumentException("Unknown cmr field " + name + " on entity bean of type " + getClass().getName());
+    }
+
+    public void OpenEJB_removeCmr(String name, Object value) {
+        if (deleted) return;
+
+        if ("b".equals(name)) {
+            b.remove(value);
+            return;
+        }
+
+        if ("bNonCascade".equals(name)) {
+            bNonCascade.remove(value);
+            return;
+        }
+
+        throw new IllegalArgumentException("Unknown cmr field " + name + " on entity bean of type " + getClass().getName());
+    }
+}

Added: incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/test/entity/cmr/onetomany/ExampleBBean_JPA.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/test/entity/cmr/onetomany/ExampleBBean_JPA.java?view=auto&rev=492404
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/test/entity/cmr/onetomany/ExampleBBean_JPA.java (added)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/test/entity/cmr/onetomany/ExampleBBean_JPA.java Wed Jan  3 20:23:04 2007
@@ -0,0 +1,128 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openejb.test.entity.cmr.onetomany;
+
+import org.apache.openejb.core.cmp.cmp2.Cmp2Entity;
+import org.apache.openejb.core.cmp.cmp2.SingleValuedCmr;
+
+public class ExampleBBean_JPA extends BBean implements Cmp2Entity {
+    public static Object deploymentInfo;
+    private transient boolean deleted;
+    private Integer field1;
+    private String field2;
+    private Integer field3;
+    private String field4;
+    private ExampleABean_JPA a;
+    private SingleValuedCmr aCmr = new SingleValuedCmr(this, "a", ExampleABean_JPA.class, "b");
+
+    private ExampleABean_JPA aNonCascade;
+    private SingleValuedCmr aNonCascadeCmr = new SingleValuedCmr(this, "aNonCascade", ExampleABean_JPA.class, "bNonCascade");
+
+    public Integer getField1() {
+        return field1;
+    }
+
+    public void setField1(Integer field1) {
+        this.field1 = field1;
+    }
+
+    public String getField2() {
+        return field2;
+    }
+
+    public void setField2(String field2) {
+        this.field2 = field2;
+    }
+
+    public Integer getField3() {
+        return field3;
+    }
+
+    public void setField3(Integer field3) {
+        this.field3 = field3;
+    }
+
+    public String getField4() {
+        return field4;
+    }
+
+    public void setField4(String field4) {
+        this.field4 = field4;
+    }
+
+    public ALocal getA() {
+        return (ALocal) aCmr.get(a);
+    }
+
+    public void setA(ALocal a) {
+        this.a = (ExampleABean_JPA) aCmr.set(this.a, a);
+    }
+
+    public ALocal getANonCascade() {
+        return (ALocal) aNonCascadeCmr.get(aNonCascade);
+    }
+
+    public void setANonCascade(ALocal aNonCascade) {
+        this.aNonCascade = (ExampleABean_JPA) aNonCascadeCmr.set(this.aNonCascade, aNonCascade);
+    }
+
+    public Object OpenEJB_getPrimaryKey() {
+        return field1;
+    }
+
+    public void OpenEJB_deleted() {
+        if (deleted) return;
+        deleted = true;
+
+        aCmr.deleted(a);
+        aNonCascadeCmr.deleted(aNonCascade);
+    }
+
+    public Object OpenEJB_addCmr(String name, Object bean) {
+        if (deleted) return null;
+
+        if ("a".equals(name)) {
+            Object oldValue = a;
+            a = (ExampleABean_JPA) bean;
+            return oldValue;
+        }
+
+        if ("aNonCascade".equals(name)) {
+            Object oldValue = aNonCascade;
+            aNonCascade = (ExampleABean_JPA) bean;
+            return oldValue;
+        }
+
+        throw new IllegalArgumentException("Unknown cmr field " + name + " on entity bean of type " + getClass().getName());
+    }
+
+    public void OpenEJB_removeCmr(String name, Object bean) {
+        if (deleted) return;
+
+        if ("a".equals(name)) {
+            a = null;
+            return;
+        }
+
+        if ("aNonCascade".equals(name)) {
+            aNonCascade = null;
+            return;
+        }
+        throw new IllegalArgumentException("Unknown cmr field " + name + " on entity bean of type " + getClass().getName());
+    }
+}

Copied: incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/test/entity/cmr/onetoone/ExampleABean_JPA.java (from r491148, incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetoone/ABean_JPA.java)
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/test/entity/cmr/onetoone/ExampleABean_JPA.java?view=diff&rev=492404&p1=incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetoone/ABean_JPA.java&r1=491148&p2=incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/test/entity/cmr/onetoone/ExampleABean_JPA.java&r2=492404
==============================================================================
--- incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetoone/ABean_JPA.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/test/entity/cmr/onetoone/ExampleABean_JPA.java Wed Jan  3 20:23:04 2007
@@ -17,16 +17,16 @@
  */
 package org.apache.openejb.test.entity.cmr.onetoone;
 
-import org.apache.openejb.test.entity.SingleValuedCmr;
-import org.apache.openejb.test.entity.CmrFactory;
+import org.apache.openejb.core.cmp.cmp2.SingleValuedCmr;
+import org.apache.openejb.core.cmp.cmp2.Cmp2Entity;
 
-public class ABean_JPA extends ABean {
+public class ExampleABean_JPA extends ABean implements Cmp2Entity {
     public static Object deploymentInfo;
-    public transient boolean deleted;
-    public Integer field1;
+    private transient boolean deleted;
+    private Integer field1;
     private String field2;
-    private BBean_JPA b;
-    private SingleValuedCmr<BBean_JPA, BLocal> bCmr = CmrFactory.cmrFactory.createSingleValuedCmr(this, "b", BBean_JPA.class, "a");
+    private ExampleBBean_JPA b;
+    private SingleValuedCmr<ExampleBBean_JPA, BLocal> bCmr = new SingleValuedCmr<ExampleBBean_JPA, BLocal>(this, "b", ExampleBBean_JPA.class, "a");
 
     public Integer getField1() {
         return field1;
@@ -52,20 +52,28 @@
         this.b = bCmr.set(this.b, b);
     }
 
+    public Object OpenEJB_getPrimaryKey() {
+        return field1;
+    }
+
     public void OpenEJB_deleted() {
-        if (deleted) return;
+        if (deleted) {
+            return;
+        }
         deleted = true;
 
         bCmr.set(b, null);
     }
 
     public Object OpenEJB_addCmr(String name, Object bean) {
-        if (deleted) return null;
+        if (deleted) {
+            return null;
+        }
 
         Object oldValue;
         if ("b".equals(name)) {
             oldValue = b;
-            b = (BBean_JPA) bean;
+            b = (ExampleBBean_JPA) bean;
         } else {
             throw new IllegalArgumentException("Unknown cmr field " + name + " on entity bean of type " + getClass().getName());
         }
@@ -73,7 +81,9 @@
     }
 
     public void OpenEJB_removeCmr(String name, Object bean) {
-        if (deleted) return;
+        if (deleted) {
+            return;
+        }
 
         if ("b".equals(name)) {
             b = null;

Copied: incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/test/entity/cmr/onetoone/ExampleBBean_JPA.java (from r491148, incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetoone/BBean_JPA.java)
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/test/entity/cmr/onetoone/ExampleBBean_JPA.java?view=diff&rev=492404&p1=incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetoone/BBean_JPA.java&r1=491148&p2=incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/test/entity/cmr/onetoone/ExampleBBean_JPA.java&r2=492404
==============================================================================
--- incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/entity/cmr/onetoone/BBean_JPA.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/test/entity/cmr/onetoone/ExampleBBean_JPA.java Wed Jan  3 20:23:04 2007
@@ -17,18 +17,18 @@
  */
 package org.apache.openejb.test.entity.cmr.onetoone;
 
-import org.apache.openejb.test.entity.CmrFactory;
-import org.apache.openejb.test.entity.SingleValuedCmr;
+import org.apache.openejb.core.cmp.cmp2.SingleValuedCmr;
+import org.apache.openejb.core.cmp.cmp2.Cmp2Entity;
 
-public class BBean_JPA extends BBean {
+public class ExampleBBean_JPA extends BBean implements Cmp2Entity {
     public static Object deploymentInfo;
-    public transient boolean deleted;
-    public Integer field1;
+    private transient boolean deleted;
+    private Integer field1;
     private String field2;
     private Integer field3;
     private String field4;
-    private ABean_JPA a;
-    private SingleValuedCmr<ABean_JPA, ALocal> aCmr = CmrFactory.cmrFactory.createSingleValuedCmr(this, "a", ABean_JPA.class, "b");
+    private ExampleABean_JPA a;
+    private SingleValuedCmr<ExampleABean_JPA, ALocal> aCmr = new SingleValuedCmr<ExampleABean_JPA, ALocal>(this, "a", ExampleABean_JPA.class, "b");
 
     public Integer getField1() {
         return field1;
@@ -70,20 +70,28 @@
         this.a = aCmr.set(this.a, a);
     }
 
+    public Object OpenEJB_getPrimaryKey() {
+        return field1;
+    }
+
     public void OpenEJB_deleted() {
-        if (deleted) return;
+        if (deleted) {
+            return;
+        }
         deleted = true;
 
         aCmr.set(a, null);
     }
 
     public Object OpenEJB_addCmr(String name, Object bean) {
-        if (deleted) return null;
+        if (deleted) {
+            return null;
+        }
 
         Object oldValue;
         if ("a".equals(name)) {
             oldValue = a;
-            a = (ABean_JPA) bean;
+            a = (ExampleABean_JPA) bean;
         } else {
             throw new IllegalArgumentException("Unknown cmr field " + name + " on entity bean of type " + getClass().getName());
         }
@@ -91,7 +99,9 @@
     }
 
     public void OpenEJB_removeCmr(String name, Object bean) {
-        if (deleted) return;
+        if (deleted) {
+            return;
+        }
 
         if ("a".equals(name)) {
             a = null;

Modified: incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/CmrFieldType.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/CmrFieldType.java?view=diff&rev=492404&r1=492403&r2=492404
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/CmrFieldType.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/CmrFieldType.java Wed Jan  3 20:23:04 2007
@@ -28,6 +28,16 @@
  * must be either: java.util.Collection or java.util.Set.
  */
 public enum CmrFieldType {
-    @XmlEnumValue("java.util.Collection") COLLECTION,
-    @XmlEnumValue("java.util.Set") SET
+    @XmlEnumValue("java.util.Collection") COLLECTION("java.util.Collection"),
+    @XmlEnumValue("java.util.Set") SET("java.util.Set");
+
+    private final String value;
+
+    CmrFieldType(String value) {
+       this.value = value;
+   }
+
+    public String toString() {
+        return value;
+    }
 }

Modified: incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/EjbRelation.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/EjbRelation.java?view=diff&rev=492404&r1=492403&r2=492404
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/EjbRelation.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/EjbRelation.java Wed Jan  3 20:23:04 2007
@@ -18,14 +18,12 @@
 
 package org.apache.openejb.jee;
 
-import javax.xml.bind.JAXBElement;
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlAttribute;
-import javax.xml.bind.annotation.XmlElementRef;
-import javax.xml.bind.annotation.XmlElementRefs;
 import javax.xml.bind.annotation.XmlID;
 import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.adapters.CollapsedStringAdapter;
 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 import java.util.ArrayList;
@@ -44,44 +42,44 @@
  */
 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(name = "ejb-relationType", propOrder = {
-        "content"
+        "description",
+        "ejbRelationName",
+        "ejbRelationshipRole"
         })
 public class EjbRelation {
+    @XmlElement(required = true)
+    protected List<Text> description;
+    @XmlElement(name = "ejb-relation-name")
+    protected String ejbRelationName;
+
+    @XmlElement(name = "ejb-relationship-role", required = true)
+    protected List<EjbRelationshipRole> ejbRelationshipRole;
 
-    @XmlElementRefs({
-    @XmlElementRef(name = "ejb-relation-name", namespace = "http://java.sun.com/xml/ns/javaee", type = JAXBElement.class),
-    @XmlElementRef(name = "ejb-relationship-role", namespace = "http://java.sun.com/xml/ns/javaee", type = JAXBElement.class),
-    @XmlElementRef(name = "description", namespace = "http://java.sun.com/xml/ns/javaee", type = JAXBElement.class)
-            })
-    protected List<JAXBElement<?>> content;
     @XmlAttribute
     @XmlJavaTypeAdapter(CollapsedStringAdapter.class)
     @XmlID
     protected String id;
 
-    /**
-     * Gets the rest of the content model.
-     * <p/>
-     * <p/>
-     * You are getting this "catch-all" property because of the following reason:
-     * The field name "EjbRelationshipRole" is used by two different parts of a schema. See:
-     * line 766 of openejb3/container/openejb-jee/src/main/xsd/ejb-jar_3_0.xsd
-     * line 764 of openejb3/container/openejb-jee/src/main/xsd/ejb-jar_3_0.xsd
-     * <p/>
-     * To get rid of this property, apply a property customization to one
-     * of both of the following declarations to change their names:
-     * Gets the value of the content property.
-     * <p/>
-     * Objects of the following type(s) are allowed in the list
-     * {@link JAXBElement }{@code <}{@link EjbRelationshipRole }{@code >}
-     * {@link JAXBElement }{@code <}{@link Text }{@code >}
-     * {@link JAXBElement }{@code <}{@link String }{@code >}
-     */
-    public List<JAXBElement<?>> getContent() {
-        if (content == null) {
-            content = new ArrayList<JAXBElement<?>>();
+    public List<Text> getDescription() {
+        if (description == null) {
+            description = new ArrayList<Text>();
+        }
+        return this.description;
+    }
+
+    public String getEjbRelationName() {
+        return ejbRelationName;
+    }
+
+    public void setEjbRelationName(String value) {
+        this.ejbRelationName = value;
+    }
+
+    public List<EjbRelationshipRole> getEjbRelationshipRole() {
+        if (ejbRelationshipRole == null) {
+            ejbRelationshipRole = new ArrayList<EjbRelationshipRole>();
         }
-        return this.content;
+        return ejbRelationshipRole;
     }
 
     public String getId() {

Modified: incubator/openejb/trunk/openejb3/container/openejb-persistence/src/main/java/org/apache/openejb/persistence/PersistenceUnitInfoImpl.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-persistence/src/main/java/org/apache/openejb/persistence/PersistenceUnitInfoImpl.java?view=diff&rev=492404&r1=492403&r2=492404
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-persistence/src/main/java/org/apache/openejb/persistence/PersistenceUnitInfoImpl.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-persistence/src/main/java/org/apache/openejb/persistence/PersistenceUnitInfoImpl.java Wed Jan  3 20:23:04 2007
@@ -252,9 +252,6 @@
 
         public byte[] transform(ClassLoader classLoader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
             byte[] bytes = classTransformer.transform(classLoader, className.replace('/', '.'), classBeingRedefined, protectionDomain, classfileBuffer);
-            if ("org/apache/openejb/test/entity/cmp/BasicCmpBean".equals(className)) {
-                System.out.println("Transformed BasicCmpBean");
-            }
             return bytes;
         }
     }