Index: openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java =================================================================== --- openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java (revision 509668) +++ openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java (working copy) @@ -95,6 +95,11 @@ * @author Abe White */ public class PCEnhancer { + // Designates a version for maintaining compatbility when PCEnhancer + // modifies enhancement that can break serialization or other contracts + // Each enhanced class will return the value of this field via + // public int getEnhancementContractVersion() + public static final int ENHANCER_VERSION = 2; public static final int ENHANCE_NONE = 0; public static final int ENHANCE_AWARE = 2 << 0; @@ -716,7 +721,6 @@ if (_meta.getPCSuperclass() == null) { addStockMethods(); addGetVersionMethod(); - addReplaceFlagsMethod(); addReplaceStateManagerMethod(); if (_meta.getIdentityType() != ClassMetaData.ID_APPLICATION) @@ -841,11 +845,6 @@ code.aload().setParam(0); code.putfield().setField(SM, SMTYPE); - // pc.pcFlags = LOAD_REQUIRED - code.aload().setLocal(inst); - code.constant().setValue(PersistenceCapable.LOAD_REQUIRED); - code.putfield().setField(PRE + "Flags", byte.class); - // copy key fields from oid if (oid) { code.aload().setLocal(inst); @@ -1330,35 +1329,6 @@ } /** - * Adds the {@link PersistenceCapable#pcReplaceFlags} - * method to the bytecode. - */ - private void addReplaceFlagsMethod() { - // public final void pcReplaceFlags () - BCMethod method = _pc.declareMethod(PRE + "ReplaceFlags", - void.class, null); - Code code = method.getCode(true); - - // if (pcStateManager != null) - loadManagedInstance(code, false); - code.getfield().setField(SM, SMTYPE); - JumpInstruction ifins = code.ifnonnull(); - code.vreturn(); - - // pcFlags = pcStateManager.replaceFlags (); - ifins.setTarget(loadManagedInstance(code, false)); - loadManagedInstance(code, false); - code.getfield().setField(SM, SMTYPE); - code.invokeinterface().setMethod(SMTYPE, "replaceFlags", - byte.class, null); - code.putfield().setField(PRE + "Flags", byte.class); - code.vreturn(); - - code.calculateMaxStack(); - code.calculateMaxLocals(); - } - - /** * Adds the {@link PersistenceCapable#pcReplaceStateManager} * method to the bytecode. */ @@ -2157,6 +2127,9 @@ // make the class implement PersistenceCapable _pc.declareInterface(PCTYPE); + // add a version stamp + addGetEnhancementContractVersionMethod(); + // find the default constructor BCMethod method = _pc.getDeclaredMethod("", (String[]) null); @@ -2212,10 +2185,6 @@ BCField field = _pc.declareField(SM, SMTYPE); field.makeProtected(); field.setTransient(true); - - field = _pc.declareField(PRE + "Flags", byte.class); - field.makeProtected(); - field.setTransient(true); } } @@ -2860,23 +2829,10 @@ return; } - // dfg: if (inst.pcFlags <= 0) return inst.; - JumpInstruction ifins = null; - if ((fieldFlag & PersistenceCapable.CHECK_READ) > 0) { - loadManagedInstance(code, true); - code.getfield().setField(PRE + "Flags", byte.class); - ifins = code.ifgt(); - loadManagedInstance(code, true); - addGetManagedValueCode(code, fmd); - code.xreturn().setType(fmd.getDeclaredType()); - } - // if (inst.pcStateManager == null) return inst.; Instruction ins = loadManagedInstance(code, true); - if (ifins != null) - ifins.setTarget(ins); code.getfield().setField(SM, SMTYPE); - ifins = code.ifnonnull(); + JumpInstruction ifins = code.ifnonnull(); loadManagedInstance(code, true); addGetManagedValueCode(code, fmd); code.xreturn().setType(fmd.getDeclaredType()); @@ -2919,25 +2875,10 @@ // PCEnhancer uses static methods; PCSubclasser does not. int firstParamOffset = getAccessorParameterOffset(); - // dfg: if (inst.pcFlags == 0) inst. = value; - JumpInstruction ifins = null; - byte fieldFlag = getFieldFlag(fmd); - if ((fieldFlag & PersistenceCapable.CHECK_WRITE) > 0) { - loadManagedInstance(code, true); - code.getfield().setField(PRE + "Flags", byte.class); - ifins = code.ifne(); - loadManagedInstance(code, true); - code.xload().setParam(firstParamOffset); - addSetManagedValueCode(code, fmd); - code.vreturn(); - } - // if (inst.pcStateManager == null) inst. = value; Instruction ins = loadManagedInstance(code, true); - if (ifins != null) - ifins.setTarget(ins); code.getfield().setField(SM, SMTYPE); - ifins = code.ifnonnull(); + JumpInstruction ifins = code.ifnonnull(); loadManagedInstance(code, true); code.xload().setParam(firstParamOffset); addSetManagedValueCode(code, fmd); @@ -3507,6 +3448,19 @@ return setter; } + private void addGetEnhancementContractVersionMethod() { + // public int getEnhancementContractVersion() + BCMethod method = _pc.declareMethod("getEnhancementContractVersion", + int.class, null); + method.makePublic(); + Code code = method.getCode(true); + code.constant().setValue(ENHANCER_VERSION); + code.areturn(); + code.calculateMaxStack(); + code.calculateMaxLocals(); + return; + } + /** * Return the concrete type for the given class, i.e. impl for managed * interfaces