You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pc...@apache.org on 2006/06/28 21:46:19 UTC

svn commit: r417860 [10/12] - in /incubator/openjpa/trunk: ./ openjpa-lib/ openjpa-lib/main/ openjpa-lib/src/ openjpa-lib/src/main/ openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/ openjpa-lib/src/test/ openjpa-lib/src/test/java/ openjpa-lib/src/...

Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/ComplexEntry.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/ComplexEntry.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/ComplexEntry.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/ComplexEntry.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2006 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 serp.bytecode.lowlevel;
+
+import java.io.*;
+
+
+/**
+ *  <p>Base class for field, method, and interface method constant pool
+ *  entries. All complex entries reference the {@link ClassEntry} of the
+ *  class that owns the entity and a {@link NameAndTypeEntry} describing
+ *  the entity.</p>
+ *
+ *  @author Abe White
+ */
+public abstract class ComplexEntry extends Entry {
+    private int _classIndex = 0;
+    private int _nameAndTypeIndex = 0;
+
+    /**
+     *  Default constructor.
+     */
+    public ComplexEntry() {
+    }
+
+    /**
+     *  Constructor.
+     *
+     *  @param classIndex                        the constant pool index of the
+     *                                                          {@link ClassEntry} describing the owner
+      *                                                          of this entity
+     *  @param nameAndTypeIndex        the constant pool index of the
+     *                                                          {@link NameAndTypeEntry} describing this
+     *                                                          entity
+     */
+    public ComplexEntry(int classIndex, int nameAndTypeIndex) {
+        _classIndex = classIndex;
+        _nameAndTypeIndex = nameAndTypeIndex;
+    }
+
+    /**
+     *  Return the constant pool index of the {@link ClassEntry} describing
+     *  the owning class of this entity.  Defaults to 0.
+     */
+    public int getClassIndex() {
+        return _classIndex;
+    }
+
+    /**
+     *  Set the constant pool index of the {@link ClassEntry} describing
+     *  the owning class of this entity.
+     */
+    public void setClassIndex(int classIndex) {
+        Object key = beforeModify();
+        _classIndex = classIndex;
+        afterModify(key);
+    }
+
+    /**
+     *  Return the referenced {@link ClassEntry}.  This method can only
+     *  be run for entries that have been added to a constant pool.
+     */
+    public ClassEntry getClassEntry() {
+        return (ClassEntry) getPool().getEntry(_classIndex);
+    }
+
+    /**
+     *  Return the constant pool index of the {@link NameAndTypeEntry}
+     *  describing this entity.
+     */
+    public int getNameAndTypeIndex() {
+        return _nameAndTypeIndex;
+    }
+
+    /**
+     *  Set the constant pool index of the {@link NameAndTypeEntry}
+     *  describing this entity.
+     */
+    public void setNameAndTypeIndex(int nameAndTypeIndex) {
+        Object key = beforeModify();
+        _nameAndTypeIndex = nameAndTypeIndex;
+        afterModify(key);
+    }
+
+    /**
+     *  Return the referenced {@link NameAndTypeEntry}.  This method can only
+     *  be run for entries that have been added to a constant pool.
+     */
+    public NameAndTypeEntry getNameAndTypeEntry() {
+        return (NameAndTypeEntry) getPool().getEntry(_nameAndTypeIndex);
+    }
+
+    void readData(DataInput in) throws IOException {
+        _classIndex = in.readUnsignedShort();
+        _nameAndTypeIndex = in.readUnsignedShort();
+    }
+
+    void writeData(DataOutput out) throws IOException {
+        out.writeShort(_classIndex);
+        out.writeShort(_nameAndTypeIndex);
+    }
+}

Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/ComplexEntry.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/ConstantEntry.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/ConstantEntry.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/ConstantEntry.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/ConstantEntry.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2006 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 serp.bytecode.lowlevel;
+
+
+/**
+ *  <p>Interface implemented by entries representing constant values.  Allows
+ *  generic access the constant value regardless of type.</p>
+ *
+ *  @author Abe White
+ */
+public interface ConstantEntry {
+    /**
+     *  Return the value of the constant held by this entry.</p>
+     */
+    public Object getConstant();
+
+    /**
+     *  Set the value of the constant held by this entry.</p>
+     */
+    public void setConstant(Object value);
+}

Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/ConstantEntry.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/ConstantPool.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/ConstantPool.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/ConstantPool.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/ConstantPool.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,725 @@
+/*
+ * Copyright 2006 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 serp.bytecode.lowlevel;
+
+import serp.bytecode.visitor.*;
+
+import serp.util.*;
+
+import java.io.*;
+
+import java.util.*;
+
+
+/**
+ *  <p>A bytecode constant pool, containing entries for all strings,
+ *  constants, classes, etc referenced in the class structure and method
+ *  opcodes.  In keeping with the low-level bytecode representation, all pool
+ *  indexes are 1-based and {@link LongEntry}s and {@link DoubleEntry}s each
+ *  occupy two indexes in the pool.</p>
+ *
+ *  @author Abe White
+ */
+public class ConstantPool implements VisitAcceptor {
+    private List _entries = new ArrayList(50);
+    private Map _lookup = new HashMap(50);
+
+    /**
+     *  Default constructor.
+     */
+    public ConstantPool() {
+    }
+
+    /**
+      *  Return all the entries in the pool.
+     */
+    public Entry[] getEntries() {
+        List entries = new ArrayList(_entries.size());
+        Entry entry;
+
+        for (Iterator itr = _entries.iterator(); itr.hasNext();) {
+            entry = (Entry) itr.next();
+
+            if (entry != null) {
+                entries.add(entry);
+            }
+        }
+
+        return (Entry[]) entries.toArray(new Entry[entries.size()]);
+    }
+
+    /**
+     *  Retrieve the entry at the specified 1-based index.
+     *
+     *  @throws IndexOutOfBoundsException if index is invalid,
+     *                          including the case that it points to the second slot of a
+     *                          long or double entry
+     */
+    public Entry getEntry(int index) {
+        Entry entry = (Entry) _entries.get(index - 1);
+
+        if (entry == null) {
+            throw new IndexOutOfBoundsException("index = " + index);
+        }
+
+        return entry;
+    }
+
+    /**
+     *  Return the index of the given entry, or 0 if it is not in the pool.
+     */
+    public int indexOf(Entry entry) {
+        if ((entry == null) || (entry.getPool() != this)) {
+            return 0;
+        }
+
+        return entry.getIndex();
+    }
+
+    /**
+     *  Add an entry to the pool.
+      *
+     *  @return the index at which the entry was added
+     */
+    public int addEntry(Entry entry) {
+        if (entry.getPool() != this) {
+            addEntry(getKey(entry), entry);
+        }
+
+        return entry.getIndex();
+    }
+
+    /**
+     *  Add an entry to the pool using the given key.
+     */
+    private int addEntry(Object key, Entry entry) {
+        entry.setPool(this);
+        _entries.add(entry);
+        entry.setIndex(_entries.size());
+
+        _lookup.put(key, entry);
+
+        if (entry.isWide()) {
+            _entries.add(null);
+        }
+
+        return entry.getIndex();
+    }
+
+    /**
+     *  Remove the given entry from the pool.
+     *
+     *  @return false if the entry is not in the pool, true otherwise
+     */
+    public boolean removeEntry(Entry entry) {
+        if ((entry == null) || (entry.getPool() != this)) {
+            return false;
+        }
+
+        int index = entry.getIndex() - 1;
+        entry.setPool(null);
+        entry.setIndex(0);
+
+        _entries.remove(index);
+
+        if (entry.isWide()) {
+            _entries.remove(index);
+        }
+
+        _lookup.remove(getKey(entry));
+
+        // rehash all the entries after the removed one with their new index
+        Object key;
+
+        for (int i = index; i < _entries.size(); i++) {
+            entry = (Entry) _entries.get(i);
+
+            if (entry != null) {
+                key = getKey(entry);
+                _lookup.remove(key);
+                entry.setIndex(i + 1);
+                _lookup.put(key, entry);
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     *  Clear all entries from the pool.
+     */
+    public void clear() {
+        Entry entry;
+
+        for (Iterator itr = _entries.iterator(); itr.hasNext();) {
+            entry = (Entry) itr.next();
+
+            if (entry != null) {
+                entry.setPool(null);
+                entry.setIndex(0);
+            }
+        }
+
+        _entries.clear();
+        _lookup.clear();
+    }
+
+    /**
+     *  Return the number of places occupied in the pool, including the fact
+      *  that long and double entries occupy two places.
+     */
+    public int size() {
+        return _entries.size();
+    }
+
+    /**
+     *  Return the index of the {@link UTF8Entry} with the given value, or
+     *  0 if it does not exist.
+     *
+     *  @param add                if true, the entry will be added if it does not
+     *                                  already exist, and the new entry's index returned
+     */
+    public int findUTF8Entry(String value, boolean add) {
+        if (value == null) {
+            if (add) {
+                throw new NullPointerException("value = null");
+            }
+
+            return 0;
+        }
+
+        int index = find(value);
+
+        if (!add || (index > 0)) {
+            return index;
+        }
+
+        return addEntry(value, new UTF8Entry(value));
+    }
+
+    /**
+     *  Return the constant pool index of the {@link DoubleEntry} for the given
+     *  value, or 0 if it does not exist.
+      *
+     *  @param value        the value to find
+     *  @param add                if true, the entry will be added if it does not
+     *                                  already exist, and the new entry's index returned
+      */
+    public int findDoubleEntry(double value, boolean add) {
+        Double key = new Double(value);
+        int index = find(key);
+
+        if (!add || (index > 0)) {
+            return index;
+        }
+
+        return addEntry(key, new DoubleEntry(value));
+    }
+
+    /**
+     *  Return the constant pool index of the {@link FloatEntry} for the given
+     *  value, or 0 if it does not exist.
+      *
+     *  @param value        the value to find
+     *  @param add                if true, the entry will be added if it does not
+     *                                  already exist, and the new entry's index returned
+      */
+    public int findFloatEntry(float value, boolean add) {
+        Float key = new Float(value);
+        int index = find(key);
+
+        if (!add || (index > 0)) {
+            return index;
+        }
+
+        return addEntry(key, new FloatEntry(value));
+    }
+
+    /**
+     *  Return the constant pool index of the {@link IntEntry} for the given
+     *  value, or 0 if it does not exist.
+      *
+     *  @param value        the value to find
+     *  @param add                if true, the entry will be added if it does not
+     *                                  already exist, and the new entry's index returned
+      */
+    public int findIntEntry(int value, boolean add) {
+        Integer key = Numbers.valueOf(value);
+        int index = find(key);
+
+        if (!add || (index > 0)) {
+            return index;
+        }
+
+        return addEntry(key, new IntEntry(value));
+    }
+
+    /**
+     *  Return the constant pool index of the {@link LongEntry} for the given
+     *  value, or 0 if it does not exist.
+      *
+     *  @param value        the value to find
+     *  @param add                if true, the entry will be added if it does not
+     *                                  already exist, and the new entry's index returned
+      */
+    public int findLongEntry(long value, boolean add) {
+        Long key = Numbers.valueOf(value);
+        int index = find(key);
+
+        if (!add || (index > 0)) {
+            return index;
+        }
+
+        return addEntry(key, new LongEntry(value));
+    }
+
+    /**
+     *  Return the constant pool index of the {@link StringEntry} for the given
+     *  string value, or 0 if it does not exist.
+      *
+     *  @param value        the value to find
+     *  @param add                if true, the entry will be added if it does not
+     *                                  already exist, and the new entry's index returned
+      */
+    public int findStringEntry(String value, boolean add) {
+        int valueIndex = findUTF8Entry(value, add);
+
+        if (valueIndex == 0) {
+            return 0;
+        }
+
+        StringKey key = new StringKey(valueIndex);
+        int index = find(key);
+
+        if (!add || (index > 0)) {
+            return index;
+        }
+
+        return addEntry(key, new StringEntry(valueIndex));
+    }
+
+    /**
+     *  Return the constant pool index of the {@link ClassEntry} for the given
+     *  class name, or 0 if it does not exist.
+      *
+     *  @param name        the class name in internal form
+     *  @param add                if true, the entry will be added if it does not
+     *                                  already exist, and the new entry's index returned
+      */
+    public int findClassEntry(String name, boolean add) {
+        int nameIndex = findUTF8Entry(name, add);
+
+        if (nameIndex == 0) {
+            return 0;
+        }
+
+        ClassKey key = new ClassKey(nameIndex);
+        int index = find(key);
+
+        if (!add || (index > 0)) {
+            return index;
+        }
+
+        return addEntry(key, new ClassEntry(nameIndex));
+    }
+
+    /**
+     *  Return the constant pool index of the {@link NameAndTypeEntry} for the
+     *  given name and descriptor, or 0 if it does not exist.
+      *
+     *  @param name        the name of the entity
+     *  @param desc        the descriptor of the entity in internal form
+     *  @param add                if true, the entry will be added if it does not
+     *                                  already exist, and the new entry's index returned
+      */
+    public int findNameAndTypeEntry(String name, String desc, boolean add) {
+        int nameIndex = findUTF8Entry(name, add);
+
+        if (nameIndex == 0) {
+            return 0;
+        }
+
+        int descIndex = findUTF8Entry(desc, add);
+
+        if (descIndex == 0) {
+            return 0;
+        }
+
+        NameAndTypeKey key = new NameAndTypeKey(nameIndex, descIndex);
+        int index = find(key);
+
+        if (!add || (index > 0)) {
+            return index;
+        }
+
+        return addEntry(key, new NameAndTypeEntry(nameIndex, descIndex));
+    }
+
+    /**
+     *  Return the constant pool index of the {@link FieldEntry} for the
+     *  given name, descriptor, and owner class name.
+      *
+     *  @param owner        the name of the field's owning class in internal form
+     *  @param name        the name of the field
+     *  @param desc        the descriptor of the field in internal form
+     *  @param add                if true, the entry will be added if it does not
+     *                                  already exist, and the new entry's index returned
+      */
+    public int findFieldEntry(String owner, String name, String desc,
+        boolean add) {
+        return findComplexEntry(owner, name, desc, Entry.FIELD, add);
+    }
+
+    /**
+     *  Return the constant pool index of the {@link MethodEntry} for the
+     *  given name, descriptor, and owner class name.
+      *
+     *  @param owner        the name of the method's owning class in internal form
+     *  @param name        the name of the method
+     *  @param desc        the descriptor of the method in internal form
+     *  @param add                if true, the entry will be added if it does not
+     *                                  already exist, and the new entry's index returned
+      */
+    public int findMethodEntry(String owner, String name, String desc,
+        boolean add) {
+        return findComplexEntry(owner, name, desc, Entry.METHOD, add);
+    }
+
+    /**
+     *  Return the constant pool index of the {@link InterfaceMethodEntry} for
+     *  the given name, descriptor, and owner class name.
+      *
+     *  @param owner        the name of the method's owning class in internal form
+     *  @param name        the name of the method
+     *  @param desc        the descriptor of the method in internal form
+     *  @param add                if true, the entry will be added if it does not
+     *                                  already exist, and the new entry's index returned
+      */
+    public int findInterfaceMethodEntry(String owner, String name, String desc,
+        boolean add) {
+        return findComplexEntry(owner, name, desc, Entry.INTERFACEMETHOD, add);
+    }
+
+    /**
+     *  Return the constant pool index of the {@link ComplexEntry} for the
+     *  given name, descriptor, and owner class name.
+      *
+     *  @param owner        the name of the owning class in internal form
+     *  @param name        the name of the entity
+     *  @param desc        the descriptor of the entity in internal form
+     *  @param type        the type of entry: field, method, interface method
+     *  @param add                if true, the entry will be added if it does not
+     *                                  already exist, and the new entry's index returned
+      */
+    private int findComplexEntry(String owner, String name, String desc,
+        int type, boolean add) {
+        int classIndex = findClassEntry(owner, add);
+
+        if (classIndex == 0) {
+            return 0;
+        }
+
+        int descIndex = findNameAndTypeEntry(name, desc, add);
+
+        if (descIndex == 0) {
+            return 0;
+        }
+
+        Object key = null;
+
+        switch (type) {
+        case Entry.FIELD:
+            key = new FieldKey(classIndex, descIndex);
+
+            break;
+
+        case Entry.METHOD:
+            key = new MethodKey(classIndex, descIndex);
+
+            break;
+
+        case Entry.INTERFACEMETHOD:
+            key = new InterfaceMethodKey(classIndex, descIndex);
+
+            break;
+        }
+
+        int index = find(key);
+
+        if (!add || (index > 0)) {
+            return index;
+        }
+
+        Entry entry = null;
+
+        switch (type) {
+        case Entry.FIELD:
+            entry = new FieldEntry(classIndex, descIndex);
+
+            break;
+
+        case Entry.METHOD:
+            entry = new MethodEntry(classIndex, descIndex);
+
+            break;
+
+        case Entry.INTERFACEMETHOD:
+            entry = new InterfaceMethodEntry(classIndex, descIndex);
+
+            break;
+        }
+
+        return addEntry(key, entry);
+    }
+
+    public void acceptVisit(BCVisitor visit) {
+        visit.enterConstantPool(this);
+
+        Entry entry;
+
+        for (Iterator itr = _entries.iterator(); itr.hasNext();) {
+            entry = (Entry) itr.next();
+
+            if (entry == null) {
+                continue;
+            }
+
+            visit.enterEntry(entry);
+            entry.acceptVisit(visit);
+            visit.exitEntry(entry);
+        }
+
+        visit.exitConstantPool(this);
+    }
+
+    /**
+     *  Fill the constant pool from the given bytecode stream.
+     */
+    public void read(DataInput in) throws IOException {
+        clear();
+
+        int entryCount = in.readUnsignedShort();
+        Entry entry;
+
+        for (int i = 1; i < entryCount; i++) {
+            entry = Entry.read(in);
+            addEntry(entry);
+
+            if (entry.isWide()) {
+                i++;
+            }
+        }
+    }
+
+    /**
+     *  Write the constant pool to the given bytecode stream.
+     */
+    public void write(DataOutput out) throws IOException {
+        out.writeShort(_entries.size() + 1);
+
+        Entry entry;
+
+        for (Iterator itr = _entries.iterator(); itr.hasNext();) {
+            entry = (Entry) itr.next();
+
+            if (entry != null) {
+                Entry.write(entry, out);
+            }
+        }
+    }
+
+    /**
+     *  Called by constant pool entries when they are mutated.
+     */
+    void modifyEntry(Object origKey, Entry entry) {
+        _lookup.remove(origKey);
+        _lookup.put(getKey(entry), entry);
+    }
+
+    /**
+     *  Returns the constant pool index of the entry with the given key.
+     */
+    private int find(Object key) {
+        Entry entry = (Entry) _lookup.get(key);
+
+        if (entry == null) {
+            return 0;
+        }
+
+        return entry.getIndex();
+    }
+
+    /**
+     *  Return the hash key used for the specified entry.
+     */
+    static Object getKey(Entry entry) {
+        switch (entry.getType()) {
+        case Entry.CLASS:
+            return new ClassKey(((ClassEntry) entry).getNameIndex());
+
+        case Entry.FIELD:
+
+            FieldEntry fe = (FieldEntry) entry;
+
+            return new FieldKey(fe.getClassIndex(), fe.getNameAndTypeIndex());
+
+        case Entry.METHOD:
+
+            MethodEntry me = (MethodEntry) entry;
+
+            return new MethodKey(me.getClassIndex(), me.getNameAndTypeIndex());
+
+        case Entry.INTERFACEMETHOD:
+
+            InterfaceMethodEntry ime = (InterfaceMethodEntry) entry;
+
+            return new InterfaceMethodKey(ime.getClassIndex(),
+                ime.getNameAndTypeIndex());
+
+        case Entry.STRING:
+            return new StringKey(((StringEntry) entry).getStringIndex());
+
+        case Entry.INT:
+        case Entry.FLOAT:
+        case Entry.LONG:
+        case Entry.DOUBLE:
+        case Entry.UTF8:
+            return ((ConstantEntry) entry).getConstant();
+
+        case Entry.NAMEANDTYPE:
+
+            NameAndTypeEntry nte = (NameAndTypeEntry) entry;
+
+            return new NameAndTypeKey(nte.getNameIndex(),
+                nte.getDescriptorIndex());
+
+        default:
+            return null;
+        }
+    }
+
+    /**
+     *  Base class key for entries with one ptr to another entry.
+     */
+    private static abstract class PtrKey {
+        private final int _index;
+
+        public PtrKey(int index) {
+            _index = index;
+        }
+
+        public int hashCode() {
+            return _index;
+        }
+
+        public boolean equals(Object other) {
+            if (other == this) {
+                return true;
+            }
+
+            if (other.getClass() != getClass()) {
+                return false;
+            }
+
+            return ((PtrKey) other)._index == _index;
+        }
+    }
+
+    /**
+     *  Key for string entries.
+     */
+    private static class StringKey extends PtrKey {
+        public StringKey(int index) {
+            super(index);
+        }
+    }
+
+    /**
+     *  Key for class entries.
+     */
+    private static class ClassKey extends PtrKey {
+        public ClassKey(int index) {
+            super(index);
+        }
+    }
+
+    /**
+     *  Base class key for entries with two ptr to other entries.
+     */
+    private static abstract class DoublePtrKey {
+        private final int _index1;
+        private final int _index2;
+
+        public DoublePtrKey(int index1, int index2) {
+            _index1 = index1;
+            _index2 = index2;
+        }
+
+        public int hashCode() {
+            return _index1 ^ _index2;
+        }
+
+        public boolean equals(Object other) {
+            if (other == this) {
+                return true;
+            }
+
+            if (other.getClass() != getClass()) {
+                return false;
+            }
+
+            DoublePtrKey key = (DoublePtrKey) other;
+
+            return (key._index1 == _index1) && (key._index2 == _index2);
+        }
+    }
+
+    /**
+     *  Key for name and type entries.
+     */
+    private static class NameAndTypeKey extends DoublePtrKey {
+        public NameAndTypeKey(int index1, int index2) {
+            super(index1, index2);
+        }
+    }
+
+    /**
+     *  Key for field entries.
+     */
+    private static class FieldKey extends DoublePtrKey {
+        public FieldKey(int index1, int index2) {
+            super(index1, index2);
+        }
+    }
+
+    /**
+     *  Key for method entries.
+     */
+    private static class MethodKey extends DoublePtrKey {
+        public MethodKey(int index1, int index2) {
+            super(index1, index2);
+        }
+    }
+
+    /**
+     *  Key for interface method entries.
+     */
+    private static class InterfaceMethodKey extends DoublePtrKey {
+        public InterfaceMethodKey(int index1, int index2) {
+            super(index1, index2);
+        }
+    }
+}

Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/ConstantPool.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/ConstantPoolTable.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/ConstantPoolTable.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/ConstantPoolTable.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/ConstantPoolTable.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,207 @@
+/*
+ * Copyright 2006 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 serp.bytecode.lowlevel;
+
+import java.io.*;
+
+
+/**
+ *  <p>Efficient representation of the constant pool as a table.  This class
+ *  can be used to parse out bits of information from bytecode without
+ *  instantiating a full {@link serp.bytecode.BCClass}.</p>
+ *
+ *  @author Abe White
+ */
+public class ConstantPoolTable {
+    private byte[] _bytecode = null;
+    private int[] _table = null;
+    private int _idx = 0;
+
+    /**
+     *  Constructor; supply class bytecode.
+     */
+    public ConstantPoolTable(byte[] b) {
+        _bytecode = b;
+        _table = new int[readUnsignedShort(b, 8)];
+        _idx = parse(b, _table);
+    }
+
+    /**
+     *  Constructor; supply input stream to bytecode.
+     */
+    public ConstantPoolTable(InputStream in) throws IOException {
+        this(toByteArray(in));
+    }
+
+    /**
+     *  Allows static computation of the byte index after the constant
+     *  pool without caching constant pool information.
+     */
+    public static int getEndIndex(byte[] b) {
+        return parse(b, null);
+    }
+
+    /**
+     *  Parse class bytecode, returning end index of pool.
+     */
+    private static int parse(byte[] b, int[] table) {
+        // each entry is the index in the byte array of the data for a const
+        // pool entry
+        int entries = (table == null) ? readUnsignedShort(b, 8) : table.length;
+        int idx = 10;
+
+        for (int i = 1; i < entries; i++) {
+            if (table != null) {
+                table[i] = idx + 1; // skip entry type
+            }
+
+            switch (b[idx]) {
+            case 1: // utf8
+                idx += (3 + readUnsignedShort(b, idx + 1));
+
+                break;
+
+            case 3: // integer
+            case 4: // float
+            case 9: // field
+            case 10: // method
+            case 11: // interface method
+            case 12: // name
+                idx += 5;
+
+                break;
+
+            case 5: // long
+            case 6: // double
+                idx += 9;
+                i++; // wide entry
+
+                break;
+
+            default:
+                idx += 3;
+            }
+        }
+
+        return idx;
+    }
+
+    /**
+     *  Read a byte value at the given offset into the given bytecode.
+     */
+    public static int readByte(byte[] b, int idx) {
+        return b[idx] & 0xFF;
+    }
+
+    /**
+     *  Read an unsigned short value at the given offset into the given
+     *  bytecode.
+     */
+    public static int readUnsignedShort(byte[] b, int idx) {
+        return (readByte(b, idx) << 8) | readByte(b, idx + 1);
+    }
+
+    /**
+     *  Read an int value at the given offset into the given bytecode.
+     */
+    public static int readInt(byte[] b, int idx) {
+        return (readByte(b, idx) << 24) | (readByte(b, idx + 1) << 16) |
+        (readByte(b, idx + 2) << 8) | readByte(b, idx + 3);
+    }
+
+    /**
+     *  Read a long value at the given offset into the given bytecode.
+     */
+    public static long readLong(byte[] b, int idx) {
+        return (readInt(b, idx) << 32) | readInt(b, idx + 4);
+    }
+
+    /**
+     *  Read a UTF-8 string value at the given offset into the given
+     *  bytecode.
+     */
+    public static String readString(byte[] b, int idx) {
+        int len = readUnsignedShort(b, idx);
+
+        try {
+            return new String(b, idx + 2, len, "UTF-8");
+        } catch (UnsupportedEncodingException uee) {
+            throw new ClassFormatError(uee.toString());
+        }
+    }
+
+    /**
+     *  Read the contents of the given stream.
+     */
+    private static byte[] toByteArray(InputStream in) throws IOException {
+        ByteArrayOutputStream bout = new ByteArrayOutputStream();
+        byte[] buf = new byte[1024];
+
+        for (int r; (r = in.read(buf)) != -1; bout.write(buf, 0, r))
+            ;
+
+        return bout.toByteArray();
+    }
+
+    /**
+     *  Return the index into the bytecode of the end of the constant pool.
+     */
+    public int getEndIndex() {
+        return _idx;
+    }
+
+    /**
+     *  Return the given table entry.
+     */
+    public int get(int idx) {
+        return _table[idx];
+    }
+
+    /**
+     *  Read a byte value at the given offset.
+     */
+    public int readByte(int idx) {
+        return readByte(_bytecode, idx);
+    }
+
+    /**
+     *  Read an unsigned short value at the given offset.
+     */
+    public int readUnsignedShort(int idx) {
+        return readUnsignedShort(_bytecode, idx);
+    }
+
+    /**
+     *  Read an int value at the given offset.
+     */
+    public int readInt(int idx) {
+        return readInt(_bytecode, idx);
+    }
+
+    /**
+     *  Read a long value at the given offset.
+     */
+    public long readLong(int idx) {
+        return readLong(_bytecode, idx);
+    }
+
+    /**
+     *  Read a UTF-8 string value at the given offset.
+     */
+    public String readString(int idx) {
+        return readString(_bytecode, idx);
+    }
+}

Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/ConstantPoolTable.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/DoubleEntry.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/DoubleEntry.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/DoubleEntry.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/DoubleEntry.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2006 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 serp.bytecode.lowlevel;
+
+import serp.bytecode.visitor.*;
+
+import java.io.*;
+
+
+/**
+ *  <p>A constant double value in the constant pool.</p>
+ *
+ *  @author Abe White
+ */
+public class DoubleEntry extends Entry implements ConstantEntry {
+    private double _value = 0.0;
+
+    /**
+     *  Default constructor.
+     */
+    public DoubleEntry() {
+    }
+
+    /**
+     *  Constructor.
+     *
+     *  @param value        the constant double value of this entry
+     */
+    public DoubleEntry(double value) {
+        _value = value;
+    }
+
+    public boolean isWide() {
+        return true;
+    }
+
+    public int getType() {
+        return Entry.DOUBLE;
+    }
+
+    /**
+     *  Return the value of the constant.
+     */
+    public double getValue() {
+        return _value;
+    }
+
+    /**
+     *  Set the value of the constant.
+     */
+    public void setValue(double value) {
+        Object key = beforeModify();
+        _value = value;
+        afterModify(key);
+    }
+
+    public Object getConstant() {
+        return new Double(getValue());
+    }
+
+    public void setConstant(Object value) {
+        setValue(((Number) value).doubleValue());
+    }
+
+    public void acceptVisit(BCVisitor visit) {
+        visit.enterDoubleEntry(this);
+        visit.exitDoubleEntry(this);
+    }
+
+    void readData(DataInput in) throws IOException {
+        _value = in.readDouble();
+    }
+
+    void writeData(DataOutput out) throws IOException {
+        out.writeDouble(_value);
+    }
+}

Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/DoubleEntry.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/Entry.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/Entry.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/Entry.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/Entry.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,188 @@
+/*
+ * Copyright 2006 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 serp.bytecode.lowlevel;
+
+import serp.bytecode.visitor.*;
+
+import java.io.*;
+
+import java.util.*;
+
+
+/**
+ *  <p>Base type for all constant pool entries.  Entries should generally be
+ *  considered immutable; modifying an entry directly can have dire
+ *  consequences, and often renders the resulting class file invalid.</p>
+ *
+ *  <p>Entries cannot be shared among constant pools.</p>
+ *
+ *  @author Abe White
+ */
+public abstract class Entry implements VisitAcceptor {
+    public static final int UTF8 = 1;
+    public static final int INT = 3;
+    public static final int FLOAT = 4;
+    public static final int LONG = 5;
+    public static final int DOUBLE = 6;
+    public static final int CLASS = 7;
+    public static final int STRING = 8;
+    public static final int FIELD = 9;
+    public static final int METHOD = 10;
+    public static final int INTERFACEMETHOD = 11;
+    public static final int NAMEANDTYPE = 12;
+    private ConstantPool _pool = null;
+    private int _index = 0;
+
+    /**
+     *  Read a single entry from the given bytecode stream and returns it.
+     */
+    public static Entry read(DataInput in) throws IOException {
+        Entry entry = create(in.readUnsignedByte());
+        entry.readData(in);
+
+        return entry;
+    }
+
+    /**
+     *  Write the given entry to the given bytecode stream.
+     */
+    public static void write(Entry entry, DataOutput out)
+        throws IOException {
+        out.writeByte(entry.getType());
+        entry.writeData(out);
+    }
+
+    /**
+     *  Create an entry based on its type code.
+     */
+    public static Entry create(int type) {
+        switch (type) {
+        case CLASS:
+            return new ClassEntry();
+
+        case FIELD:
+            return new FieldEntry();
+
+        case METHOD:
+            return new MethodEntry();
+
+        case INTERFACEMETHOD:
+            return new InterfaceMethodEntry();
+
+        case STRING:
+            return new StringEntry();
+
+        case INT:
+            return new IntEntry();
+
+        case FLOAT:
+            return new FloatEntry();
+
+        case LONG:
+            return new LongEntry();
+
+        case DOUBLE:
+            return new DoubleEntry();
+
+        case NAMEANDTYPE:
+            return new NameAndTypeEntry();
+
+        case UTF8:
+            return new UTF8Entry();
+
+        default:
+            throw new IllegalArgumentException("type = " + type);
+        }
+    }
+
+    /**
+     *  Return the type code for this entry type.
+     */
+    public abstract int getType();
+
+    /**
+     *  Return true if this is a wide entry -- i.e. if it takes up two
+     *  places in the constant pool.  Returns false by default.
+     */
+    public boolean isWide() {
+        return false;
+    }
+
+    /**
+     *  Returns the constant pool containing this entry, or null if none.
+     */
+    public ConstantPool getPool() {
+        return _pool;
+    }
+
+    /**
+     *  Returns the index of the entry in the owning constant pool, or 0.
+     */
+    public int getIndex() {
+        return _index;
+    }
+
+    /**
+     *  This method is called after reading the entry type from bytecode.
+     *  It should read all the data for this entry from the given stream.
+     */
+    abstract void readData(DataInput in) throws IOException;
+
+    /**
+     *  This method is called after writing the entry type to bytecode.
+     *  It should write all data for this entry to the given stream.
+     */
+    abstract void writeData(DataOutput out) throws IOException;
+
+    /**
+     *  Subclasses must call this method before their state is mutated.
+     */
+    Object beforeModify() {
+        if (_pool == null) {
+            return null;
+        }
+
+        return _pool.getKey(this);
+    }
+
+    /**
+     *  Subclasses must call this method when their state is mutated.
+     */
+    void afterModify(Object key) {
+        if (_pool != null) {
+            _pool.modifyEntry(key, this);
+        }
+    }
+
+    /**
+     *  Sets the owning pool of the entry.
+     */
+    void setPool(ConstantPool pool) {
+        // attempting to overwrite current pool?
+        if ((_pool != null) && (pool != null) && (_pool != pool)) {
+            throw new IllegalStateException("Entry already belongs to a pool");
+        }
+
+        _pool = pool;
+    }
+
+    /**
+     *  Set the index of this entry within the pool.
+     */
+    void setIndex(int index) {
+        _index = index;
+    }
+}

Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/Entry.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/FieldEntry.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/FieldEntry.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/FieldEntry.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/FieldEntry.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2006 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 serp.bytecode.lowlevel;
+
+import serp.bytecode.visitor.*;
+
+import java.io.*;
+
+
+/**
+ *  <p>A reference to a class field.</p>
+ *
+ *  @author Abe White
+ */
+public class FieldEntry extends ComplexEntry {
+    /**
+     *  Default constructor.
+     */
+    public FieldEntry() {
+    }
+
+    /**
+     *  Constructor.
+      *
+     *  @see ComplexEntry#ComplexEntry(int,int)
+     */
+    public FieldEntry(int classIndex, int nameAndTypeIndex) {
+        super(classIndex, nameAndTypeIndex);
+    }
+
+    public int getType() {
+        return Entry.FIELD;
+    }
+
+    public void acceptVisit(BCVisitor visit) {
+        visit.enterFieldEntry(this);
+        visit.exitFieldEntry(this);
+    }
+}

Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/FieldEntry.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/FloatEntry.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/FloatEntry.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/FloatEntry.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/FloatEntry.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2006 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 serp.bytecode.lowlevel;
+
+import serp.bytecode.visitor.*;
+
+import java.io.*;
+
+
+/**
+ *  <p>A constant float value in the constant pool.</p>
+ *
+ *  @author Abe White
+ */
+public class FloatEntry extends Entry implements ConstantEntry {
+    private float _value = 0.0F;
+
+    /**
+     *  Default constructor.
+     */
+    public FloatEntry() {
+    }
+
+    /**
+     *  Constructor.
+     *
+     *  @param value        the constant float value of this entry
+     */
+    public FloatEntry(float value) {
+        _value = value;
+    }
+
+    public int getType() {
+        return Entry.FLOAT;
+    }
+
+    /**
+     *  Return the value of this constant.
+      */
+    public float getValue() {
+        return _value;
+    }
+
+    /**
+     *  Set the value of this constant.
+      */
+    public void setValue(float value) {
+        Object key = beforeModify();
+        _value = value;
+        afterModify(key);
+    }
+
+    public Object getConstant() {
+        return new Float(getValue());
+    }
+
+    public void setConstant(Object value) {
+        setValue(((Number) value).floatValue());
+    }
+
+    public void acceptVisit(BCVisitor visit) {
+        visit.enterFloatEntry(this);
+        visit.exitFloatEntry(this);
+    }
+
+    void readData(DataInput in) throws IOException {
+        _value = in.readFloat();
+    }
+
+    void writeData(DataOutput out) throws IOException {
+        out.writeFloat(_value);
+    }
+}

Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/FloatEntry.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/IntEntry.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/IntEntry.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/IntEntry.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/IntEntry.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2006 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 serp.bytecode.lowlevel;
+
+import serp.bytecode.visitor.*;
+
+import serp.util.*;
+
+import java.io.*;
+
+
+/**
+ *  <p>A constant int value in the constant pool.</p>
+ *
+ *  @author Abe White
+ */
+public class IntEntry extends Entry implements ConstantEntry {
+    private int _value = -1;
+
+    /**
+     *  Default constructor.
+     */
+    public IntEntry() {
+    }
+
+    /**
+     *  Constructor.
+     *
+     *  @param value        the constant int value of this entry
+     */
+    public IntEntry(int value) {
+        _value = value;
+    }
+
+    public int getType() {
+        return Entry.INT;
+    }
+
+    /**
+     *  Return the value of this constant.
+     */
+    public int getValue() {
+        return _value;
+    }
+
+    /**
+     *  Set the value of this constant.
+     */
+    public void setValue(int value) {
+        Object key = beforeModify();
+        _value = value;
+        afterModify(key);
+    }
+
+    public Object getConstant() {
+        return Numbers.valueOf(getValue());
+    }
+
+    public void setConstant(Object value) {
+        setValue(((Number) value).intValue());
+    }
+
+    protected void readData(DataInput in) throws IOException {
+        _value = in.readInt();
+    }
+
+    protected void writeData(DataOutput out) throws IOException {
+        out.writeInt(_value);
+    }
+
+    public void acceptVisit(BCVisitor visit) {
+        visit.enterIntEntry(this);
+        visit.exitIntEntry(this);
+    }
+}

Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/IntEntry.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/InterfaceMethodEntry.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/InterfaceMethodEntry.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/InterfaceMethodEntry.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/InterfaceMethodEntry.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2006 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 serp.bytecode.lowlevel;
+
+import serp.bytecode.visitor.*;
+
+import java.io.*;
+
+
+/**
+ *  <p>A reference to an interface method.</p>
+ *
+ *  @author Abe White
+ */
+public class InterfaceMethodEntry extends ComplexEntry {
+    /**
+     *  Default constructor.
+     */
+    public InterfaceMethodEntry() {
+    }
+
+    /**
+     *  Constructor.
+      *
+     *  @see ComplexEntry#ComplexEntry(int,int)
+     */
+    public InterfaceMethodEntry(int classIndex, int nameAndTypeIndex) {
+        super(classIndex, nameAndTypeIndex);
+    }
+
+    public int getType() {
+        return Entry.INTERFACEMETHOD;
+    }
+
+    public void acceptVisit(BCVisitor visit) {
+        visit.enterInterfaceMethodEntry(this);
+        visit.exitInterfaceMethodEntry(this);
+    }
+}

Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/InterfaceMethodEntry.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/LongEntry.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/LongEntry.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/LongEntry.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/LongEntry.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2006 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 serp.bytecode.lowlevel;
+
+import serp.bytecode.visitor.*;
+
+import serp.util.*;
+
+import java.io.*;
+
+
+/**
+ *  <p>A long constant in the constant pool.</p>
+ *
+ *  @author Abe White
+ */
+public class LongEntry extends Entry implements ConstantEntry {
+    private long _value = 0L;
+
+    /**
+     *  Default constructor.
+     */
+    public LongEntry() {
+    }
+
+    /**
+     *  Constructor.
+     *
+     *  @param value        the constant long value of this entry
+     */
+    public LongEntry(long value) {
+        _value = value;
+    }
+
+    public boolean isWide() {
+        return true;
+    }
+
+    public int getType() {
+        return Entry.LONG;
+    }
+
+    /**
+     *  Return the value of the constant.
+     */
+    public long getValue() {
+        return _value;
+    }
+
+    /**
+     *  Set the value of the constant.
+     */
+    public void setValue(long value) {
+        Object key = beforeModify();
+        _value = value;
+        afterModify(key);
+    }
+
+    public Object getConstant() {
+        return Numbers.valueOf(getValue());
+    }
+
+    public void setConstant(Object value) {
+        setValue(((Number) value).longValue());
+    }
+
+    public void acceptVisit(BCVisitor visit) {
+        visit.enterLongEntry(this);
+        visit.exitLongEntry(this);
+    }
+
+    void readData(DataInput in) throws IOException {
+        _value = in.readLong();
+    }
+
+    void writeData(DataOutput out) throws IOException {
+        out.writeLong(_value);
+    }
+}

Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/LongEntry.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/MethodEntry.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/MethodEntry.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/MethodEntry.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/MethodEntry.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2006 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 serp.bytecode.lowlevel;
+
+import serp.bytecode.visitor.*;
+
+import java.io.*;
+
+
+/**
+ *  <p>A reference to a class method.</p>
+ *
+ *  @author Abe White
+ */
+public class MethodEntry extends ComplexEntry {
+    /**
+     *  Default constructor.
+     */
+    public MethodEntry() {
+    }
+
+    /**
+     *  Constructor.
+      *
+     *  @see ComplexEntry#ComplexEntry(int,int)
+     */
+    public MethodEntry(int classIndex, int nameAndTypeIndex) {
+        super(classIndex, nameAndTypeIndex);
+    }
+
+    public int getType() {
+        return Entry.METHOD;
+    }
+
+    public void acceptVisit(BCVisitor visit) {
+        visit.enterMethodEntry(this);
+        visit.exitMethodEntry(this);
+    }
+}

Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/MethodEntry.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/NameAndTypeEntry.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/NameAndTypeEntry.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/NameAndTypeEntry.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/NameAndTypeEntry.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2006 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 serp.bytecode.lowlevel;
+
+import serp.bytecode.visitor.*;
+
+import java.io.*;
+
+
+/**
+ *  <p>Entry containing indexes referencing a name and a descriptor.  Used
+ *  to describe fields and methods of other classes referenced by opcodes.</p>
+ *
+ *  @author Abe White
+ */
+public class NameAndTypeEntry extends Entry {
+    private int _nameIndex = 0;
+    private int _descriptorIndex = 0;
+
+    /**
+     *  Default constructor.
+     */
+    public NameAndTypeEntry() {
+    }
+
+    /**
+     *  Constructor.
+     *
+     *  @param nameIndex                the constant pool index of the
+     *                                                  {@link UTF8Entry} containing the name of
+     *                                                  this entity
+     *  @param descriptorIndex        the constant pool index of the
+     *                                                  {@link UTF8Entry} containing the descriptor
+     *                                                  for this entity
+     */
+    public NameAndTypeEntry(int nameIndex, int descriptorIndex) {
+        _nameIndex = nameIndex;
+        _descriptorIndex = descriptorIndex;
+    }
+
+    public int getType() {
+        return Entry.NAMEANDTYPE;
+    }
+
+    /**
+     *  Return the constant pool index of the {@link UTF8Entry}
+     *  containing the name of this entity.
+     */
+    public int getNameIndex() {
+        return _nameIndex;
+    }
+
+    /**
+     *  Set the constant pool index of the {@link UTF8Entry}
+     *  containing the name of this entity.
+     */
+    public void setNameIndex(int nameIndex) {
+        Object key = beforeModify();
+        _nameIndex = nameIndex;
+        afterModify(key);
+    }
+
+    /**
+     *  Return the name's referenced {@link UTF8Entry}.  This method can only
+     *  be run for entries that have been added to a constant pool.
+     */
+    public UTF8Entry getNameEntry() {
+        return (UTF8Entry) getPool().getEntry(_nameIndex);
+    }
+
+    /**
+     *  Return the constant pool index of the {@link UTF8Entry}
+     *  containing the descriptor for this entity.
+     */
+    public int getDescriptorIndex() {
+        return _descriptorIndex;
+    }
+
+    /**
+     *  Set the constant pool index of a {@link UTF8Entry}
+     *  containing the descriptor for this entity.
+     */
+    public void setDescriptorIndex(int descriptorIndex) {
+        Object key = beforeModify();
+        _descriptorIndex = descriptorIndex;
+        afterModify(key);
+    }
+
+    /**
+     *  Return the descriptor's referenced {@link UTF8Entry}.  This method
+     *  can only be run for entries that have been added to a constant pool.
+     */
+    public UTF8Entry getDescriptorEntry() {
+        return (UTF8Entry) getPool().getEntry(_descriptorIndex);
+    }
+
+    public void acceptVisit(BCVisitor visit) {
+        visit.enterNameAndTypeEntry(this);
+        visit.exitNameAndTypeEntry(this);
+    }
+
+    void readData(DataInput in) throws IOException {
+        _nameIndex = in.readUnsignedShort();
+        _descriptorIndex = in.readUnsignedShort();
+    }
+
+    void writeData(DataOutput out) throws IOException {
+        out.writeShort(_nameIndex);
+        out.writeShort(_descriptorIndex);
+    }
+}

Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/NameAndTypeEntry.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/StringEntry.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/StringEntry.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/StringEntry.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/StringEntry.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2006 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 serp.bytecode.lowlevel;
+
+import serp.bytecode.visitor.*;
+
+import java.io.*;
+
+
+/**
+ *  <p>A String constant in the constant pool.  String constants
+ *  hold a reference to a {@link UTF8Entry} that stores the actual value.</p>
+ *
+ *  @author Abe White
+ */
+public class StringEntry extends Entry implements ConstantEntry {
+    private int _stringIndex = -1;
+
+    /**
+     *  Default constructor.
+     */
+    public StringEntry() {
+    }
+
+    /**
+     *  Constructor.
+     *
+     *  @param stringIndex        the constant pool index of the {@link UTF8Entry}
+     *                                          containing the value of this string
+     */
+    public StringEntry(int stringIndex) {
+        _stringIndex = stringIndex;
+    }
+
+    public int getType() {
+        return Entry.STRING;
+    }
+
+    /**
+     *  Return the constant pool index of the {@link UTF8Entry}
+     *  storing the        value of this string.
+     */
+    public int getStringIndex() {
+        return _stringIndex;
+    }
+
+    /**
+     *  Set the constant pool index of the {@link UTF8Entry}
+     *  storing the        value of this string.
+     */
+    public void setStringIndex(int stringIndex) {
+        Object key = beforeModify();
+        _stringIndex = stringIndex;
+        afterModify(key);
+    }
+
+    /**
+     *  Return the referenced {@link UTF8Entry}.  This method can only
+     *  be run for entries that have been added to a constant pool.
+     */
+    public UTF8Entry getStringEntry() {
+        return (UTF8Entry) getPool().getEntry(_stringIndex);
+    }
+
+    public Object getConstant() {
+        return getStringEntry().getValue();
+    }
+
+    public void setConstant(Object value) {
+        getStringEntry().setConstant(value);
+    }
+
+    public void acceptVisit(BCVisitor visit) {
+        visit.enterStringEntry(this);
+        visit.exitStringEntry(this);
+    }
+
+    void readData(DataInput in) throws IOException {
+        _stringIndex = in.readUnsignedShort();
+    }
+
+    void writeData(DataOutput out) throws IOException {
+        out.writeShort(_stringIndex);
+    }
+}

Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/StringEntry.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/UTF8Entry.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/UTF8Entry.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/UTF8Entry.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/UTF8Entry.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2006 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 serp.bytecode.lowlevel;
+
+import serp.bytecode.visitor.*;
+
+import java.io.*;
+
+
+/**
+ *  <p>A unicode string value in the constant pool.</p>
+ *
+ *  @author Abe White
+ */
+public class UTF8Entry extends Entry implements ConstantEntry {
+    private String _value = "";
+
+    /**
+     *  Default constructor.
+     */
+    public UTF8Entry() {
+    }
+
+    /**
+     *  Constructor.
+     *
+     *  @param value        the constant string value of this entry
+     */
+    public UTF8Entry(String value) {
+        _value = value;
+    }
+
+    public int getType() {
+        return Entry.UTF8;
+    }
+
+    /**
+     *  Return the value of the entry.
+     */
+    public String getValue() {
+        return _value;
+    }
+
+    /**
+     *  Set the value of the entry.
+     */
+    public void setValue(String value) {
+        if (value == null) {
+            throw new NullPointerException("value = null");
+        }
+
+        Object key = beforeModify();
+        _value = value;
+        afterModify(key);
+    }
+
+    public Object getConstant() {
+        return getValue();
+    }
+
+    public void setConstant(Object value) {
+        setValue((String) value);
+    }
+
+    public void acceptVisit(BCVisitor visit) {
+        visit.enterUTF8Entry(this);
+        visit.exitUTF8Entry(this);
+    }
+
+    void readData(DataInput in) throws IOException {
+        _value = in.readUTF();
+    }
+
+    void writeData(DataOutput out) throws IOException {
+        out.writeUTF(_value);
+    }
+}

Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/UTF8Entry.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/package.html
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/package.html?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/package.html (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/package.html Wed Jun 28 12:46:13 2006
@@ -0,0 +1,11 @@
+<html>
+<body>
+	<p><strong>Lowlevel Bytecode Manipuation</strong></p>
+	<p>
+		This package contains facilities for lowlevel bytecode manipulation
+		through the class constant pool.  It is generally not necessary to use
+ 		this package directly, as all necessary functionality is made available
+		at a high level via the <code>serp.bytecode</code> package.
+	</p>
+</body>
+</html>

Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/package.html
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/package.html
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/package.html?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/package.html (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/package.html Wed Jun 28 12:46:13 2006
@@ -0,0 +1,139 @@
+<html>
+<body>
+	<p><strong>Bytecode Manipuation</strong></p>
+	<p>
+		This package contains a framework for Java bytecode manipulation.
+	</p>
+	<p>
+		Bytecode manipulation is a powerful tool in the arsenal of the Java
+		developer.  It can be used for tasks from compiling alternative 
+		programming languages to run in a JVM, to creating new classes on the
+		fly at runtime, to instrumenting classes for performance analysis, to
+		debugging, to altering or enhancing the capabilities of existing
+		compiled classes.  Traditionally, however, this power has come at a
+		price: modifying bytecode has required an in-depth knowledge of the
+		class file structure and has necessitated very low-level programming
+		techniques.  These costs have proven too much for most developers, and 
+	 	bytecode manipulation has been largely ignored by the mainstream.
+	</p>
+	<p>
+		The goal of the serp bytecode framework is to tap the full power of
+		bytecode modification while lowering its associated costs.
+		The framework provides a set of high-level APIs for manipulating all 
+		aspects of bytecode, from large-scale structures like class member 
+		fields to the individual instructions that comprise the code of 
+		methods.  While in order to perform any advanced manipulation, some 
+		understanding of the 
+		<a href="http://java.sun.com/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html">
+		class file format</a> and especially of the 
+		<a href="http://java.sun.com/docs/books/vmspec/2nd-edition/html/Instructions.doc.html">
+		JVM instruction set</a> is necessary, the framework makes it as easy
+		as possible to enter the world of bytecode development.
+	</p>
+	<p>
+		There are several other excellent bytecode frameworks available.   Serp
+		excels, however, in the following areas:
+		<ul>
+			<li>
+				<em>Ease of use.</em>  Serp provides very high-level APIs for 
+				all normal bytecode modification functionality.   Additionally,
+				the framework contains a large set of convenience methods to 
+				make code that uses it as clean as possible.  From overloading
+				its methods to prevent you from having to make type 
+				conversions, to making shortcuts for operations like adding 
+				default constructors, serp tries to take the pain out of 
+				bytecode development.
+			</li>
+			<li>
+				<em>Power.</em>  Serp does not hide any of the power of
+				bytecode manipulation behind a limited set of high-level 
+				functions.  In addition to its available high-level APIs, which
+				themselves cover the functionality all but the most advanced
+				users will ever need, serp gives you direct access to the 
+				low-level details of the class file and constant pool.  You 
+				can even switch back and
+				forth between low-level and high-level operations;
+				serp maintains complete consistency of the class structure
+				at all times.  A change to a method descriptor in the constant
+				pool, for example, will immediately change the return values
+				of all the high-level APIs that describe that method.
+			</li>
+			<li>
+				<em>Constant pool management.</em>  In the class file format,
+				all constant values are stored in a constant pool of shared
+				entries to minimize the size of class structures.  Serp gives
+				you access to the constant pool directly, but most of you
+				will never use it; serp's high-level APIs completely
+				abstract management of the constant pool.
+				Any time a new constant is needed, serp will automatically add
+				it to the pool while ensuring that no duplicates ever exist.
+				Serp also does its best to manipulate the pool so that the
+				effects of changing a constant are as expected: i.e. changing
+				one instruction to use the string "bar" instead of "foo" 
+				will not affect other instructions that use the string "foo",
+				but changing the name of a class field will instantly change
+				all instructions that reference that field to use the new name.
+			</li>
+			<li>
+				<em>Instruction morphing.</em>  Dealing with the individual
+				instructions that make up method code is the most difficult
+				part of bytecode manipulation.  To facilitate this process,
+				most serp instruction representations have the ability to
+				change their underlying low-level opcodes on the fly as the
+				you modify the parameters of the instruction.  For 
+				example, accessing the constant integer value 0 requires the
+				opcode <code>iconst0</code>, while accessing the string 
+				constant "foo" requires a different opcode, <code>ldc</code>,
+				followed by the constant pool index of "foo".  In serp, however,
+				there is only one instruction, <code>constant</code>.  This
+				instruction has <code>setValue</code> methods which use the
+				given value to automatically determine the correct opcodes and
+				arguments -- <code>iconst0</code> for a value of 0 and 
+				<code>ldc</code> plus the proper constant pool index for the
+				value of "foo".
+			</li>
+		</ul> 
+	</p>
+	<p>
+		Serp is not ideally suited to all applications.  Here are a few
+		disadvantages of serp:
+		<ul>
+			<li>
+				<em>Speed.</em>  Serp is not built for speed.  Though there
+				are plans for performing incremental parsing, serp currently
+				fully parses class files when a class is loaded, which is a 
+				slow process.
+				Also, serp's insistence on full-time consistency between the
+				low and high level class structures slows down both access and
+				mutator methods.  These factors are less of a concern, though,
+				when creating new classes at runtime (rather than modifying 
+				existing code), or when using serp as part of the compilation
+				process.  Serp excels in both of these scenarios.
+			</li>
+			<li>
+				<em>Memory.</em>  Serp's high-level structures for representing
+				class bytecode are very memory-hungry.
+			</li>
+			<li>
+				<em>Multi-threaded modifications.</em>  The serp toolkit is
+				not threadsafe.  Multiple threads cannot safely make
+				modifications to the same classes the same time.
+			</li>
+			<li>
+				<em>Project-level modifications.</em>  Changes made in one
+				class in a serp project are not yet automatically propogated
+				to other classes.  However, there are plans to implement this,
+				as well as plans to allow operations to modify bytecode based
+				on specified patterns, similar to aspect-oriented programming.
+			</li>
+		</ul>
+	</p>
+	<p>
+		The first class that you should study in this package is the 
+		{@link serp.bytecode.Project} type.  From there, move onto the 
+		{@link serp.bytecode.BCClass}, and trace its APIs into 
+		{@link serp.bytecode.BCField}s, {@link serp.bytecode.BCMethod}s,
+		and finally into actual {@link serp.bytecode.Code}. 
+	</p>
+</body>
+</html>

Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/package.html
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/visitor/BCVisitor.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/visitor/BCVisitor.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/visitor/BCVisitor.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/visitor/BCVisitor.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,415 @@
+/*
+ * Copyright 2006 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 serp.bytecode.visitor;
+
+import serp.bytecode.*;
+import serp.bytecode.Deprecated;
+
+import serp.bytecode.lowlevel.*;
+
+
+/**
+ *  <p>Base class for visitors on a bytecode entity.  The public {@link #visit}
+ *  method will traverse the object graph of the given entity, calling the
+ *  <code>enter*</code> and <code>exit*</code> methods as it visits each
+ *  object.  The traversal is done depth-first.  Subclasses should override
+ *  only the methods for visiting the entities they are interested in.
+ *  Whenever there is a general method (i.e. <code>enter/exitEntry</code>) as
+ *  well as a more specific one        (i.e. <code>enter/exitStringEntry</code>), the
+ *  more general method will be called first, followed by a call on the correct
+ *  specific method.  Most subclasses will override either the general or
+ *  specific cases, but not both.</p>
+ *
+ *  @author Abe White
+ */
+public class BCVisitor {
+    /**
+     *  Visit the given entity.
+     */
+    public void visit(VisitAcceptor obj) {
+        if (obj == null) {
+            return;
+        }
+
+        obj.acceptVisit(this);
+    }
+
+    public void enterProject(Project obj) {
+    }
+
+    public void exitProject(Project obj) {
+    }
+
+    public void enterBCClass(BCClass obj) {
+    }
+
+    public void exitBCClass(BCClass obj) {
+    }
+
+    public void enterBCMember(BCMember obj) {
+    }
+
+    public void exitBCMember(BCMember obj) {
+    }
+
+    public void enterBCField(BCField obj) {
+    }
+
+    public void exitBCField(BCField obj) {
+    }
+
+    public void enterBCMethod(BCMethod obj) {
+    }
+
+    public void exitBCMethod(BCMethod obj) {
+    }
+
+    public void enterAttribute(Attribute obj) {
+    }
+
+    public void exitAttribute(Attribute obj) {
+    }
+
+    public void enterConstantValue(ConstantValue obj) {
+    }
+
+    public void exitConstantValue(ConstantValue obj) {
+    }
+
+    public void enterDeprecated(Deprecated obj) {
+    }
+
+    public void exitDeprecated(Deprecated obj) {
+    }
+
+    public void enterExceptions(Exceptions obj) {
+    }
+
+    public void exitExceptions(Exceptions obj) {
+    }
+
+    public void enterInnerClasses(InnerClasses obj) {
+    }
+
+    public void exitInnerClasses(InnerClasses obj) {
+    }
+
+    public void enterLineNumberTable(LineNumberTable obj) {
+    }
+
+    public void exitLineNumberTable(LineNumberTable obj) {
+    }
+
+    public void enterLocalVariableTable(LocalVariableTable obj) {
+    }
+
+    public void exitLocalVariableTable(LocalVariableTable obj) {
+    }
+
+    public void enterLocalVariableTypeTable(LocalVariableTypeTable obj) {
+    }
+
+    public void exitLocalVariableTypeTable(LocalVariableTypeTable obj) {
+    }
+
+    public void enterSourceFile(SourceFile obj) {
+    }
+
+    public void exitSourceFile(SourceFile obj) {
+    }
+
+    public void enterSynthetic(Synthetic obj) {
+    }
+
+    public void exitSynthetic(Synthetic obj) {
+    }
+
+    public void enterUnknownAttribute(UnknownAttribute obj) {
+    }
+
+    public void exitUnknownAttribute(UnknownAttribute obj) {
+    }
+
+    public void enterCode(Code obj) {
+    }
+
+    public void exitCode(Code obj) {
+    }
+
+    public void enterExceptionHandler(ExceptionHandler obj) {
+    }
+
+    public void exitExceptionHandler(ExceptionHandler obj) {
+    }
+
+    public void enterInnerClass(InnerClass obj) {
+    }
+
+    public void exitInnerClass(InnerClass obj) {
+    }
+
+    public void enterLineNumber(LineNumber obj) {
+    }
+
+    public void exitLineNumber(LineNumber obj) {
+    }
+
+    public void enterLocalVariable(LocalVariable obj) {
+    }
+
+    public void exitLocalVariable(LocalVariable obj) {
+    }
+
+    public void enterLocalVariableType(LocalVariableType obj) {
+    }
+
+    public void exitLocalVariableType(LocalVariableType obj) {
+    }
+
+    public void enterInstruction(Instruction obj) {
+    }
+
+    public void exitInstruction(Instruction obj) {
+    }
+
+    public void enterArrayLoadInstruction(ArrayLoadInstruction obj) {
+    }
+
+    public void exitArrayLoadInstruction(ArrayLoadInstruction obj) {
+    }
+
+    public void enterArrayStoreInstruction(ArrayStoreInstruction obj) {
+    }
+
+    public void exitArrayStoreInstruction(ArrayStoreInstruction obj) {
+    }
+
+    public void enterClassInstruction(ClassInstruction obj) {
+    }
+
+    public void exitClassInstruction(ClassInstruction obj) {
+    }
+
+    public void enterConstantInstruction(ConstantInstruction obj) {
+    }
+
+    public void exitConstantInstruction(ConstantInstruction obj) {
+    }
+
+    public void enterConvertInstruction(ConvertInstruction obj) {
+    }
+
+    public void exitConvertInstruction(ConvertInstruction obj) {
+    }
+
+    public void enterGetFieldInstruction(GetFieldInstruction obj) {
+    }
+
+    public void exitGetFieldInstruction(GetFieldInstruction obj) {
+    }
+
+    public void enterIIncInstruction(IIncInstruction obj) {
+    }
+
+    public void exitIIncInstruction(IIncInstruction obj) {
+    }
+
+    public void enterJumpInstruction(JumpInstruction obj) {
+    }
+
+    public void exitJumpInstruction(JumpInstruction obj) {
+    }
+
+    public void enterIfInstruction(IfInstruction obj) {
+    }
+
+    public void exitIfInstruction(IfInstruction obj) {
+    }
+
+    public void enterLoadInstruction(LoadInstruction obj) {
+    }
+
+    public void exitLoadInstruction(LoadInstruction obj) {
+    }
+
+    public void enterLookupSwitchInstruction(LookupSwitchInstruction obj) {
+    }
+
+    public void exitLookupSwitchInstruction(LookupSwitchInstruction obj) {
+    }
+
+    public void enterMathInstruction(MathInstruction obj) {
+    }
+
+    public void exitMathInstruction(MathInstruction obj) {
+    }
+
+    public void enterMethodInstruction(MethodInstruction obj) {
+    }
+
+    public void exitMethodInstruction(MethodInstruction obj) {
+    }
+
+    public void enterMultiANewArrayInstruction(MultiANewArrayInstruction obj) {
+    }
+
+    public void exitMultiANewArrayInstruction(MultiANewArrayInstruction obj) {
+    }
+
+    public void enterNewArrayInstruction(NewArrayInstruction obj) {
+    }
+
+    public void exitNewArrayInstruction(NewArrayInstruction obj) {
+    }
+
+    public void enterPutFieldInstruction(PutFieldInstruction obj) {
+    }
+
+    public void exitPutFieldInstruction(PutFieldInstruction obj) {
+    }
+
+    public void enterRetInstruction(RetInstruction obj) {
+    }
+
+    public void exitRetInstruction(RetInstruction obj) {
+    }
+
+    public void enterReturnInstruction(ReturnInstruction obj) {
+    }
+
+    public void exitReturnInstruction(ReturnInstruction obj) {
+    }
+
+    public void enterStackInstruction(StackInstruction obj) {
+    }
+
+    public void exitStackInstruction(StackInstruction obj) {
+    }
+
+    public void enterStoreInstruction(StoreInstruction obj) {
+    }
+
+    public void exitStoreInstruction(StoreInstruction obj) {
+    }
+
+    public void enterTableSwitchInstruction(TableSwitchInstruction obj) {
+    }
+
+    public void exitTableSwitchInstruction(TableSwitchInstruction obj) {
+    }
+
+    public void enterWideInstruction(WideInstruction obj) {
+    }
+
+    public void exitWideInstruction(WideInstruction obj) {
+    }
+
+    public void enterMonitorEnterInstruction(MonitorEnterInstruction obj) {
+    }
+
+    public void exitMonitorEnterInstruction(MonitorEnterInstruction obj) {
+    }
+
+    public void enterMonitorExitInstruction(MonitorExitInstruction obj) {
+    }
+
+    public void exitMonitorExitInstruction(MonitorExitInstruction obj) {
+    }
+
+    public void enterCmpInstruction(CmpInstruction obj) {
+    }
+
+    public void exitCmpInstruction(CmpInstruction obj) {
+    }
+
+    public void enterConstantPool(ConstantPool obj) {
+    }
+
+    public void exitConstantPool(ConstantPool obj) {
+    }
+
+    public void enterEntry(Entry obj) {
+    }
+
+    public void exitEntry(Entry obj) {
+    }
+
+    public void enterClassEntry(ClassEntry obj) {
+    }
+
+    public void exitClassEntry(ClassEntry obj) {
+    }
+
+    public void enterDoubleEntry(DoubleEntry obj) {
+    }
+
+    public void exitDoubleEntry(DoubleEntry obj) {
+    }
+
+    public void enterFieldEntry(FieldEntry obj) {
+    }
+
+    public void exitFieldEntry(FieldEntry obj) {
+    }
+
+    public void enterFloatEntry(FloatEntry obj) {
+    }
+
+    public void exitFloatEntry(FloatEntry obj) {
+    }
+
+    public void enterIntEntry(IntEntry obj) {
+    }
+
+    public void exitIntEntry(IntEntry obj) {
+    }
+
+    public void enterInterfaceMethodEntry(InterfaceMethodEntry obj) {
+    }
+
+    public void exitInterfaceMethodEntry(InterfaceMethodEntry obj) {
+    }
+
+    public void enterLongEntry(LongEntry obj) {
+    }
+
+    public void exitLongEntry(LongEntry obj) {
+    }
+
+    public void enterMethodEntry(MethodEntry obj) {
+    }
+
+    public void exitMethodEntry(MethodEntry obj) {
+    }
+
+    public void enterNameAndTypeEntry(NameAndTypeEntry obj) {
+    }
+
+    public void exitNameAndTypeEntry(NameAndTypeEntry obj) {
+    }
+
+    public void enterStringEntry(StringEntry obj) {
+    }
+
+    public void exitStringEntry(StringEntry obj) {
+    }
+
+    public void enterUTF8Entry(UTF8Entry obj) {
+    }
+
+    public void exitUTF8Entry(UTF8Entry obj) {
+    }
+}

Propchange: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/visitor/BCVisitor.java
------------------------------------------------------------------------------
    svn:executable = *