db-jdo-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From m..@apache.org
Subject svn commit: r158176 [9/79] - in incubator/jdo/trunk/ri11: ./ src/ src/conf/ src/java/ src/java/org/ src/java/org/apache/ src/java/org/apache/jdo/ src/java/org/apache/jdo/ejb/ src/java/org/apache/jdo/enhancer/ src/java/org/apache/jdo/impl/ src/java/org/apache/jdo/impl/enhancer/ src/java/org/apache/jdo/impl/enhancer/classfile/ src/java/org/apache/jdo/impl/enhancer/core/ src/java/org/apache/jdo/impl/enhancer/generator/ src/java/org/apache/jdo/impl/enhancer/meta/ src/java/org/apache/jdo/impl/enhancer/meta/model/ src/java/org/apache/jdo/impl/enhancer/meta/prop/ src/java/org/apache/jdo/impl/enhancer/meta/util/ src/java/org/apache/jdo/impl/enhancer/util/ src/java/org/apache/jdo/impl/fostore/ src/java/org/apache/jdo/impl/jdoql/ src/java/org/apache/jdo/impl/jdoql/jdoqlc/ src/java/org/apache/jdo/impl/jdoql/scope/ src/java/org/apache/jdo/impl/jdoql/tree/ src/java/org/apache/jdo/impl/model/ src/java/org/apache/jdo/impl/model/java/ src/java/org/apache/jdo/impl/model/java/runtime/ src/java/org/apache/jdo/impl/model/jdo/ src/java/org/apache/jdo/impl/model/jdo/caching/ src/java/org/apache/jdo/impl/model/jdo/util/ src/java/org/apache/jdo/impl/model/jdo/xml/ src/java/org/apache/jdo/impl/pm/ src/java/org/apache/jdo/impl/sco/ src/java/org/apache/jdo/impl/state/ src/java/org/apache/jdo/jdoql/ src/java/org/apache/jdo/jdoql/tree/ src/java/org/apache/jdo/model/ src/java/org/apache/jdo/model/java/ src/java/org/apache/jdo/model/jdo/ src/java/org/apache/jdo/pm/ src/java/org/apache/jdo/sco/ src/java/org/apache/jdo/state/ src/java/org/apache/jdo/store/ src/java/org/apache/jdo/util/ test/ test/conf/ test/enhancer/ test/enhancer/sempdept/ test/enhancer/sempdept/src/ test/enhancer/sempdept/src/empdept/ test/fsuid2/ test/fsuid2/org/ test/fsuid2/org/apache/ test/fsuid2/org/apache/jdo/ test/fsuid2/org/apache/jdo/pc/ test/java/ test/java/org/ test/java/org/apache/ test/java/org/apache/jdo/ test/java/org/apache/jdo/impl/ test/java/org/apache/jdo/impl/fostore/ test/java/org/apache/jdo/pc/ test/java/org/apache/jdo/pc/appid/ test/java/org/apache/jdo/pc/empdept/ test/java/org/apache/jdo/pc/serializable/ test/java/org/apache/jdo/pc/xempdept/ test/java/org/apache/jdo/test/ test/java/org/apache/jdo/test/query/ test/java/org/apache/jdo/test/util/ test/jdo/ test/jdo/org/ test/jdo/org/apache/ test/jdo/org/apache/jdo/ test/jdo/org/apache/jdo/pc/ test/jdo/org/apache/jdo/pc/appid/ test/jdo/org/apache/jdo/pc/empdept/ test/jdo/org/apache/jdo/pc/serializable/ test/jdo/org/apache/jdo/pc/xempdept/ xdocs/
Date Sat, 19 Mar 2005 01:05:58 GMT
Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/VMOp.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/VMOp.java?view=auto&rev=158176
==============================================================================
--- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/VMOp.java (added)
+++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/classfile/VMOp.java Fri Mar 18 17:02:29 2005
@@ -0,0 +1,546 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.jdo.impl.enhancer.classfile;
+
+/**
+ * Description of the VM opcodes
+ */
+public class VMOp implements VMConstants {
+    /* The opcode value */
+    private int opcodeValue;
+
+    /* The name of the opcode */
+    private String opcodeName;
+
+    /* The number of stack argument words */
+    private int stackArgs;
+
+    /* The number of stack result words */
+    private int stackResults;
+
+    /* The "type" signature of the stack argument words */
+    private String stackArgTypes;
+
+    /* The "type" signature of the stack result words */
+    private String stackResultTypes;
+
+    /* public accessors */
+
+    /**
+     * Return the opcode value 
+     */
+    final public int opcode() {
+        return opcodeValue;
+    }
+
+    /**
+     * Return the opcode name
+     */
+    final public String name() {
+        return opcodeName;
+    }
+
+    /**
+     * Return the number of words of stack arguments expected by this operation.
+     * If the number is not a fixed value, return -1;
+     */
+    final public int nStackArgs() {
+        return stackArgs;
+    }
+
+    /**
+     * Return the number of words of stack results produced by this operation.
+     * If the number is not a fixed value, return -1;
+     */
+    final public int nStackResults() {
+        return stackResults;
+    }
+
+    /**
+     * Return the type descriptor for the stack arguments to the operation.
+     */
+    final public String argTypes() {
+        return stackArgTypes;
+    }
+
+    /**
+     * Return the type descriptor for the stack results of the operation.
+     */
+    final public String resultTypes() {
+        return stackResultTypes;
+    }
+
+    /**
+     * constructor for a VMOp
+     */
+   
+    public VMOp(int theOpcode, String theOpcodeName, int nArgs, int nResults,
+                String argDescr, String resultDescr) {
+        opcodeValue = theOpcode;
+        opcodeName = theOpcodeName;
+        stackArgs = nArgs;
+        stackResults = nResults;
+        stackArgTypes = argDescr;
+        stackResultTypes = resultDescr;
+    }
+
+    /* package local methods */
+
+    static VMOp[] ops =  {
+        /* | no change*/
+        new VMOp(opc_nop, "nop", 0, 0, "", ""),
+        /* | ... -> ..., null */
+        new VMOp(opc_aconst_null, "aconst_null", 0, 1, "", "A"),
+        /* | ... -> ..., -1 */
+        new VMOp(opc_iconst_m1, "iconst_m1", 0, 1, "", "I"),
+        /* | ... -> ..., 0 */
+        new VMOp(opc_iconst_0, "iconst_0", 0, 1, "", "I"),
+        /* | ... -> ..., 1 */
+        new VMOp(opc_iconst_1, "iconst_1", 0, 1, "", "I"),
+        /* | ... -> ..., 2 */
+        new VMOp(opc_iconst_2, "iconst_2", 0, 1, "", "I"),
+        /* | ... -> ..., 3 */
+        new VMOp(opc_iconst_3, "iconst_3", 0, 1, "", "I"),
+        /* | ... -> ..., 4 */
+        new VMOp(opc_iconst_4, "iconst_4", 0, 1, "", "I"),
+        /* | ... -> ..., 5 */
+        new VMOp(opc_iconst_5, "iconst_5", 0, 1, "", "I"),
+        /* | ... -> ..., 0<high/low>, 0<high/low> */
+        new VMOp(opc_lconst_0, "lconst_0", 0, 2, "", "J"),
+        /* | ... -> ..., 1<high/low>, 1<high/low> */
+        new VMOp(opc_lconst_1, "lconst_1", 0, 2, "", "J"),
+        /* | ... -> ..., 0.0f */
+        new VMOp(opc_fconst_0, "fconst_0", 0, 1, "", "F"),
+        /* | ... -> ..., 1.0f */
+        new VMOp(opc_fconst_1, "fconst_1", 0, 1, "", "F"),
+        /* | ... -> ..., 2.0f */
+        new VMOp(opc_fconst_2, "fconst_2", 0, 1, "", "F"),
+        /* | ... -> ..., 0.0<high/low>, 0.0<high/low> */
+        new VMOp(opc_dconst_0, "dconst_0", 0, 2, "", "D"),
+        /* | ... -> ..., 1.0<high/low>, 1.0<high/low> */
+        new VMOp(opc_dconst_1, "dconst_1", 0, 2, "", "D"),
+        /* byte1 | ... => ..., value */
+        new VMOp(opc_bipush, "bipush", 0, 1, "", "I"),
+        /* byte1 byte2 | ... => ..., value */
+        new VMOp(opc_sipush, "sipush", 0, 1, "", "I"),
+        /* indexbyte1 | ... => ..., item */
+        new VMOp(opc_ldc, "ldc", 0, 1, "", "W"),
+        /* indexbyte1 indexbyte2 | ... => ..., item */
+        new VMOp(opc_ldc_w, "ldc_w", 0, 1, "", "W"),
+        /* indexbyte1 indexbyte2 | ... => ..., item1, item2 */
+        new VMOp(opc_ldc2_w, "ldc2_w", 0, 2, "", "X"),
+        /* vindex | ... => ..., value<vindex> */
+        new VMOp(opc_iload, "iload", 0, 1, "", "I"),
+        /* vindex | ... => ..., value<vindex><h/l>, value<vindex><h/l> */
+        new VMOp(opc_lload, "lload", 0, 2, "", "J"),
+        /* vindex | ... => ..., value<vindex> */
+        new VMOp(opc_fload, "fload", 0, 1, "", "F"),
+        /* vindex | ... => ..., value<vindex><h/l>, value<vindex><h/l> */
+        new VMOp(opc_dload, "dload", 0, 2, "", "D"),
+        /* vindex | ... => ..., value<vindex> */
+        new VMOp(opc_aload, "aload", 0, 1, "", "A"),
+        /* | ... => ..., value<0> */
+        new VMOp(opc_iload_0, "iload_0", 0, 1, "", "I"),
+        /* | ... => ..., value<1> */
+        new VMOp(opc_iload_1, "iload_1", 0, 1, "", "I"),
+        /* | ... => ..., value<2> */
+        new VMOp(opc_iload_2, "iload_2", 0, 1, "", "I"),
+        /* | ... => ..., value<3> */
+        new VMOp(opc_iload_3, "iload_3", 0, 1, "", "I"),
+        /* | ... => ..., value<0><h/l>, value<0><h/l> */
+        new VMOp(opc_lload_0, "lload_0", 0, 2, "", "J"),
+        /* | ... => ..., value<1><h/l>, value<1><h/l> */
+        new VMOp(opc_lload_1, "lload_1", 0, 2, "", "J"),
+        /* | ... => ..., value<2><h/l>, value<2><h/l> */
+        new VMOp(opc_lload_2, "lload_2", 0, 2, "", "J"),
+        /* | ... => ..., value<3><h/l>, value<3><h/l> */
+        new VMOp(opc_lload_3, "lload_3", 0, 2, "", "J"),
+        /* | ... => ..., value<0> */
+        new VMOp(opc_fload_0, "fload_0", 0, 1, "", "F"),
+        /* | ... => ..., value<1> */
+        new VMOp(opc_fload_1, "fload_1", 0, 1, "", "F"),
+        /* | ... => ..., value<2> */
+        new VMOp(opc_fload_2, "fload_2", 0, 1, "", "F"),
+        /* | ... => ..., value<3> */
+        new VMOp(opc_fload_3, "fload_3", 0, 1, "", "F"),
+        /* | ... => ..., value<0><h/l>, value<0><h/l> */
+        new VMOp(opc_dload_0, "dload_0", 0, 2, "", "D"),
+        /* | ... => ..., value<1><h/l>, value<1><h/l> */
+        new VMOp(opc_dload_1, "dload_1", 0, 2, "", "D"),
+        /* | ... => ..., value<2><h/l>, value<2><h/l> */
+        new VMOp(opc_dload_2, "dload_2", 0, 2, "", "D"),
+        /* | ... => ..., value<3><h/l>, value<3><h/l> */
+        new VMOp(opc_dload_3, "dload_3", 0, 2, "", "D"),
+        /* | ... => ..., value<0> */
+        new VMOp(opc_aload_0, "aload_0", 0, 1, "", "A"),
+        /* | ... => ..., value<1> */
+        new VMOp(opc_aload_1, "aload_1", 0, 1, "", "A"),
+        /* | ... => ..., value<2> */
+        new VMOp(opc_aload_2, "aload_2", 0, 1, "", "A"),
+        /* | ... => ..., value<3> */
+        new VMOp(opc_aload_3, "aload_3", 0, 1, "", "A"),
+        /* | ..., arrayref, index => ..., value */
+        new VMOp(opc_iaload, "iaload", 2, 1, "AI", "I"),
+        /* | ..., arrayref, index => ..., value<h/l>, value<h/l> */
+        new VMOp(opc_laload, "laload", 2, 2, "AI", "J"),
+        /* | ..., arrayref, index => ..., value */
+        new VMOp(opc_faload, "faload", 2, 1, "AI", "F"),
+        /* | ..., arrayref, index => ..., value<h/l>, value<h/l> */
+        new VMOp(opc_daload, "daload", 2, 2, "AI", "D"),
+        /* | ..., arrayref, index => ..., value */
+        new VMOp(opc_aaload, "aaload", 2, 1, "AI", "A"),
+        /* | ..., arrayref, index => ..., value */
+        new VMOp(opc_baload, "baload", 2, 1, "AI", "I"),
+        /* | ..., arrayref, index => ..., value */
+        new VMOp(opc_caload, "caload", 2, 1, "AI", "I"),
+        /* | ..., arrayref, index => ..., value */
+        new VMOp(opc_saload, "saload", 2, 1, "AI", "I"),
+        /* vindex | ..., value => ... */
+        new VMOp(opc_istore, "istore", 1, 0, "I", ""),
+        /* vindex | ..., value<h/l>, value<h/l> => ... */
+        new VMOp(opc_lstore, "lstore", 2, 0, "J", ""),
+        /* vindex | ..., value => ... */
+        new VMOp(opc_fstore, "fstore", 1, 0, "F", ""),
+        /* vindex | ..., value<h/l>, value<h/l> => ... */
+        new VMOp(opc_dstore, "dstore", 2, 0, "D", ""),
+        /* vindex | ..., value => ... */
+        new VMOp(opc_astore, "astore", 1, 0, "A", ""),
+        /* | ..., value => ... */
+        new VMOp(opc_istore_0, "istore_0", 1, 0, "I", ""),
+        /* | ..., value => ... */
+        new VMOp(opc_istore_1, "istore_1", 1, 0, "I", ""),
+        /* | ..., value => ... */
+        new VMOp(opc_istore_2, "istore_2", 1, 0, "I", ""),
+        /* | ..., value => ... */
+        new VMOp(opc_istore_3, "istore_3", 1, 0, "I", ""),
+        /* | ..., value<h/l>, value<h/l> => ... */
+        new VMOp(opc_lstore_0, "lstore_0", 2, 0, "J", ""),
+        /* | ..., value<h/l>, value<h/l> => ... */
+        new VMOp(opc_lstore_1, "lstore_1", 2, 0, "J", ""),
+        /* | ..., value<h/l>, value<h/l> => ... */
+        new VMOp(opc_lstore_2, "lstore_2", 2, 0, "J", ""),
+        /* | ..., value<h/l>, value<h/l> => ... */
+        new VMOp(opc_lstore_3, "lstore_3", 2, 0, "J", ""),
+        /* | ..., value => ... */
+        new VMOp(opc_fstore_0, "fstore_0", 1, 0, "F", ""),
+        /* | ..., value => ... */
+        new VMOp(opc_fstore_1, "fstore_1", 1, 0, "F", ""),
+        /* | ..., value => ... */
+        new VMOp(opc_fstore_2, "fstore_2", 1, 0, "F", ""),
+        /* | ..., value => ... */
+        new VMOp(opc_fstore_3, "fstore_3", 1, 0, "F", ""),
+        /* | ..., value<h/l>, value<h/l> => ... */
+        new VMOp(opc_dstore_0, "dstore_0", 2, 0, "D", ""),
+        /* | ..., value<h/l>, value<h/l> => ... */
+        new VMOp(opc_dstore_1, "dstore_1", 2, 0, "D", ""),
+        /* | ..., value<h/l>, value<h/l> => ... */
+        new VMOp(opc_dstore_2, "dstore_2", 2, 0, "D", ""),
+        /* | ..., value<h/l>, value<h/l> => ... */
+        new VMOp(opc_dstore_3, "dstore_3", 2, 0, "D", ""),
+        /* | ..., value => ... */
+        new VMOp(opc_astore_0, "astore_0", 1, 0, "A", ""),
+        /* | ..., value => ... */
+        new VMOp(opc_astore_1, "astore_1", 1, 0, "A", ""),
+        /* | ..., value => ... */
+        new VMOp(opc_astore_2, "astore_2", 1, 0, "A", ""),
+        /* | ..., value => ... */
+        new VMOp(opc_astore_3, "astore_3", 1, 0, "A", ""),
+        /* | ..., arrayref, index, value => ... */
+        new VMOp(opc_iastore, "iastore", 3, 0, "AII", ""),
+        /* | ..., arrayref, index, value<h/l>, value<h/l> => ... */
+        new VMOp(opc_lastore, "lastore", 4, 0, "AIJ", ""),
+        /* | ..., arrayref, index, value => ... */
+        new VMOp(opc_fastore, "fastore", 3, 0, "AIF", ""),
+        /* | ..., arrayref, index, value<h/l>, value<h/l> => ... */
+        new VMOp(opc_dastore, "dastore", 4, 0, "AID", ""),
+        /* | ..., arrayref, index, value => ... */
+        new VMOp(opc_aastore, "aastore", 3, 0, "AIA", ""),
+        /* | ..., arrayref, index, value => ... */
+        new VMOp(opc_bastore, "bastore", 3, 0, "AII", ""),
+        /* | ..., arrayref, index, value => ... */
+        new VMOp(opc_castore, "castore", 3, 0, "AII", ""),
+        /* | ..., arrayref, index, value => ... */
+        new VMOp(opc_sastore, "sastore", 3, 0, "AII", ""),
+        /* | ..., any => ... */
+        new VMOp(opc_pop, "pop", 1, 0, "W", ""),
+        /* | ..., any1, any2 => ... */
+        new VMOp(opc_pop2, "pop2", 2, 0, "WW", ""),
+        /* | ..., any => ..., any, any */
+        new VMOp(opc_dup, "dup", 1, 2, "W", "WW"),
+        /* | ..., any1, any2 => ..., any2, any1, any2 */
+        new VMOp(opc_dup_x1, "dup_x1", 2, 3, "WW", "WWW"),
+        /* | ..., any1, any2, any3 => ..., any3, any1, any2, any3 */
+        new VMOp(opc_dup_x2, "dup_x2", 3, 4, "WWW", "WWWW"),
+        /* | ..., any1, any2 => ..., any1, any2, any1, any2 */
+        new VMOp(opc_dup2, "dup2", 2, 4, "WW", "WWWW"),
+        /* | ..., any1, any2, any3 => ..., any2, any3, any1, any2, any3 */
+        new VMOp(opc_dup2_x1, "dup2_x1", 3, 5, "WWW", "WWWWW"),
+        /* | ..., any1, any2, any3, any4 => ..., any3, any4, any1, any2, any3, any4 */
+        new VMOp(opc_dup2_x2, "dup2_x2", 4, 6, "WWWW", "WWWWWW"),
+        /* | ..., any1, any2 => ..., any2, any1 */
+        new VMOp(opc_swap, "swap", 2, 2, "WW", "WW"),
+        /* | ..., value1, value2 => ..., result */
+        new VMOp(opc_iadd, "iadd", 2, 1, "II", "I"),
+        /* | ..., value1<h/l>, value1<h/l>, value2<h/l>, value2<h/l> => ..., result<h/l>, result<h/l> */
+        new VMOp(opc_ladd, "ladd", 4, 2, "JJ", "J"),
+        /* | ..., value1, value2 => ..., result */
+        new VMOp(opc_fadd, "fadd", 2, 1, "FF", "F"),
+        /* | ..., value1<h/l>, value1<h/l>, value2<h/l>, value2<h/l> => ..., result<h/l>, result<h/l> */
+        new VMOp(opc_dadd, "dadd", 4, 2, "DD", "D"),
+        /* | ..., value1, value2 => ..., result */
+        new VMOp(opc_isub, "isub", 2, 1, "II", "I"),
+        /* | ..., value1<h/l>, value1<h/l>, value2<h/l>, value2<h/l> => ..., result<h/l>, result<h/l> */
+        new VMOp(opc_lsub, "lsub", 4, 2, "JJ", "J"),
+        /* | ..., value1, value2 => ..., result */
+        new VMOp(opc_fsub, "fsub", 2, 1, "FF", "F"),
+        /* | ..., value1<h/l>, value1<h/l>, value2<h/l>, value2<h/l> => ..., result<h/l>, result<h/l> */
+        new VMOp(opc_dsub, "dsub", 4, 2, "DD", "D"),
+        /* | ..., value1, value2 => ..., result */
+        new VMOp(opc_imul, "imul", 2, 1, "II", "I"),
+        /* | ..., value1<h/l>, value1<h/l>, value2<h/l>, value2<h/l> => ..., result<h/l>, result<h/l> */
+        new VMOp(opc_lmul, "lmul", 4, 2, "JJ", "J"),
+        /* | ..., value1, value2 => ..., result */
+        new VMOp(opc_fmul, "fmul", 2, 1, "FF", "F"),
+        /* | ..., value1<h/l>, value1<h/l>, value2<h/l>, value2<h/l> => ..., result<h/l>, result<h/l> */
+        new VMOp(opc_dmul, "dmul", 4, 2, "DD", "D"),
+        /* | ..., value1, value2 => ..., result */
+        new VMOp(opc_idiv, "idiv", 2, 1, "II", "I"),
+        /* | ..., value1<h/l>, value1<h/l>, value2<h/l>, value2<h/l> => ..., result<h/l>, result<h/l> */
+        new VMOp(opc_ldiv, "ldiv", 4, 2, "JJ", "J"),
+        /* | ..., value1, value2 => ..., result */
+        new VMOp(opc_fdiv, "fdiv", 2, 1, "FF", "F"),
+        /* | ..., value1<h/l>, value1<h/l>, value2<h/l>, value2<h/l> => ..., result<h/l>, result<h/l> */
+        new VMOp(opc_ddiv, "ddiv", 4, 2, "DD", "D"),
+        /* | ..., value1, value2 => ..., result */
+        new VMOp(opc_irem, "irem", 2, 1, "II", "I"),
+        /* | ..., value1<h/l>, value1<h/l>, value2<h/l>, value2<h/l> => ..., result<h/l>, result<h/l> */
+        new VMOp(opc_lrem, "lrem", 4, 2, "JJ", "J"),
+        /* | ..., value1, value2 => ..., result */
+        new VMOp(opc_frem, "frem", 2, 1, "FF", "F"),
+        /* | ..., value1<h/l>, value1<h/l>, value2<h/l>, value2<h/l> => ..., result<h/l>, result<h/l> */
+        new VMOp(opc_drem, "drem", 4, 2, "DD", "D"),
+        /* | ..., value => ..., result */
+        new VMOp(opc_ineg, "ineg", 1, 1, "I", "I"),
+        /* | ..., value<h/l>, value<h/l> => ..., result<h/l>, result<h/l> */
+        new VMOp(opc_lneg, "lneg", 2, 2, "J", "J"),
+        /* | ..., value => ..., result */
+        new VMOp(opc_fneg, "fneg", 1, 1, "F", "F"),
+        /* | ..., value<h/l>, value<h/l> => ..., result<h/l>, result<h/l> */
+        new VMOp(opc_dneg, "dneg", 2, 2, "D", "D"),
+        /* | ..., value1, value2 => ..., result */
+        new VMOp(opc_ishl, "ishl", 2, 1, "II", "I"),
+        /* | ..., value1<h/l>, value1<h/l>, value2 => ..., result */
+        new VMOp(opc_lshl, "lshl", 3, 2, "JI", "J"),
+        /* | ..., value1, value2 => ..., result */
+        new VMOp(opc_ishr, "ishr", 2, 1, "II", "I"),
+        /* | ..., value1<h/l>, value1<h/l>, value2 => ..., result<h/l>, result<h/l> */
+        new VMOp(opc_lshr, "lshr", 3, 2, "JI", "J"),
+        /* | ..., value1, value2 => ..., result */
+        new VMOp(opc_iushr, "iushr", 2, 1, "II", "I"),
+        /* | ..., value1<h/l>, value1<h/l>, value2 => ..., result<h/l>, result<h/l> */
+        new VMOp(opc_lushr, "lushr", 3, 2, "JI", "J"),
+        /* | ..., value1, value2 => ..., result */
+        new VMOp(opc_iand, "iand", 2, 1, "II", "I"),
+        /* | ..., value1<h/l>, value1<h/l>, value2<h/l>, value2<h/l> => ..., result<h/l>, result<h/l> */
+        new VMOp(opc_land, "land", 4, 2, "JJ", "J"),
+        /* | ..., value1, value2 => ..., result */
+        new VMOp(opc_ior, "ior", 2, 1, "II", "I"),
+        /* | ..., value1<h/l>, value1<h/l>, value2<h/l>, value2<h/l> => ..., result<h/l>, result<h/l> */
+        new VMOp(opc_lor, "lor", 4, 2, "JJ", "J"),
+        /* | ..., value1, value2 => ..., result */
+        new VMOp(opc_ixor, "ixor", 2, 1, "II", "I"),
+        /* | ..., value1<h/l>, value1<h/l>, value2<h/l>, value2<h/l> => ..., result<h/l>, result<h/l> */
+        new VMOp(opc_lxor, "lxor", 4, 2, "JJ", "J"),
+        /* vindex, const | no change */
+        new VMOp(opc_iinc, "iinc", 0, 0, "", ""),
+        /* | ..., value => ..., value<h/l>, value<h/l> */
+        new VMOp(opc_i2l, "i2l", 1, 2, "I", "J"),
+        /* | ..., value => ..., value */
+        new VMOp(opc_i2f, "i2f", 1, 1, "I", "F"),
+        /* | ..., value => ..., value<h/l>, value<h/l> */
+        new VMOp(opc_i2d, "i2d", 1, 2, "I", "D"),
+        /* | ..., value<h/l>, value<h/l> => ..., value */
+        new VMOp(opc_l2i, "l2i", 2, 1, "J", "I"),
+        /* | ..., value<h/l>, value<h/l> => ..., value */
+        new VMOp(opc_l2f, "l2f", 2, 1, "J", "F"),
+        /* | ..., value<h/l>, value<h/l> => ..., value<h/l>, value<h/l> */
+        new VMOp(opc_l2d, "l2d", 2, 2, "J", "D"),
+        /* | ..., value => ..., value */
+        new VMOp(opc_f2i, "f2i", 1, 1, "F", "I"),
+        /* | ..., value => ..., value<h/l>, value<h/l> */
+        new VMOp(opc_f2l, "f2l", 1, 2, "F", "J"),
+        /* | ..., value => ..., value<h/l>, value<h/l> */
+        new VMOp(opc_f2d, "f2d", 1, 2, "F", "D"),
+        /* | ..., value<h/l>, value<h/l> => ..., value */
+        new VMOp(opc_d2i, "d2i", 2, 1, "D", "I"),
+        /* | ..., value<h/l>, value<h/l> => ..., value<h/l>, value<h/l> */
+        new VMOp(opc_d2l, "d2l", 2, 2, "D", "J"),
+        /* | ..., value<h/l>, value<h/l> => ..., value */
+        new VMOp(opc_d2f, "d2f", 2, 1, "D", "F"),
+        /* | ..., value => ..., result */
+        new VMOp(opc_i2b, "i2b", 1, 1, "I", "I"),
+        /* | ..., value => ..., result */
+        new VMOp(opc_i2c, "i2c", 1, 1, "I", "I"),
+        /* | ..., value => ..., result */
+        new VMOp(opc_i2s, "i2s", 1, 1, "I", "I"),
+        /* | ..., v1<h/l>, v1<h/l>, v2<h/l>, v2<h/l> => ..., result */
+        new VMOp(opc_lcmp, "lcmp", 4, 1, "JJ", "I"),
+        /*  | ..., v1<h/l>, v1<h/l>, v2<h/l>, v2<h/l> => ..., result */
+        new VMOp(opc_fcmpl, "fcmpl", 2, 1, "FF", "I"),
+        /*  | ..., v1, v2 => ..., result */
+        new VMOp(opc_fcmpg, "fcmpg", 2, 1, "FF", "I"),
+        /* | ..., v1<h/l>, v1<h/l>, v2<h/l>, v2<h/l> => ..., result */
+        new VMOp(opc_dcmpl, "dcmpl", 4, 1, "DD", "I"),
+        /* | ..., v1<h/l>, v1<h/l>, v2<h/l>, v2<h/l> => ..., result */
+        new VMOp(opc_dcmpg, "dcmpg", 4, 1, "DD", "I"),
+        /* brbyte1, brbyte2 | ..., value => ... */
+        new VMOp(opc_ifeq, "ifeq", 1, 0, "I", ""),
+        /* brbyte1, brbyte2 | ..., value => ... */
+        new VMOp(opc_ifne, "ifne", 1, 0, "I", ""),
+        /* brbyte1, brbyte2 | ..., value => ... */
+        new VMOp(opc_iflt, "iflt", 1, 0, "I", ""),
+        /* brbyte1, brbyte2 | ..., value => ... */
+        new VMOp(opc_ifge, "ifge", 1, 0, "I", ""),
+        /* brbyte1, brbyte2 | ..., value => ... */
+        new VMOp(opc_ifgt, "ifgt", 1, 0, "I", ""),
+        /* brbyte1, brbyte2 | ..., value => ... */
+        new VMOp(opc_ifle, "ifle", 1, 0, "I", ""),
+        /* brbyte1, brbyte2 | ..., value1, value2 => ... */
+        new VMOp(opc_if_icmpeq, "if_icmpeq", 2, 0, "II", ""),
+        /* brbyte1, brbyte2 | ..., value1, value2 => ... */
+        new VMOp(opc_if_icmpne, "if_icmpne", 2, 0, "II", ""),
+        /* brbyte1, brbyte2 | ..., value1, value2 => ... */
+        new VMOp(opc_if_icmplt, "if_icmplt", 2, 0, "II", ""),
+        /* brbyte1, brbyte2 | ..., value1, value2 => ... */
+        new VMOp(opc_if_icmpge, "if_icmpge", 2, 0, "II", ""),
+        /* brbyte1, brbyte2 | ..., value1, value2 => ... */
+        new VMOp(opc_if_icmpgt, "if_icmpgt", 2, 0, "II", ""),
+        /* brbyte1, brbyte2 | ..., value1, value2 => ... */
+        new VMOp(opc_if_icmple, "if_icmple", 2, 0, "II", ""),
+        /* brbyte1, brbyte2 | ..., value1, value2 => ... */
+        new VMOp(opc_if_acmpeq, "if_acmpeq", 2, 0, "AA", ""),
+        /* brbyte1, brbyte2 | ..., value1, value2 => ... */
+        new VMOp(opc_if_acmpne, "if_acmpne", 2, 0, "AA", ""),
+        /* brbyte1, brbyte2 | no change */
+        new VMOp(opc_goto, "goto", 0, 0, "", ""),
+        /* brbyte1, brbyte2 | ... => ..., return_addr */
+        new VMOp(opc_jsr, "jsr", 0, 1, "", "W"),
+        /* vindex | no change */
+        new VMOp(opc_ret, "ret", 0, 0, "", ""),
+        /* ??? | ..., index => ... */
+        new VMOp(opc_tableswitch, "tableswitch", 1, 0, "I", ""),
+        /* ??? | ..., key => ... */
+        new VMOp(opc_lookupswitch, "lookupswitch", 1, 0, "I", ""),
+        /* | ..., value => [empty] */
+        new VMOp(opc_ireturn, "ireturn", 1, 0, "I", ""),
+        /* | ..., value<h/l>, value<h/l> => [empty] */
+        new VMOp(opc_lreturn, "lreturn", 2, 0, "J", ""),
+        /* | ..., value => [empty] */
+        new VMOp(opc_freturn, "freturn", 1, 0, "F", ""),
+        /* | ..., value<h/l>, value<h/l> => [empty] */
+        new VMOp(opc_dreturn, "dreturn", 2, 0, "D", ""),
+        /* | ..., value => [empty] */
+        new VMOp(opc_areturn, "areturn", 1, 0, "A", ""),
+        /* | ... => [empty] */
+        new VMOp(opc_return, "return", 0, 0, "", ""),
+        /* idxbyte1, idxbyte2 | ... => ..., value [ value2 ] */
+        new VMOp(opc_getstatic, "getstatic", 0, -1, "", "?"),
+        /* idxbyte1, idxbyte2 | ..., value [ value2 ] => ... */
+        new VMOp(opc_putstatic, "putstatic", -1, 0, "?", ""),
+        /* idxbyte1, idxbyte2 | ..., objectref => ..., value [ value2 ] */
+        new VMOp(opc_getfield, "getfield", 1, -1, "A", "?"),
+        /* idxbyte1, idxbyte2 | ..., objectref, value [ value2 ] => ... */
+        new VMOp(opc_putfield, "putfield", -1, 0, "A?", ""),
+        /* idxbyte1, idxbyte2 | ..., objectref, [args] => ... */
+        new VMOp(opc_invokevirtual, "invokevirtual", -1, -1, "A?", "?"),
+        /* idxbyte1, idxbyte2 | ..., objectref, [args] => ... */
+        new VMOp(opc_invokespecial, "invokespecial", -1, -1, "A?", "?"),
+        /* idxbyte1, idxbyte2 | ..., [args] => ... */
+        new VMOp(opc_invokestatic, "invokestatic", -1, -1, "?", "?"),
+        /* idxbyte1, idxbyte2, nargs, rsvd | ..., objectref, [args] => ... */
+        new VMOp(opc_invokeinterface, "invokeinterface", -1, -1, "A?", "?"),
+        /* */
+        new VMOp(opc_xxxunusedxxx, "xxxunusedxxx", 0, 0, "", ""),
+        /* idxbyte1, idxbyte2 | ... => ..., objectref */
+        new VMOp(opc_new, "new", 0, 1, "", "A"),
+        /* atype | ..., size => ..., result */
+        new VMOp(opc_newarray, "newarray", 1, 1, "I", "A"),
+        /* indexbyte1, indexbyte2 | ..., size => ..., result */
+        new VMOp(opc_anewarray, "anewarray", 1, 1, "I", "A"),
+        /* | ..., objectref => ..., length */
+        new VMOp(opc_arraylength, "arraylength", 1, 1, "A", "I"),
+        /* | ..., objectref => [undefined] */
+        new VMOp(opc_athrow, "athrow", 1, 0, "A", "?"),
+        /* idxbyte1, idxbyte2 | ..., objectref => ..., objectref */
+        new VMOp(opc_checkcast, "checkcast", 1, 1, "A", "A"),
+        /* idxbyte1, idxbyte2 | ..., objectref => ..., result */
+        new VMOp(opc_instanceof, "instanceof", 1, 1, "A", "I"),
+        /* | ..., objectref => ... */
+        new VMOp(opc_monitorenter, "monitorenter", 1, 0, "A", ""),
+        /* | ..., objectref => ... */
+        new VMOp(opc_monitorexit, "monitorexit", 1, 0, "A", ""),
+        /* an instruction | special */
+        new VMOp(opc_wide, "wide", 0, 0, "", ""),
+        /* indexbyte1, indexbyte2, dimensions | ..., size1, ..., sizen => ..., result*/
+        new VMOp(opc_multianewarray, "multianewarray", -1, 1, "?", "A"),
+        /* brbyte1, brbyte2 | ..., value => ... */
+        new VMOp(opc_ifnull, "ifnull", 1, 0, "A", ""),
+        /* brbyte1, brbyte2 | ..., value => ... */
+        new VMOp(opc_ifnonnull, "ifnonnull", 1, 0, "A", ""),
+        /* brbyte1, brbyte2, brbyte3, brbyte4 | no change */
+        new VMOp(opc_goto_w, "goto_w", 0, 0, "", ""),
+        /* brbyte1, brbyte2, brbyte3, brbyte4 | ... => ..., return_addr */
+        new VMOp(opc_jsr_w, "jsr_w", 0, 1, "", "W") };
+
+    /**
+     * Check that each entry in the ops array has a valid VMOp entry
+     */
+    private static void check() {
+        for (int i=0; i<=opc_jsr_w; i++) {
+            VMOp op = ops[i];
+            if (op == null)
+                throw new InsnError ("null VMOp for " + i);
+            if (op.opcode() != i)
+                throw new InsnError ("bad opcode for " + i);
+
+            if (1 == 0) {
+                /* check arg/result data */
+                checkTypes(op.argTypes(), op.nStackArgs(), op);
+                checkTypes(op.resultTypes(), op.nStackResults(), op);
+            }
+        }
+    }
+
+    private static void checkTypes(String types, int n, VMOp op) {
+        for (int i=0; i<types.length(); i++) {
+            char c = types.charAt(i);
+            if (c == '?')
+                return;
+            if (c == 'J' || c == 'X' || c == 'D')
+                n -= 2;
+            else
+                n -= 1;
+        }
+        if (n != 0)
+            throw new InsnError ("Bad arg/result for VMOp " + op.opcodeName);
+    }
+
+    static {
+        check();
+    }
+}

Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/core/Analyzer.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/core/Analyzer.java?view=auto&rev=158176
==============================================================================
--- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/core/Analyzer.java (added)
+++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/enhancer/core/Analyzer.java Fri Mar 18 17:02:29 2005
@@ -0,0 +1,1586 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.jdo.impl.enhancer.core;
+
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Arrays;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.HashMap;
+
+import org.apache.jdo.impl.enhancer.classfile.ClassAttribute;
+import org.apache.jdo.impl.enhancer.classfile.ClassField;
+import org.apache.jdo.impl.enhancer.classfile.ClassFile;
+import org.apache.jdo.impl.enhancer.classfile.ClassMethod;
+import org.apache.jdo.impl.enhancer.classfile.ConstClass;
+import org.apache.jdo.impl.enhancer.classfile.ConstantPool;
+import org.apache.jdo.impl.enhancer.classfile.GenericAttribute;
+import org.apache.jdo.impl.enhancer.meta.EnhancerMetaData;
+import org.apache.jdo.impl.enhancer.util.Support;
+
+
+
+
+
+/**
+ * Analyzes a class for enhancement.
+ */
+final class Analyzer
+    extends Support
+    implements JDOConstants, EnhancerConstants
+{
+    /**
+     * The class is not to be modified by the enahncer.
+     */
+    static public final int CC_Unenhancable = -2;
+
+    /**
+     * The class is detected to be enhanced already and is not to be modifed.
+     */
+    static public final int CC_PreviouslyEnhanced = -1;
+
+    /**
+     * The enhancement status of the class hasn't been determined yet.
+     */
+    static public final int CC_PersistenceUnknown = 0;
+
+    /**
+     * The class is to be enhanced for persistence-awareness.
+     */
+    static public final int CC_PersistenceAware = 1;
+
+    /**
+     * The class is to be enhanced for specific persistence-capability
+     * (class does extend another persistence-capable class).
+     */
+    static public final int CC_PersistenceCapable = 2;
+
+    /**
+     * The class is to be enhanced for generic and specific
+     * persistence-capability (class does not extend another
+     * persistence-capable class).
+     */
+    static public final int CC_PersistenceCapableRoot = 3;
+
+    /**
+     * The names of the jdo fields of persistene-capable classes.
+     */
+    static private final Set jdoFieldNames = new HashSet();
+    static 
+    {
+        jdoFieldNames.add(JDO_PC_jdoStateManager_Name);
+        jdoFieldNames.add(JDO_PC_jdoFlags_Name);
+        jdoFieldNames.add(JDO_PC_jdoInheritedFieldCount_Name);
+        jdoFieldNames.add(JDO_PC_jdoFieldNames_Name);
+        jdoFieldNames.add(JDO_PC_jdoFieldTypes_Name);
+        jdoFieldNames.add(JDO_PC_jdoFieldFlags_Name);
+        jdoFieldNames.add(JDO_PC_jdoPersistenceCapableSuperclass_Name);
+    }
+
+    /**
+     * The classfile's enhancement controller.
+     */
+    private final Controller control;
+
+    /**
+     * The classfile to be enhanced.
+     */
+    private final ClassFile classFile;
+
+    /**
+     * The class name in VM form.
+     */
+    private final String className;
+
+    /**
+     * The class name in user ('.' delimited) form.
+     */
+    private final String userClassName;
+
+    /**
+     * The classfile's constant pool.
+     */
+    private final ConstantPool pool;
+
+    /**
+     * Repository for the enhancement options.
+     */
+    private final Environment env;
+
+    /**
+     * Repository for JDO meta-data on classes.
+     */
+    private final EnhancerMetaData meta;
+
+    /**
+     * What type of class is this with respect to persistence.
+     */
+    private int persistenceType = CC_PersistenceUnknown;
+
+    /**
+     * The name of the persistence-capable superclass if defined.
+     */
+    private String pcSuperClassName;
+
+    /**
+     * The name of the persistence-capable rootclass if defined.
+     */
+    private String pcRootClassName;
+
+    /**
+     * The name of this class or the next persistence-capable superclass
+     * that owns a key class, or the PC rootclass if none defines a key class.
+     */
+    private String pcKeyOwnerClassName;
+
+    /**
+     * The name next persistence-capable superclass that owns a key class,
+     * or the PC rootclass if none defines a key class.
+     */
+    private String pcSuperKeyOwnerClassName;
+
+    /**
+     * The name of the key class if defined.
+     */
+    private String keyClassName;
+
+    /**
+     * The name of the key class of the next persistence-capable superclass
+     * that defines one.
+     */
+    private String superKeyClassName;
+
+    /**
+     * The number of key fields.
+     */
+    private int keyFieldCount;
+
+    /**
+     * The indexes of all key fields.
+     */
+    private int[] keyFieldIndexes;
+
+    /**
+     * The number of managed fields.
+     */
+    private int managedFieldCount;
+
+    /**
+     * The number of annotated fields.
+     */
+    private int annotatedFieldCount;
+
+    /**
+     * The names of all annotated fields sorted by relative field index.
+     */
+    private String[] annotatedFieldNames;
+
+    /**
+     * The type names of all annotated fields sorted by relative field index.
+     */
+    private String[] annotatedFieldSigs;
+
+    /**
+     * The java access modifiers of all annotated fields sorted by relative
+     * field index.
+     */
+    private int[] annotatedFieldMods;
+
+    /**
+     * The jdo flags of all annotated fields sorted by relative field index.
+     */
+    private int[] annotatedFieldFlags;
+
+    /**
+     * The map of found JDO fields.
+     */
+    private final Map jdoLikeFields = new HashMap(20);
+
+    /**
+     * The map of found JDO methods
+     */
+    private final Map jdoLikeMethods = new HashMap(50);
+
+    /**
+     * The map of found JDO methods
+     */
+    private final Map annotatableMethods = new HashMap(100);
+
+    /**
+     * True if a jdo member has been seen in this class.
+     */
+    private boolean hasImplementsPC = false;
+    private boolean hasGenericJDOFields = false;
+    private boolean hasGenericJDOMethods = false;
+    private boolean hasGenericJDOMembers = false;
+    private boolean hasSpecificJDOFields = false;
+    private boolean hasSpecificJDOMethods = false;
+    private boolean hasSpecificJDOMembers = false;
+    private boolean hasCallbackJDOMethods = false;
+    private boolean hasJDOMembers = false;
+
+    /**
+     * True if the class has a default (no-argument) constructor.
+     */
+    private boolean hasDefaultConstructor = false;
+
+    //^olsen: performance opt.: make these fields of type ClassMethod
+    
+    /**
+     * True if the class has a static initializer block.
+     */
+    private boolean hasStaticInitializer = false;
+
+    /**
+     * True if the class has a clone() method.
+     */
+    private boolean hasCloneMethod = false;
+
+    /**
+     * True if the class has a writeObject(java.io.ObjectOutputStream) method.
+     */
+    private boolean hasWriteObjectMethod = false;
+
+    /**
+     * True if the class has a writeReplace() method.
+     */
+    private boolean hasWriteReplaceMethod = false;
+
+    /**
+     * True if the class has a readObject(java.io.ObjectInputStream) method.
+     */
+    private boolean hasReadObjectMethod = false;
+
+    // ----------------------------------------------------------------------
+    
+    /**
+     * Constructor
+     */
+    public Analyzer(Controller control,
+                    Environment env)
+    {
+        affirm(control != null);
+        affirm(env != null);
+
+        this.control = control;
+        this.classFile = control.getClassFile();
+        this.className = classFile.classNameString();
+        this.userClassName = classFile.userClassName();
+        this.pool = classFile.pool();
+        this.env = env;
+        this.meta = env.getEnhancerMetaData();
+
+        affirm(classFile != null);
+        affirm(className != null);
+        affirm(userClassName != null);
+        affirm(pool != null);
+        affirm(meta != null);
+    }
+
+    /**
+     * Returns the class file which we are operating on.
+     */
+    public ClassFile getClassFile()
+    {
+        return classFile;
+    }
+
+    /**
+     * Return the persistence type for this class
+     */
+    public int getPersistenceType()
+    {
+        return persistenceType;
+    }
+
+    /**
+     * Returns true if the class has been analyzed already.
+     */
+    public boolean isAnalyzed()
+    {
+        return (persistenceType != CC_PersistenceUnknown);
+    }
+
+    /**
+     * Returns true if the class is one which should be a candidate for
+     * annotation.
+     */
+    public boolean isAnnotateable()
+    {
+        return (persistenceType >= CC_PersistenceUnknown);
+    }
+
+    /**
+     * Returns true if the class is to be enhanced for persistence-capability.
+     */
+    public boolean isAugmentable()
+    {
+        return (persistenceType >= CC_PersistenceCapable);
+    }
+
+    /**
+     * Returns true if the class is to be enhanced as least-derived,
+     * persistence-capable class.
+     */
+    public boolean isAugmentableAsRoot()
+    {
+        return (persistenceType >= CC_PersistenceCapableRoot);
+    }
+
+    /**
+     * Returns the methods that are candidates for annotation.
+     */
+    public Collection getAnnotatableMethods()
+    {
+        return annotatableMethods.values();
+    }
+
+    /**
+     * Returns the name of the persistence-capable superclass if defined.
+     */
+    public String getPCSuperClassName()
+    {
+        return pcSuperClassName;
+    }
+
+    /**
+     * Returns the name of the persistence-capable rootclass if defined.
+     */
+    public String getPCRootClassName()
+    {
+        return pcRootClassName;
+    }
+
+    /**
+     * Returns the name of this class or the next persistence-capable
+     * superclass that owns a key class.
+     */
+    public String getPCKeyOwnerClassName()
+    {
+        return pcKeyOwnerClassName;
+    }
+
+    /**
+     * Returns the name of this class or the next persistence-capable
+     * that owns a key class.
+     */
+    public String getPCSuperKeyOwnerClassName()
+    {
+        return pcSuperKeyOwnerClassName;
+    }
+
+    /**
+     * Returns the name of the key class if defined.
+     */
+    public String getKeyClassName()
+    {
+        return keyClassName;
+    }
+
+    /**
+     * Returns the name of the key class of the next persistence-capable
+     * superclass that defines one.
+     */
+    public String getSuperKeyClassName()
+    {
+        return superKeyClassName;
+    }
+
+    /**
+     * Returns the number of key field.
+     */
+    public int getKeyFieldCount()
+    {
+        return keyFieldCount;
+    }
+
+    /**
+     * Returns the names of the key fields.
+     */
+    public int[] getKeyFieldIndexes()
+    {
+        return keyFieldIndexes;
+    }
+
+    /**
+     * Returns the number of managed field.
+     */
+    public int getManagedFieldCount()
+    {
+        return managedFieldCount;
+    }
+
+    /**
+     * Returns the number of annotated field.
+     */
+    public int getAnnotatedFieldCount()
+    {
+        return annotatedFieldCount;
+    }
+
+    /**
+     * Returns the names of the annotated fields.
+     */
+    public String[] getAnnotatedFieldNames()
+    {
+        return annotatedFieldNames;
+    }
+
+    /**
+     * Returns the types names of the annotated fields.
+     */
+    public String[] getAnnotatedFieldSigs()
+    {
+        return annotatedFieldSigs;
+    }
+
+    /**
+     * Returns the Java access modifiers of the annotated fields.
+     */
+    public int[] getAnnotatedFieldMods()
+    {
+        return annotatedFieldMods;
+    }
+
+    /**
+     * Returns the JDO flags of the annotated fields.
+     */
+    public int[] getAnnotatedFieldFlags()
+    {
+        return annotatedFieldFlags;
+    }
+
+    /**
+     * Returns true if the class has a default (no-argument) constructor.
+     */
+    public boolean hasDefaultConstructor()
+    {
+        return hasDefaultConstructor;
+    }
+
+    /**
+     * Returns true if the class has a static initializer block.
+     */
+    public boolean hasStaticInitializer()
+    {
+        return hasStaticInitializer;
+    }
+
+    /**
+     * Returns true if the class has a clone() method.
+     */
+    public boolean hasCloneMethod()
+    {
+        return hasCloneMethod;
+    }
+
+    /**
+     * Returns true if the class has a writeObject() method.
+     */
+    public boolean hasWriteObjectMethod()
+    {
+        return hasWriteObjectMethod;
+    }
+
+    /**
+     * Returns true if the class has a writeReplace() method.
+     */
+    public boolean hasWriteReplaceMethod()
+    {
+        return hasWriteReplaceMethod;
+    }
+
+    /**
+     * Returns true if the class has a readObject() method.
+     */
+    public boolean hasReadObjectMethod()
+    {
+        return hasReadObjectMethod;
+    }
+
+    /**
+     * Returns true if the class already provides the JDO augmentation.
+     */
+    public boolean hasJDOAugmentation()
+    {
+        return hasJDOMembers;
+    }
+
+    // ----------------------------------------------------------------------
+    
+    /**
+     * Analyzes the class for existing augmentation.
+     */
+    public void scan()
+    {
+        env.message("scanning class " + userClassName);
+
+        // skip previously enhanced files
+        checkForEnhancedAttribute();
+        if (!isAnnotateable()) {
+            return;
+        }
+
+        // skip unenhancable files
+        initPersistenceType();
+        if (!isAnnotateable()) {
+            return;
+        }
+        affirm(persistenceType > CC_Unenhancable);
+        
+        scanFields();
+        scanMethods();
+
+        if (isAugmentable()) {
+            checkPCFeasibility();
+            checkSpecificAugmentation();
+            checkCallbackAugmentation();
+
+            if (isAugmentableAsRoot()) {
+                checkGenericAugmentation();
+            }
+        }
+
+        //^olsen: check
+/*
+        //@olsen: check whether member starts with the reserved jdo prefix
+        if (methodName.startsWith("jdo")) {
+            //@olsen: issue a warning only
+            env.warning(
+                getI18N("enhancer.class_has_jdo_like_member",
+                        userClassName, methodName));
+            return;
+        }
+        //@olsen: check whether member starts with the reserved jdo prefix
+        if (fieldName.startsWith("jdo")) {
+            //@olsen: issue a warning only
+            env.warning(
+                getI18N("enhancer.class_has_jdo_like_member",
+                        userClassName, fieldName));
+            return;
+        }
+*/
+    }
+
+    /**
+     * Scans the attributes of a ClassFile
+     */
+    private void checkForEnhancedAttribute()
+    {
+        for (Enumeration e = classFile.attributes().elements();
+             e.hasMoreElements();) {
+            final ClassAttribute attr = (ClassAttribute)e.nextElement();
+            final String attrName = attr.attrName().asString();
+            if (SUNJDO_PC_EnhancedAttribute.equals(attrName)) {
+                persistenceType = CC_PreviouslyEnhanced;
+
+                // At some point we may want to consider stripping old
+                // annotations and re-annotating, but not yet
+                env.message("ignoring previously enhanced class "
+                            + userClassName);
+                return;
+            }
+        }
+    }
+
+    // ----------------------------------------------------------------------
+    
+    /**
+     * Sets the persistence type of a class according to JDO metadata.
+     */
+    private void initPersistenceType()
+    {
+        affirm(persistenceType == CC_PersistenceUnknown);
+
+        // check if class is known not to be changed
+        final EnhancerMetaData meta = env.getEnhancerMetaData();
+        if (meta.isKnownUnenhancableClass(className)) {
+            persistenceType = CC_Unenhancable;
+            return;
+        }
+
+        // check if class is persistence-capable
+        if (meta.isPersistenceCapableClass(className)) {
+            pcSuperClassName
+                = meta.getPersistenceCapableSuperClass(className);
+            pcRootClassName
+                = meta.getPersistenceCapableRootClass(className);
+            affirm(pcSuperClassName == null || pcRootClassName != null);
+
+            persistenceType
+                = (pcSuperClassName == null
+                   ? CC_PersistenceCapableRoot
+                   : CC_PersistenceCapable);
+
+            //^olsen: assert consistency between Java and JDO metadata
+            affirm(!classFile.isInterface());
+            //affirm(!classFile.isInnerClass());
+
+            //^olsen: assert consistency between Java and JDO metadata
+            // disallow enhancing classes not derived from java.lang.Object
+            final ConstClass superConstClass = classFile.superName();
+            affirm(superConstClass != null);
+
+            // non-pc-root classes must not derive from java.lang.Object
+            affirm(pcSuperClassName == null
+                   || !superConstClass.asString().equals("java/lang/Object"));
+
+            // define the PC key owner class
+            pcKeyOwnerClassName = className;
+            while (meta.getKeyClass(pcKeyOwnerClassName) == null) {
+                final String pcSuperClassName
+                    = meta.getPersistenceCapableSuperClass(
+                        pcKeyOwnerClassName);
+                if (pcSuperClassName == null)
+                    break;
+                pcKeyOwnerClassName = pcSuperClassName;
+            }
+            affirm(pcKeyOwnerClassName != null);
+
+            // define the PC super key owner class
+            pcSuperKeyOwnerClassName = pcSuperClassName;
+            if (pcSuperKeyOwnerClassName != null) {
+                while (meta.getKeyClass(pcSuperKeyOwnerClassName) == null) {
+                    final String pcSuperClassName
+                        = meta.getPersistenceCapableSuperClass(
+                            pcSuperKeyOwnerClassName);
+                    if (pcSuperClassName == null)
+                        break;
+                    pcSuperKeyOwnerClassName = pcSuperClassName;
+                }
+                affirm(pcKeyOwnerClassName != null);
+            }
+
+            keyClassName
+                = meta.getKeyClass(className);
+            superKeyClassName
+                = meta.getSuperKeyClass(className);
+            affirm(superKeyClassName == null || pcSuperClassName != null);
+        }
+    }
+
+    /**
+     * Scans the fields.
+     */
+    private void scanFields()
+    {
+        // all fields for which accessor/mutator needs to be generated
+        final Map annotatedFieldMap = new HashMap();
+
+        if (isAugmentable()) {
+            // loop over class fields to declare them to the model
+            for (final Enumeration e = classFile.fields().elements();
+                 e.hasMoreElements();) {
+                final ClassField field = (ClassField)e.nextElement();
+                final String name = field.name().asString();
+                final String sig = field.signature().asString();
+
+                // skip jdo fields
+                if (jdoFieldNames.contains(name)) {
+                    continue;
+                }
+
+                // skip static fields
+                if (field.isStatic()) {
+                    continue;
+                }
+
+                // skip known non-managed fields
+                if (meta.isKnownNonManagedField(className, name, sig)) {
+                    continue;
+                }
+
+                // remember field requiring accessor/mutator
+                Object obj = annotatedFieldMap.put(name, field);
+                affirm(obj == null,
+                   ("Error in classfile: repeated declaration of field: "
+                    + userClassName + "." + name));
+
+                // skip final, transient fields
+                if (field.isFinal()
+                    || field.isTransient()) {
+                    continue;
+                }
+
+                if (false) {
+                    System.out.println("Analyzer.scanFields(): declaring "
+                                       + className + "." + name + " : " + sig);
+                }
+                meta.declareField(className, name, sig);
+            }
+        }
+
+        // nr of fields needing accessor/mutator methods
+        annotatedFieldCount = annotatedFieldMap.size();
+        
+        // get managed field names from meta data
+        final String[] managedFieldNames = meta.getManagedFields(className);
+        affirm(managedFieldNames != null);
+        managedFieldCount = managedFieldNames.length;
+        final Set managedFieldNamesSet
+            = new HashSet(Arrays.asList(managedFieldNames));
+        affirm(managedFieldNamesSet.size() == managedFieldCount,
+               "JDO metadata: returned duplicate managed fields.");
+        affirm(managedFieldCount <= annotatedFieldCount,
+               "JDO metadata: managed fields exceed annotated fields.");
+
+        // data structures for key fields
+        final String[] keyFieldNames = meta.getKeyFields(className);
+        affirm(keyFieldNames != null);
+        keyFieldCount = keyFieldNames.length;
+        affirm(keyFieldCount == 0 || keyClassName != null,
+               "JDO metadata: returned key fields but no key class.");
+        final Set keyFieldNamesSet
+            = new HashSet(Arrays.asList(keyFieldNames));
+        affirm(keyFieldNamesSet.size() == keyFieldCount,
+               "JDO metadata: returned duplicate key fields.");
+        affirm(keyFieldCount <= managedFieldCount,
+               "JDO metadata: key fields exceed managed fields.");
+
+        // loop over class fields to compute 'jdo*' and key/managed fields
+        for (final Enumeration e = classFile.fields().elements();
+             e.hasMoreElements();) {
+            final ClassField field = (ClassField)e.nextElement();
+            final String name = field.name().asString();
+            final String sig = field.signature().asString();
+            final String userFieldName = userClassName + "." + name;
+            
+            if (false) {
+                System.out.println("Analyzer.scanFields(): scanning "
+                                   + className + "." + name + " : " + sig);
+            }
+
+            // map 'jdo*' field names to class fields
+            if (name.startsWith("jdo")) {
+                final Object f = jdoLikeFields.put(name, field);
+                affirm(f == null);
+            }
+
+            // skip non-managed fields
+            if (!managedFieldNamesSet.contains(name)) {
+                affirm(!meta.isManagedField(className, name));
+
+                // check for non-managed key field
+                affirm(!keyFieldNamesSet.contains(name),
+                       ("JDO metadata: reported the field " + userFieldName
+                        + " to be non-managed but key."));
+                continue;
+            }
+            affirm(meta.isManagedField(className, name));
+
+            // check for managed static field
+            affirm(!field.isStatic(),
+                   ("JDO metadata: reported the field " + userFieldName
+                    + " to be managed though it's static."));
+
+            // check for managed final field
+            affirm(!field.isFinal(),
+                   ("JDO metadata: reported the field " + userFieldName
+                    + " to be managed though it's final."));
+
+            // allow for managed transient fields
+
+//^olsen: adopt
+/*
+            r[i++] = hasField(
+                out,
+                Modifier.PRIVATE | Modifier.FINAL | Modifier.STATIC,
+                long.class,
+                "serialVersionUID");
+*/
+        }
+        
+        // get the managed field flags ordered by relative index
+        final int[] managedFieldFlags
+            = meta.getFieldFlags(className, managedFieldNames);
+
+        // compute the managed field types ordered by relative index
+        // and key field indexes
+        int j = 0;
+        keyFieldIndexes = new int[keyFieldCount];
+        final String[] managedFieldSigs = new String[managedFieldCount];
+        final int[] managedFieldMods = new int[managedFieldCount];
+        for (int i = 0; i < managedFieldCount; i++) {
+            final String name = managedFieldNames[i];
+            affirm(name != null);
+
+            // assert consistency between Java and JDO metadata
+            final ClassField field = (ClassField)annotatedFieldMap.get(name);
+            affirm(field != null,
+                   ("The managed field " + userClassName + "." + name +
+                    " is not declared by the class."));
+            affirm(!field.isStatic(),
+                   ("The managed field " + userClassName + "." + name +
+                    " is static."));
+            affirm(!field.isFinal(),
+                   ("The managed field " + userClassName + "." + name +
+                    " is final."));
+
+            // mark managed field as taken care of
+            annotatedFieldMap.remove(name);
+
+            // assign key field index
+            if (keyFieldNamesSet.contains(name)) {
+                affirm(meta.isKeyField(className, name));
+                keyFieldIndexes[j++] = i;
+            }
+            
+            // add field type and Java access modifers
+            managedFieldSigs[i] = field.signature().asString();
+            managedFieldMods[i] = field.access();
+
+            // set the serializable bit if field is not (Java) transient
+            // This code might be removed as soon as the metadata is able
+            // to retrieve the info as part of meta.getFieldFlags.
+            if (!field.isTransient()) {
+                managedFieldFlags[i] |= EnhancerMetaData.SERIALIZABLE;
+            }
+            
+            if (false) {
+                System.out.println("managed field: "
+                                   + className + "." + name + " : {");
+                System.out.println("    sigs = " + managedFieldSigs[i]);
+                System.out.println("    mods = "
+                                   + Integer.toHexString(managedFieldMods[i]));
+                System.out.println("    flags = "
+                                   + Integer.toHexString(managedFieldFlags[i]));
+            } 
+        }
+        
+        // post conditions of managed/key field processing
+        affirm(keyFieldIndexes.length == keyFieldCount);
+        affirm(keyFieldCount <= managedFieldCount);
+        affirm(managedFieldNames.length == managedFieldCount);
+        affirm(managedFieldSigs.length == managedFieldCount);
+        affirm(managedFieldMods.length == managedFieldCount);
+        affirm(managedFieldFlags.length == managedFieldCount);
+        affirm(managedFieldCount <= annotatedFieldCount);
+        
+        // assign the annotated field arrays
+        if (managedFieldCount == annotatedFieldCount) {
+            // return if the annotated fields are equal to the managed ones
+            annotatedFieldNames = managedFieldNames;
+            annotatedFieldSigs = managedFieldSigs;
+            annotatedFieldMods = managedFieldMods;
+            annotatedFieldFlags = managedFieldFlags;
+        } else {
+            // fill the annotated field arrays with the managed ones
+            annotatedFieldNames = new String[annotatedFieldCount];
+            annotatedFieldSigs = new String[annotatedFieldCount];
+            annotatedFieldMods = new int[annotatedFieldCount];
+            annotatedFieldFlags = new int[annotatedFieldCount];
+            int i = managedFieldCount;
+            System.arraycopy(managedFieldNames, 0, annotatedFieldNames, 0, i);
+            System.arraycopy(managedFieldSigs, 0, annotatedFieldSigs, 0, i);
+            System.arraycopy(managedFieldMods, 0, annotatedFieldMods, 0, i);
+            System.arraycopy(managedFieldFlags, 0, annotatedFieldFlags, 0, i);
+
+            // append the annotated, non-managed fields
+            for (Iterator k = annotatedFieldMap.entrySet().iterator();
+                 k.hasNext();) {
+                final Map.Entry entry = (Map.Entry)k.next();
+                final String name = (String)entry.getKey();
+                final ClassField field = (ClassField)entry.getValue();
+                affirm(name.equals(field.name().asString()));
+
+                affirm(!field.isStatic(),
+                       ("The managed field " + userClassName + "." + name +
+                        " is static."));
+
+                // add field type and Java access modifers
+                annotatedFieldNames[i] = name;
+                annotatedFieldSigs[i] = field.signature().asString();
+                annotatedFieldMods[i] = field.access();
+                annotatedFieldFlags[i] = 0x0; // direct read/write access
+                i++;
+            }
+            affirm(i == annotatedFieldCount);
+        }
+        
+        // post conditions
+        affirm(keyFieldIndexes.length == keyFieldCount);
+        affirm(keyFieldCount <= managedFieldCount);
+        affirm(annotatedFieldNames.length == annotatedFieldCount);
+        affirm(annotatedFieldSigs.length == annotatedFieldCount);
+        affirm(annotatedFieldMods.length == annotatedFieldCount);
+        affirm(annotatedFieldFlags.length == annotatedFieldCount);
+        affirm(managedFieldCount <= annotatedFieldCount);
+    }
+
+    /**
+     * Scans the methods of a ClassFile.
+     */
+    private void scanMethods()
+    {
+        // check methods
+        for (final Enumeration e = classFile.methods().elements();
+             e.hasMoreElements();) {
+            final ClassMethod method = (ClassMethod)e.nextElement();
+            final String name = method.name().asString();
+            final String sig = method.signature().asString();
+            affirm(name != null);
+            affirm(sig != null);
+
+            final String key = methodKey(name, sig);
+            affirm(key != null);
+
+            // for non-abstract, non-native methods, map names to class methods
+            if (!method.isAbstract() && !method.isNative()) {
+                final Object m = annotatableMethods.put(key, method);
+                affirm(m == null);
+            }
+
+            // for 'jdo*' like methods, map names to class methods
+            if (name.startsWith("jdo")) {
+                final Object m = jdoLikeMethods.put(key, method);
+                affirm(m == null);
+                continue;
+            }
+
+            // check for a default constructor by name and signature
+            if (name.equals(NameHelper.constructorName())
+                && sig.equals(NameHelper.constructorSig())) {
+                hasDefaultConstructor = true;
+                continue;
+            }
+            
+            // check for a static initializer block by name and signature
+            if (name.equals(JAVA_clinit_Name)
+                && sig.equals(JAVA_clinit_Sig)) {
+                hasStaticInitializer = true;
+                continue;
+            }
+
+            // check for method clone() by name and signature
+            if (name.equals(JAVA_Object_clone_Name)
+                && sig.equals(JAVA_Object_clone_Sig)) {
+                hasCloneMethod = true;
+                continue;
+            }
+
+            // check for method writeObject() by name and signature
+            if (name.equals(JAVA_Object_writeObject_Name)
+                && sig.equals(JAVA_Object_writeObject_Sig)) {
+                hasWriteObjectMethod = true;
+                continue;
+            }
+
+            // check for method writeReplace() by name and signature
+            if (name.equals(JAVA_Object_writeReplace_Name)
+                && sig.equals(JAVA_Object_writeReplace_Sig)) {
+                hasWriteReplaceMethod = true;
+                continue;
+            }
+
+            // check for method readObject() by name and signature
+            if (name.equals(JAVA_Object_readObject_Name)
+                && sig.equals(JAVA_Object_readObject_Sig)) {
+                hasReadObjectMethod = true;
+
+                // remove readObject() method from annotation candidates
+                Object m = annotatableMethods.remove(key);
+                affirm(m != null);
+                continue;
+            }
+        }
+
+        // check for a default constructor by name and signature
+        if (hasDefaultConstructor) {
+            env.message(getI18N("enhancer.class_has_default_constructor"));
+        } else {
+            env.message(getI18N("enhancer.class_has_not_default_constructor"));
+        }
+            
+        // check for a static initializer block by name and signature
+        if (hasStaticInitializer) {
+            env.message(getI18N("enhancer.class_has_static_initializer"));
+        } else {
+            env.message(getI18N("enhancer.class_has_not_static_initializer"));
+        }
+
+        // check for method clone() by name and signature
+        if (hasCloneMethod) {
+            env.message(getI18N("enhancer.class_has_clone_method"));
+        } else {
+            env.message(getI18N("enhancer.class_has_not_clone_method"));
+        }
+
+        // check for method writeObject() by name and signature
+        if (hasWriteObjectMethod) {
+            env.message(getI18N("enhancer.class_has_writeObject_method"));
+        } else {
+            env.message(getI18N("enhancer.class_has_not_writeObject_method"));
+        }
+
+        // check for method writeReplace() by name and signature
+        if (hasWriteReplaceMethod) {
+            env.message(getI18N("enhancer.class_has_writeReplace_method"));
+        } else {
+            env.message(getI18N("enhancer.class_has_not_writeReplace_method"));
+        }
+
+        // check for method readObject() by name and signature
+        if (hasReadObjectMethod) {
+            env.message(getI18N("enhancer.class_has_readObject_method"));
+        } else {
+            env.message(getI18N("enhancer.class_has_not_readObject_method"));
+        }
+    }
+
+    private void checkGenericAugmentation()
+    {
+        scanForImplementsPC();
+        scanForGenericJDOFields();
+        scanForGenericJDOMethods();
+
+        final boolean all
+            = (hasImplementsPC && hasGenericJDOFields && hasGenericJDOMethods);
+        //^olsen: check
+        final boolean none
+            = !(hasImplementsPC
+                || hasGenericJDOFields || hasGenericJDOMethods);
+
+        if (all ^ none) {
+            hasGenericJDOMembers = hasImplementsPC;
+            env.message(
+                getI18N("enhancer.class_has_generic_jdo_members",
+                        String.valueOf(hasGenericJDOMembers)));
+
+            //^olsen: check for specific enhancement
+
+            return;
+        }
+
+        final String key
+            = "enhancer.class_has_inconsistently_declared_jdo_members";
+        if (hasGenericJDOFields && !hasGenericJDOMethods) {
+            env.error(
+                getI18N(key,
+                        userClassName,
+                        "<generic jdo fields>",
+                        "<generic jdo methods>"));
+        } else if (!hasGenericJDOFields && hasGenericJDOMethods) {
+            env.error(
+                getI18N(key,
+                        userClassName,
+                        "<generic jdo methods>",
+                        "<generic jdo fields>"));
+        } else if (!hasGenericJDOFields && !hasGenericJDOMethods) {
+            env.error(
+                getI18N(key,
+                        userClassName,
+                        "<implements " + JDO_PersistenceCapable_Name + ">",
+                        "<generic jdo members>"));
+        } else {
+            env.error(
+                getI18N(key,
+                        userClassName,
+                        "<generic jdo members>",
+                        "<implements " + JDO_PersistenceCapable_Name + ">"));
+        }
+    }
+    
+    private void checkSpecificAugmentation()
+    {
+        scanForSpecificJDOFields();
+        scanForSpecificJDOMethods();
+
+        final boolean all
+            = (hasSpecificJDOFields && hasSpecificJDOMethods);
+        //^olsen: check
+        final boolean none
+            = !(hasSpecificJDOFields || hasSpecificJDOMethods);
+
+        if (all ^ none) {
+            hasSpecificJDOMembers = hasSpecificJDOFields;
+            env.message(
+                getI18N("enhancer.class_has_specific_jdo_members",
+                        String.valueOf(hasSpecificJDOMembers)));
+            return;
+        }
+
+        final String key
+            = "enhancer.class_has_inconsistently_declared_jdo_members";
+        if (hasSpecificJDOFields && !hasSpecificJDOMethods) {
+            env.error(
+                getI18N(key,
+                        userClassName,
+                        "<specific jdo fields>",
+                        "<specific jdo methods>"));
+        } else {
+            env.error(
+                getI18N(key,
+                        userClassName,
+                        "<specific jdo methods>",
+                        "<specific jdo fields>"));
+        }
+    }
+    
+    private void checkCallbackAugmentation()
+    {
+        scanForCallbackJDOMethods();
+        env.message(
+            getI18N("enhancer.class_has_callback_jdo_methods",
+                    String.valueOf(hasCallbackJDOMethods)));
+    }
+    
+    private void checkPCFeasibility()
+    {
+        if (!hasDefaultConstructor) {
+            env.error(
+                getI18N("enhancer.class_missing_default_constructor",
+                        userClassName));
+        }
+    }
+    
+    /**
+     * Scans the class for implementing the PC interface.
+     */
+    private void scanForImplementsPC()
+    {
+        hasImplementsPC = false;
+        for (final Iterator ifc = classFile.interfaces().iterator();
+             ifc.hasNext();) {
+            final ConstClass i = (ConstClass)ifc.next();
+            if (i.asString().equals(JDO_PersistenceCapable_Path)) {
+                hasImplementsPC = true;
+                break;
+            }
+        }
+        env.message(
+            getI18N("enhancer.class_implements_jdo_pc",
+                    String.valueOf(hasImplementsPC)));
+    }
+
+    /**
+     * Scans for JDO fields of generic augmentation.
+     */
+    private void scanForGenericJDOFields()
+    {
+        // performance shortcut
+        if (jdoLikeFields.isEmpty()) {
+            hasGenericJDOFields = false;
+            env.message(
+                getI18N("enhancer.class_has_generic_jdo_fields",
+                        String.valueOf(hasGenericJDOFields)));
+            return;
+        }
+
+        // sets of found/missing 'jdo*' members
+        final Set found = new HashSet(10);
+        final Set missing = new HashSet(10);
+
+        scanJDOField(JDO_PC_jdoStateManager_Name,
+                     JDO_PC_jdoStateManager_Sig,
+                     JDO_PC_jdoStateManager_Mods,
+                     found, missing);
+        scanJDOField(JDO_PC_jdoFlags_Name,
+                     JDO_PC_jdoFlags_Sig,
+                     JDO_PC_jdoFlags_Mods,
+                     found, missing);
+
+        if (found.isEmpty() ^ missing.isEmpty()) {
+            hasGenericJDOFields = missing.isEmpty();
+            env.message(
+                getI18N("enhancer.class_has_generic_jdo_fields",
+                        String.valueOf(hasGenericJDOFields)));
+            return;
+        }
+
+        reportInconsistentJDOMembers(found, missing);
+    }
+
+    /**
+     * Scans for JDO methods of generic augmentation.
+     */
+    private void scanForGenericJDOMethods()
+    {
+        // performance shortcut
+        if (jdoLikeMethods.isEmpty()) {
+            hasGenericJDOMethods = false;
+            env.message(
+                getI18N("enhancer.class_has_generic_jdo_methods",
+                        String.valueOf(hasGenericJDOMethods)));
+            return;
+        }
+
+        // sets of found/missing 'jdo*' members
+        final Set found = new HashSet(30);
+        final Set missing = new HashSet(30);
+
+        scanJDOMethod(JDO_PC_jdoReplaceStateManager_Name,
+                      JDO_PC_jdoReplaceStateManager_Sig,
+                      JDO_PC_jdoReplaceStateManager_Mods,
+                      found, missing);
+        scanJDOMethod(JDO_PC_jdoReplaceFlags_Name,
+                      JDO_PC_jdoReplaceFlags_Sig,
+                      JDO_PC_jdoReplaceFlags_Mods,
+                      found, missing);
+        scanJDOMethod(JDO_PC_jdoGetPersistenceManager_Name,
+                      JDO_PC_jdoGetPersistenceManager_Sig,
+                      JDO_PC_jdoGetPersistenceManager_Mods,
+                      found, missing);
+        scanJDOMethod(JDO_PC_jdoGetObjectId_Name,
+                      JDO_PC_jdoGetObjectId_Sig,
+                      JDO_PC_jdoGetObjectId_Mods,
+                      found, missing);
+        scanJDOMethod(JDO_PC_jdoGetTransactionalObjectId_Name,
+                      JDO_PC_jdoGetTransactionalObjectId_Sig,
+                      JDO_PC_jdoGetTransactionalObjectId_Mods,
+                      found, missing);
+        scanJDOMethod(JDO_PC_jdoIsPersistent_Name,
+                      JDO_PC_jdoIsPersistent_Sig,
+                      JDO_PC_jdoIsPersistent_Mods,
+                      found, missing);
+        scanJDOMethod(JDO_PC_jdoIsTransactional_Name,
+                      JDO_PC_jdoIsTransactional_Sig,
+                      JDO_PC_jdoIsTransactional_Mods,
+                      found, missing);
+        scanJDOMethod(JDO_PC_jdoIsNew_Name,
+                      JDO_PC_jdoIsNew_Sig,
+                      JDO_PC_jdoIsNew_Mods,
+                      found, missing);
+        scanJDOMethod(JDO_PC_jdoIsDeleted_Name,
+                      JDO_PC_jdoIsDeleted_Sig,
+                      JDO_PC_jdoIsDeleted_Mods,
+                      found, missing);
+        scanJDOMethod(JDO_PC_jdoIsDirty_Name,
+                      JDO_PC_jdoIsDirty_Sig,
+                      JDO_PC_jdoIsDirty_Mods,
+                      found, missing);
+        scanJDOMethod(JDO_PC_jdoMakeDirty_Name,
+                      JDO_PC_jdoMakeDirty_Sig,
+                      JDO_PC_jdoMakeDirty_Mods,
+                      found, missing);
+        scanJDOMethod(JDO_PC_jdoPreSerialize_Name,
+                      JDO_PC_jdoPreSerialize_Sig,
+                      JDO_PC_jdoPreSerialize_Mods,
+                      found, missing);
+        scanJDOMethod(JDO_PC_jdoReplaceFields_Name,
+                      JDO_PC_jdoReplaceFields_Sig,
+                      JDO_PC_jdoReplaceFields_Mods,
+                      found, missing);
+        scanJDOMethod(JDO_PC_jdoProvideFields_Name,
+                      JDO_PC_jdoProvideFields_Sig,
+                      JDO_PC_jdoProvideFields_Mods,
+                      found, missing);
+
+        if (found.isEmpty() ^ missing.isEmpty()) {
+            hasGenericJDOMethods = missing.isEmpty();
+            env.message(
+                getI18N("enhancer.class_has_generic_jdo_methods",
+                        String.valueOf(hasGenericJDOMethods)));
+            return;
+        }
+
+        reportInconsistentJDOMembers(found, missing);
+    }
+
+    /**
+     * Scans for JDO fields of specific augmentation.
+     */
+    private void scanForSpecificJDOFields()
+    {
+        // performance shortcut
+        if (jdoLikeFields.isEmpty()) {
+            hasSpecificJDOFields = false;
+            env.message(
+                getI18N("enhancer.class_has_specific_jdo_fields",
+                        String.valueOf(hasSpecificJDOFields)));
+            return;
+        }
+
+        // sets of found/missing 'jdo*' members
+        final Set found = new HashSet(10);
+        final Set missing = new HashSet(10);
+
+        scanJDOField(JDO_PC_jdoInheritedFieldCount_Name,
+                     JDO_PC_jdoInheritedFieldCount_Sig,
+                     JDO_PC_jdoInheritedFieldCount_Mods,
+                     found, missing);
+        scanJDOField(JDO_PC_jdoFieldNames_Name,
+                     JDO_PC_jdoFieldNames_Sig,
+                     JDO_PC_jdoFieldNames_Mods,
+                     found, missing);
+        scanJDOField(JDO_PC_jdoFieldTypes_Name,
+                     JDO_PC_jdoFieldTypes_Sig,
+                     JDO_PC_jdoFieldTypes_Mods,
+                     found, missing);
+        scanJDOField(JDO_PC_jdoFieldFlags_Name,
+                     JDO_PC_jdoFieldFlags_Sig,
+                     JDO_PC_jdoFieldFlags_Mods,
+                     found, missing);
+        scanJDOField(JDO_PC_jdoPersistenceCapableSuperclass_Name,
+                     JDO_PC_jdoPersistenceCapableSuperclass_Sig,
+                     JDO_PC_jdoPersistenceCapableSuperclass_Mods,
+                     found, missing);
+
+        if (found.isEmpty() ^ missing.isEmpty()) {
+            hasSpecificJDOFields = missing.isEmpty();
+            env.message(
+                getI18N("enhancer.class_has_specific_jdo_fields",
+                        String.valueOf(hasSpecificJDOFields)));
+            return;
+        }
+
+        reportInconsistentJDOMembers(found, missing);
+    }
+
+    /**
+     * Scans for JDO methods of specific augmentation.
+     */
+    private void scanForSpecificJDOMethods()
+    {
+        // performance shortcut
+        if (jdoLikeMethods.isEmpty()) {
+            hasSpecificJDOMethods = false;
+            env.message(
+                getI18N("enhancer.class_has_specific_jdo_methods",
+                        String.valueOf(hasSpecificJDOMethods)));
+            return;
+        }
+
+        // sets of found/missing 'jdo*' members
+        final Set found = new HashSet(30);
+        final Set missing = new HashSet(30);
+
+        scanJDOMethod(JDO_PC_jdoGetManagedFieldCount_Name,
+                      JDO_PC_jdoGetManagedFieldCount_Sig,
+                      JDO_PC_jdoGetManagedFieldCount_Mods,
+                      found, missing);
+        scanJDOMethod(JDO_PC_jdoNewInstance_Name,
+                      JDO_PC_jdoNewInstance_Sig,
+                      JDO_PC_jdoNewInstance_Mods,
+                      found, missing);
+        scanJDOMethod(JDO_PC_jdoNewInstance_Name,
+                      JDO_PC_jdoNewInstance_Sig,
+                      JDO_PC_jdoNewInstance_Mods,
+                      found, missing);
+        scanJDOMethod(JDO_PC_jdoNewObjectIdInstance_Name,
+                      JDO_PC_jdoNewObjectIdInstance_Sig,
+                      JDO_PC_jdoNewObjectIdInstance_Mods,
+                      found, missing);
+        scanJDOMethod(JDO_PC_jdoNewObjectIdInstance_Name,
+                      JDO_PC_jdoNewObjectIdInstance_Sig,
+                      JDO_PC_jdoNewObjectIdInstance_Mods,
+                      found, missing);
+        scanJDOMethod(JDO_PC_jdoCopyKeyFieldsToObjectId_Name,
+                      JDO_PC_jdoCopyKeyFieldsToObjectId_Sig,
+                      JDO_PC_jdoCopyKeyFieldsToObjectId_Mods,
+                      found, missing);
+        scanJDOMethod(JDO_PC_jdoCopyKeyFieldsToObjectId_OIFS_Name,
+                      JDO_PC_jdoCopyKeyFieldsToObjectId_OIFS_Sig,
+                      JDO_PC_jdoCopyKeyFieldsToObjectId_OIFS_Mods,
+                      found, missing);
+        scanJDOMethod(JDO_PC_jdoCopyKeyFieldsFromObjectId_OIFC_Name,
+                      JDO_PC_jdoCopyKeyFieldsFromObjectId_OIFC_Sig,
+                      JDO_PC_jdoCopyKeyFieldsFromObjectId_OIFC_Mods,
+                      found, missing);
+        scanJDOMethod(JDO_PC_jdoReplaceField_Name,
+                      JDO_PC_jdoReplaceField_Sig,
+                      JDO_PC_jdoReplaceField_Mods,
+                      found, missing);
+        scanJDOMethod(JDO_PC_jdoProvideField_Name,
+                      JDO_PC_jdoProvideField_Sig,
+                      JDO_PC_jdoProvideField_Mods,
+                      found, missing);
+        scanJDOMethod(JDO_PC_jdoCopyFields_Name,
+                      JDO_PC_jdoCopyFields_Sig,
+                      JDO_PC_jdoCopyFields_Mods,
+                      found, missing);
+        scanJDOMethod(JDO_PC_jdoCopyField_Name,
+                      JDONameHelper.getJDO_PC_jdoCopyField_Sig(className),
+                      JDO_PC_jdoCopyField_Mods,
+                      found, missing);
+
+        if (found.isEmpty() ^ missing.isEmpty()) {
+            hasSpecificJDOMethods = missing.isEmpty();
+            env.message(
+                getI18N("enhancer.class_has_specific_jdo_methods",
+                        String.valueOf(hasSpecificJDOMethods)));
+            return;
+        }
+
+        reportInconsistentJDOMembers(found, missing);
+    }
+
+    /**
+     * Scans for JDO methods of generic augmentation.
+     */
+    private void scanForCallbackJDOMethods()
+    {
+        // performance shortcut
+        if (jdoLikeMethods.isEmpty()) {
+            hasCallbackJDOMethods = false;
+            env.message(
+                getI18N("enhancer.class_has_callback_jdo_methods",
+                        String.valueOf(hasCallbackJDOMethods)));
+            return;
+        }
+
+        // sets of found/missing 'jdo*' members
+        final Set found = new HashSet(30);
+        final Set missing = new HashSet(30);
+        final boolean annotatable = true;
+
+        scanJDOMethod(JDO_IC_jdoPostLoad_Name,
+                      JDO_IC_jdoPostLoad_Sig,
+                      JDO_IC_jdoPostLoad_Mods,
+                      found, missing, !annotatable);
+
+        scanJDOMethod(JDO_IC_jdoPreStore_Name,
+                      JDO_IC_jdoPreStore_Sig,
+                      JDO_IC_jdoPreStore_Mods,
+                      found, missing, annotatable);
+
+        scanJDOMethod(JDO_IC_jdoPreClear_Name,
+                      JDO_IC_jdoPreClear_Sig,
+                      JDO_IC_jdoPreClear_Mods,
+                      found, missing, !annotatable);
+
+        scanJDOMethod(JDO_IC_jdoPreDelete_Name,
+                      JDO_IC_jdoPreDelete_Sig,
+                      JDO_IC_jdoPreDelete_Mods,
+                      found, missing, annotatable);
+
+        // no requirement to check for 'missing' methods
+        if (!found.isEmpty()) {
+            hasCallbackJDOMethods = true;
+            env.message(
+                getI18N("enhancer.class_has_callback_jdo_methods",
+                        String.valueOf(hasCallbackJDOMethods)));
+        }
+    }
+
+    /**
+     * Verifies a JDO field signature.
+     */
+    private void scanJDOField(String fieldName,
+                              String expectedSig,
+                              int expectedMods,
+                              Set found,
+                              Set missing)
+    {
+        final ClassField field = (ClassField)jdoLikeFields.get(fieldName);
+        if (field == null) {
+            missing.add(fieldName);
+            return;
+        }
+        found.add(fieldName);
+
+        final String foundSig = field.signature().asString();
+        final int foundMods = field.access();
+        if (!expectedSig.equals(foundSig) || expectedMods != foundMods) {
+            env.error(
+                getI18N("enhancer.class_has_illegally_declared_jdo_member",
+                        new Object[]{ userClassName,
+                                      fieldName,
+                                      expectedSig,
+                                      foundSig,
+                                      new Integer(expectedMods),
+                                      new Integer(foundMods) }));
+        }
+    }
+
+    /**
+     * Verifies a JDO method signature.
+     */
+    private void scanJDOMethod(String methodName,
+                               String expectedSig,
+                               int expectedMods,
+                               Set found,
+                               Set missing)
+    {
+        scanJDOMethod(methodName, expectedSig, expectedMods,
+                      found, missing, true);
+    }
+
+    /**
+     * Verifies a JDO method signature.
+     */
+    private void scanJDOMethod(String methodName,
+                               String expectedSig,
+                               int expectedMods,
+                               Set found,
+                               Set missing,
+                               boolean annotatable)
+    {
+        final String key = methodKey(methodName, expectedSig);
+        final ClassMethod method = (ClassMethod)jdoLikeMethods.get(key);
+        if (method == null) {
+            missing.add(key);
+            return;
+        }
+        found.add(key);
+
+        final String foundSig = method.signature().asString();
+        final int foundMods = method.access();
+        if (!expectedSig.equals(foundSig) || expectedMods != foundMods) {
+            env.error(
+                getI18N("enhancer.class_has_illegally_declared_jdo_member",
+                        new Object[]{ userClassName,
+                                      methodName,
+                                      expectedSig,
+                                      foundSig,
+                                      new Integer(expectedMods),
+                                      new Integer(foundMods) }));
+        }
+
+        // remove jdo method from annotation candidates
+        if (!annotatable) {
+            Object m = annotatableMethods.remove(key);
+            affirm(m != null);
+        }
+    }
+
+    /**
+     * Reports an error for some found/missing JDO fields or methods.
+     */
+    private void reportInconsistentJDOMembers(Set found,
+                                              Set missing)
+    {
+        final Iterator fi = found.iterator();
+        final StringBuffer f = new StringBuffer((String)fi.next());
+        while (fi.hasNext()) {
+            f.append(", " + fi.next());
+        }
+
+        final Iterator mi = found.iterator();
+        final StringBuffer m = new StringBuffer((String)mi.next());
+        while (mi.hasNext()) {
+            m.append(", " + mi.next());
+        }
+
+        env.error(
+            getI18N("enhancer.class_has_inconsistently_declared_jdo_members",
+                    userClassName, f.toString(), m.toString()));
+    }
+
+    // ----------------------------------------------------------------------
+    
+    static private String methodKey(String name,
+                                    String sig)
+    {
+        affirm(name != null);
+        affirm(sig != null && sig.charAt(0) == '(' && sig.indexOf(')') > 0);
+        final String parms = sig.substring(0, sig.indexOf(')') + 1);
+        return (name + parms);
+    }
+}



Mime
View raw message