openjpa-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From p..@apache.org
Subject svn commit: r417860 [9/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/t...
Date Wed, 28 Jun 2006 19:46:19 GMT
Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/Project.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/Project.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/Project.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/Project.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,451 @@
+/*
+ * 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;
+
+import serp.bytecode.lowlevel.*;
+
+import serp.bytecode.visitor.*;
+
+import serp.util.*;
+
+import java.io.*;
+
+import java.util.*;
+
+
+/**
+ *  <p>The Project represents a working set of classes.  It caches parsed
+ *  bytecode and is responsible for bytecode class creation.  Currently
+ *  changes made in one class are <strong>not</strong> reflected in other
+ *  classes, though this will be an option in the future.</p>
+ *
+ *  <p>Bytecode that has been parsed is held in a cache so that retrieving
+ *  a class with the same name multiple times always returns the same
+ *  {@link BCClass} instance.</p>
+ *
+ *  <p>A future goal is to eventually have facilities for traversing jars
+ *  or directory structures to find classes that meet a given criteria (such
+ *  as implementing a given interface, etc) and to perform operations on entire
+ *  projects, similar to aspect-oriented programming.</p>
+ *
+ *  @author Abe White
+ */
+public class Project implements VisitAcceptor {
+    private final String _name;
+    private final HashMap _cache = new HashMap();
+    private final NameCache _names = new NameCache();
+
+    /**
+     *  Default constructor.
+     */
+    public Project() {
+        this(null);
+    }
+
+    /**
+     *  Construct a named project.
+     */
+    public Project(String name) {
+        _name = name;
+    }
+
+    /**
+     *  Return the project name, or null if unset.
+     */
+    public String getName() {
+        return _name;
+    }
+
+    /**
+     *  Return the name cache, which includes utilities for converting names
+     *  from internal to external form and vice versa.
+     */
+    public NameCache getNameCache() {
+        return _names;
+    }
+
+    /**
+     *  Load a class with the given name.
+     *
+     *  @see #loadClass(String,ClassLoader)
+     */
+    public BCClass loadClass(String name) {
+        return loadClass(name, null);
+    }
+
+    /**
+     *  Load the bytecode for the class with the given name.
+     *  If a {@link BCClass} with the given name already exists in this project,
+     *  it will be returned.  Otherwise, a new {@link BCClass} will be created
+     *  with the given name and returned.  If the name represents an existing
+     *  type, the returned instance will contain the parsed bytecode for
+     *  that type.  If the name is of a primitive or array type, the returned
+     *  instance will act accordingly.
+     *
+     *  @param name        the name of the class, including package
+     *  @param loader        the class loader to use to search for an existing
+     *                                  class with the given name; if null defaults to the
+     *                                  context loader of the current thread
+     *  @throws RuntimeException on parse error
+     */
+    public BCClass loadClass(String name, ClassLoader loader) {
+        // convert to proper Class.forName() form
+        name = _names.getExternalForm(name, false);
+
+        BCClass cached = checkCache(name);
+
+        if (cached != null) {
+            return cached;
+        }
+
+        // check for existing type
+        if (loader == null) {
+            loader = Thread.currentThread().getContextClassLoader();
+        }
+
+        try {
+            return loadClass(Strings.toClass(name, loader));
+        } catch (Exception e) {
+        }
+
+        String componentName = _names.getComponentName(name);
+        BCClass ret = new BCClass(this);
+
+        if (componentName != null) {
+            ret.setState(new ArrayState(name, componentName));
+        } else {
+            ret.setState(new ObjectState(_names));
+            ret.setName(name);
+            ret.setSuperclass(Object.class);
+        }
+
+        cache(name, ret);
+
+        return ret;
+    }
+
+    /**
+     *  Load the bytecode for the given class.
+     *  If a {@link BCClass} with the name of the given class already exists in
+     *  this project, it will be returned.  Otherwise, the bytecode of the given
+     *  class will be parsed and returned as a new {@link BCClass}.  If the
+     *  given class is an array or primitive type, the returned instance will
+     *  act accordingly.
+     *
+     *  @param type        the class to parse
+     *  @throws RuntimeException on parse error
+     */
+    public BCClass loadClass(Class type) {
+        BCClass cached = checkCache(type.getName());
+
+        if (cached != null) {
+            return cached;
+        }
+
+        BCClass ret = new BCClass(this);
+
+        if (type.isPrimitive()) {
+            ret.setState(new PrimitiveState(type, _names));
+        } else if (type.isArray()) {
+            ret.setState(new ArrayState(type.getName(),
+                    _names.getExternalForm(type.getComponentType().getName(),
+                        false)));
+        } else {
+            ret.setState(new ObjectState(_names));
+
+            try {
+                ret.read(type);
+            } catch (IOException ioe) {
+                throw new RuntimeException(ioe.toString());
+            }
+        }
+
+        cache(type.getName(), ret);
+
+        return ret;
+    }
+
+    /**
+     *  Load the bytecode from the given class file.
+     *  If this project        already contains the class in the given file, it will
+     *  be returned.  Otherwise a new {@link BCClass} will be created from the
+     *  given bytecode.
+      *
+     *  @throws RuntimeException on parse error
+     */
+    public BCClass loadClass(File classFile) {
+        return loadClass(classFile, null);
+    }
+
+    /**
+     *  Load the bytecode from the given class file.
+     *  If this project        already contains the class in the given file, it will
+     *  be returned.  Otherwise a new {@link BCClass} will be created from the
+     *  given bytecode.
+      *
+     *  @throws RuntimeException on parse error
+     */
+    public BCClass loadClass(File classFile, ClassLoader loader) {
+        // parse the bytecode from the file
+        BCClass ret = new BCClass(this);
+        ret.setState(new ObjectState(_names));
+
+        try {
+            ret.read(classFile, loader);
+        } catch (IOException ioe) {
+            throw new RuntimeException(ioe.toString());
+        }
+
+        String name = ret.getName();
+        BCClass cached = checkCache(name);
+
+        if (cached != null) {
+            return cached;
+        }
+
+        cache(name, ret);
+
+        return ret;
+    }
+
+    /**
+     *  Load the bytecode from the given stream.
+     *  If this project        already contains the class in the given stream,
+     *  it will be returned.  Otherwise a new {@link BCClass} will be created
+     *  from the given bytecode.
+     *
+     *  @throws RuntimeException on parse error
+     */
+    public BCClass loadClass(InputStream in) {
+        return loadClass(in, null);
+    }
+
+    /**
+     *  Load the bytecode from the given stream.
+     *  If this project        already contains the class in the given stream,
+     *  it will be returned.  Otherwise a new {@link BCClass} will be created
+     *  from the given bytecode.
+     *
+     *  @throws RuntimeException on parse error
+     */
+    public BCClass loadClass(InputStream in, ClassLoader loader) {
+        BCClass ret = new BCClass(this);
+        ret.setState(new ObjectState(_names));
+
+        try {
+            ret.read(in, loader);
+        } catch (IOException ioe) {
+            throw new RuntimeException(ioe.toString());
+        }
+
+        String name = ret.getName();
+        BCClass cached = checkCache(name);
+
+        if (cached != null) {
+            return cached;
+        }
+
+        cache(name, ret);
+
+        return ret;
+    }
+
+    /**
+     *  Import the given bytecode from another project.  If a {@link BCClass}
+     *  with the same name already exists in this project, it will be returned.
+     *  Otherwise, a new {@link BCClass} will be created from the
+     *  information in the given class.
+     */
+    public BCClass loadClass(BCClass bc) {
+        String name = bc.getName();
+        BCClass cached = checkCache(name);
+
+        if (cached != null) {
+            return cached;
+        }
+
+        BCClass ret = new BCClass(this);
+
+        if (bc.isPrimitive()) {
+            ret.setState(new PrimitiveState(bc.getType(), _names));
+        } else if (bc.isArray()) {
+            ret.setState(new ArrayState(bc.getName(), bc.getComponentName()));
+        } else {
+            ret.setState(new ObjectState(_names));
+            ret.read(bc);
+        }
+
+        cache(name, ret);
+
+        return ret;
+    }
+
+    /**
+     *  Clears all classes from this project.
+     */
+    public void clear() {
+        Collection values = _cache.values();
+        BCClass bc;
+
+        for (Iterator itr = values.iterator(); itr.hasNext();) {
+            bc = (BCClass) itr.next();
+            itr.remove();
+            bc.invalidate();
+        }
+
+        _names.clear();
+    }
+
+    /**
+     *  Remove a class from this project.  After removal, the result of any
+     *  further operations on the class is undefined.
+     *
+     *  @return true if the class belonged to this project, false
+     *                          otherwise
+     */
+    public boolean removeClass(String type) {
+        return removeClass(checkCache(type));
+    }
+
+    /**
+     *  Remove a class from this project.  After removal, the result of any
+     *  further operations on the class is undefined.
+     *
+     *  @return true if the class belonged to this project, false
+     *                          otherwise
+     */
+    public boolean removeClass(Class type) {
+        if (type == null) {
+            return false;
+        }
+
+        return removeClass(checkCache(type.getName()));
+    }
+
+    /**
+     *  Remove a class from this project.  After removal, the result of any
+     *  further operations on the class is undefined.
+     *
+     *  @return true if the class belonged to this project, false
+     *                          otherwise
+     */
+    public boolean removeClass(BCClass type) {
+        if (type == null) {
+            return false;
+        }
+
+        if (!removeFromCache(type.getName(), type)) {
+            return false;
+        }
+
+        type.invalidate();
+
+        return true;
+    }
+
+    /**
+     *  Return all loaded classes in the project.
+     */
+    public BCClass[] getClasses() {
+        Collection values = _cache.values();
+
+        return (BCClass[]) values.toArray(new BCClass[values.size()]);
+    }
+
+    /**
+     *  Return true if the project already contains the given class.
+     */
+    public boolean containsClass(String type) {
+        return _cache.containsKey(type);
+    }
+
+    /**
+     *  Return true if the project already contains the given class.
+     */
+    public boolean containsClass(Class type) {
+        return (type == null) ? false : containsClass(type.getName());
+    }
+
+    /**
+     *  Return true if the project already contains the given class.
+     */
+    public boolean containsClass(BCClass type) {
+        return (type == null) ? false : containsClass(type.getName());
+    }
+
+    public void acceptVisit(BCVisitor visit) {
+        visit.enterProject(this);
+
+        BCClass[] classes = getClasses();
+
+        for (int i = 0; i < classes.length; i++)
+            classes[i].acceptVisit(visit);
+
+        visit.exitProject(this);
+    }
+
+    /**
+     *  Renames the given class within this project.  Used internally by
+     *  {@link BCClass} instances when their name is modified.
+     *
+     *  @throws IllegalStateException if a class with the new name already
+     *                          exists
+     */
+    void renameClass(String oldName, String newName, BCClass bc) {
+        if (oldName.equals(newName)) {
+            return;
+        }
+
+        BCClass cached = (BCClass) checkCache(newName);
+
+        if (cached != null) {
+            throw new IllegalStateException("A class with name " + newName +
+                " already exists in this project");
+        }
+
+        removeFromCache(oldName, bc);
+        cache(newName, bc);
+    }
+
+    /**
+     *  Check the cache for a loaded type.
+     */
+    private BCClass checkCache(String name) {
+        return (BCClass) _cache.get(name);
+    }
+
+    /**
+     *  Cache a class.
+     */
+    private void cache(String name, BCClass bc) {
+        _cache.put(name, bc);
+    }
+
+    /**
+     *  Remove a cached class.
+     */
+    private boolean removeFromCache(String name, BCClass bc) {
+        BCClass rem = (BCClass) checkCache(name);
+
+        if (rem != bc) {
+            return false;
+        }
+
+        _cache.remove(name);
+
+        return true;
+    }
+}

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

Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/PutFieldInstruction.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/PutFieldInstruction.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/PutFieldInstruction.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/PutFieldInstruction.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,68 @@
+/*
+ * 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;
+
+import serp.bytecode.visitor.*;
+
+
+/**
+ *  <p>Stores a value from the stack into a field.</p>
+ *
+ *  @author Abe White
+ */
+public class PutFieldInstruction extends FieldInstruction {
+    PutFieldInstruction(Code owner, int opcode) {
+        super(owner, opcode);
+    }
+
+    public int getLogicalStackChange() {
+        if (getFieldTypeName() == null) {
+            return 0;
+        }
+
+        if (getOpcode() == Constants.PUTSTATIC) {
+            return -1;
+        }
+
+        return -2;
+    }
+
+    public int getStackChange() {
+        String type = getFieldTypeName();
+
+        if (type == null) {
+            return 0;
+        }
+
+        int stack = -2;
+
+        if (long.class.getName().equals(type) ||
+                double.class.getName().equals(type)) {
+            stack++;
+        }
+
+        if (getOpcode() == Constants.PUTSTATIC) {
+            stack++;
+        }
+
+        return stack;
+    }
+
+    public void acceptVisit(BCVisitor visit) {
+        visit.enterPutFieldInstruction(this);
+        visit.exitPutFieldInstruction(this);
+    }
+}

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

Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/RetInstruction.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/RetInstruction.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/RetInstruction.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/RetInstruction.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,64 @@
+/*
+ * 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;
+
+import serp.bytecode.visitor.*;
+
+import java.io.*;
+
+
+/**
+ *  <p>The <code>ret</code> instruction is used in the implementation of
+ *  finally.</p>
+ *
+ *  @author Abe White
+ */
+public class RetInstruction extends LocalVariableInstruction {
+    RetInstruction(Code owner) {
+        super(owner, Constants.RET);
+    }
+
+    int getLength() {
+        return super.getLength() + 1;
+    }
+
+    public boolean equalsInstruction(Instruction other) {
+        if (this == other) {
+            return true;
+        }
+
+        if (!(other instanceof RetInstruction)) {
+            return false;
+        }
+
+        return super.equalsInstruction(other);
+    }
+
+    public void acceptVisit(BCVisitor visit) {
+        visit.enterRetInstruction(this);
+        visit.exitRetInstruction(this);
+    }
+
+    void read(DataInput in) throws IOException {
+        super.read(in);
+        setLocal(in.readUnsignedByte());
+    }
+
+    void write(DataOutput out) throws IOException {
+        super.write(out);
+        out.writeByte(getLocal());
+    }
+}

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

Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/ReturnInstruction.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/ReturnInstruction.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/ReturnInstruction.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/ReturnInstruction.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,128 @@
+/*
+ * 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;
+
+import serp.bytecode.visitor.*;
+
+import java.io.*;
+
+import java.util.*;
+
+
+/**
+ *  <p>Returns a value (or void) from a method.</p>
+ *
+ *  @author Abe White
+ */
+public class ReturnInstruction extends TypedInstruction {
+    private static final Class[][] _mappings = new Class[][] {
+            { byte.class, int.class },
+            { char.class, int.class },
+            { short.class, int.class },
+            { boolean.class, int.class },
+        };
+
+    ReturnInstruction(Code owner) {
+        super(owner);
+    }
+
+    ReturnInstruction(Code owner, int opcode) {
+        super(owner, opcode);
+    }
+
+    public String getTypeName() {
+        switch (getOpcode()) {
+        case Constants.IRETURN:
+            return int.class.getName();
+
+        case Constants.LRETURN:
+            return long.class.getName();
+
+        case Constants.FRETURN:
+            return float.class.getName();
+
+        case Constants.DRETURN:
+            return double.class.getName();
+
+        case Constants.ARETURN:
+            return Object.class.getName();
+
+        case Constants.RETURN:
+            return void.class.getName();
+
+        default:
+            return null;
+        }
+    }
+
+    public TypedInstruction setType(String type) {
+        type = mapType(type, _mappings, true);
+
+        if (type == null) {
+            return (TypedInstruction) setOpcode(Constants.NOP);
+        }
+
+        switch (type.charAt(0)) {
+        case 'i':
+            return (TypedInstruction) setOpcode(Constants.IRETURN);
+
+        case 'l':
+            return (TypedInstruction) setOpcode(Constants.LRETURN);
+
+        case 'f':
+            return (TypedInstruction) setOpcode(Constants.FRETURN);
+
+        case 'd':
+            return (TypedInstruction) setOpcode(Constants.DRETURN);
+
+        case 'v':
+            return (TypedInstruction) setOpcode(Constants.RETURN);
+
+        default:
+            return (TypedInstruction) setOpcode(Constants.ARETURN);
+        }
+    }
+
+    public int getLogicalStackChange() {
+        switch (getOpcode()) {
+        case Constants.NOP:
+            return 0;
+
+        default:
+            return -1;
+        }
+    }
+
+    public int getStackChange() {
+        switch (getOpcode()) {
+        case Constants.RETURN:
+        case Constants.NOP:
+            return 0;
+
+        case Constants.LRETURN:
+        case Constants.DRETURN:
+            return -2;
+
+        default:
+            return -1;
+        }
+    }
+
+    public void acceptVisit(BCVisitor visit) {
+        visit.enterReturnInstruction(this);
+        visit.exitReturnInstruction(this);
+    }
+}

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

Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/SourceFile.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/SourceFile.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/SourceFile.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/SourceFile.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,135 @@
+/*
+ * 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;
+
+import serp.bytecode.lowlevel.*;
+
+import serp.bytecode.visitor.*;
+
+import java.io.*;
+
+
+/**
+ *  <p>Attribute naming the source file for this class.</p>
+ *
+ *  @author Abe White
+ */
+public class SourceFile extends Attribute {
+    int _sourceFileIndex = 0;
+
+    SourceFile(int nameIndex, Attributes owner) {
+        super(nameIndex, owner);
+    }
+
+    int getLength() {
+        return 2;
+    }
+
+    /**
+     *  Return the index into the class {@link ConstantPool} of the
+     *  {@link UTF8Entry} naming the source file for this class, or 0 if
+     *  not set.
+     */
+    public int getFileIndex() {
+        return _sourceFileIndex;
+    }
+
+    /**
+     *  Set the index into the class {@link ConstantPool} of the
+     *  {@link UTF8Entry} naming the source file for this class.
+     */
+    public void setFileIndex(int sourceFileIndex) {
+        if (sourceFileIndex < 0) {
+            sourceFileIndex = 0;
+        }
+
+        _sourceFileIndex = sourceFileIndex;
+    }
+
+    /**
+     *  Return the name of the source file, or null if not set.
+     */
+    public String getFileName() {
+        if (_sourceFileIndex == 0) {
+            return null;
+        }
+
+        return ((UTF8Entry) getPool().getEntry(_sourceFileIndex)).getValue();
+    }
+
+    /**
+     *  Return the file object for the source file, or null if not set.
+     *
+     *  @param dir                the directory of the file, or null
+     */
+    public File getFile(File dir) {
+        String name = getFileName();
+
+        if (name == null) {
+            return null;
+        }
+
+        return new File(dir, name);
+    }
+
+    /**
+     *  Set the name of the source file.  The name should be the file name
+     *  only; it should not include the path to the file.
+      */
+    public void setFile(String name) {
+        if (name == null) {
+            setFileIndex(0);
+        } else {
+            setFileIndex(getPool().findUTF8Entry(name, true));
+        }
+    }
+
+    /**
+     *  Set the source file.  Note that only the file name is recorded;
+     *  the path to the file is discarded.
+     */
+    public void setFile(File file) {
+        if (file == null) {
+            setFile((String) null);
+        } else {
+            setFile(file.getName());
+        }
+    }
+
+    /**
+      *  Set the file name from the current class name plus the .java extension.
+     */
+    public void setFromClassName() {
+        setFile(((BCClass) getOwner()).getClassName() + ".java");
+    }
+
+    public void acceptVisit(BCVisitor visit) {
+        visit.enterSourceFile(this);
+        visit.exitSourceFile(this);
+    }
+
+    void read(Attribute other) {
+        setFile(((SourceFile) other).getFileName());
+    }
+
+    void read(DataInput in, int length) throws IOException {
+        setFileIndex(in.readUnsignedShort());
+    }
+
+    void write(DataOutput out, int length) throws IOException {
+        out.writeShort(getFileIndex());
+    }
+}

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

Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/StackInstruction.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/StackInstruction.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/StackInstruction.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/StackInstruction.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,177 @@
+/*
+ * 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;
+
+import serp.bytecode.lowlevel.*;
+
+import serp.bytecode.visitor.*;
+
+
+/**
+ *  <p>Represents an instruction that manipulates the stack of the current
+ *  frame.  Using the {@link #setType} methods is a hint about the type being
+ *  manipulated that might cause this instruction to use the wide version
+ *  of the opcode it represents (if manipulating a long or double).  This
+ *  saves the developer from having to decide at compile time whether to
+ *  use <code>pop</code> or <code>pop2</code>, etc.</p>
+ *
+ *  @author Abe White
+ */
+public class StackInstruction extends TypedInstruction {
+    StackInstruction(Code owner, int opcode) {
+        super(owner, opcode);
+    }
+
+    public int getLogicalStackChange() {
+        return getStackChange();
+    }
+
+    public int getStackChange() {
+        switch (getOpcode()) {
+        case Constants.POP:
+            return -1;
+
+        case Constants.POP2:
+            return -2;
+
+        case Constants.DUP:
+        case Constants.DUPX1:
+        case Constants.DUPX2:
+            return 1;
+
+        case Constants.DUP2:
+        case Constants.DUP2X1:
+        case Constants.DUP2X2:
+            return 2;
+
+        default:
+            return 0;
+        }
+    }
+
+    /**
+     *  This method will always return null; use {@link #isWide} to determine
+     *  if this is pop2, dup2, etc.
+     */
+    public String getTypeName() {
+        return null;
+    }
+
+    public TypedInstruction setType(String type) {
+        type = getProject().getNameCache().getExternalForm(type, false);
+
+        return setWide(long.class.getName().equals(type) ||
+            double.class.getName().equals(type));
+    }
+
+    /**
+     *  Return whether to use the wide form of the current opcode for
+     *  operations on longs or doubles.
+     */
+    public boolean isWide() {
+        switch (getOpcode()) {
+        case Constants.POP2:
+        case Constants.DUP2:
+        case Constants.DUP2X1:
+        case Constants.DUP2X2:
+            return true;
+
+        default:
+            return false;
+        }
+    }
+
+    /**
+     *  Set whether to use the wide form of the current opcode for operations
+     *  on longs or doubles.
+     *
+     *  @return this instruction, for method chaining
+     */
+    public StackInstruction setWide(boolean wide) {
+        switch (getOpcode()) {
+        case Constants.POP:
+
+            if (wide) {
+                setOpcode(Constants.POP2);
+            }
+
+            break;
+
+        case Constants.POP2:
+
+            if (!wide) {
+                setOpcode(Constants.POP);
+            }
+
+            break;
+
+        case Constants.DUP:
+
+            if (wide) {
+                setOpcode(Constants.DUP2);
+            }
+
+            break;
+
+        case Constants.DUP2:
+
+            if (!wide) {
+                setOpcode(Constants.DUP);
+            }
+
+            break;
+
+        case Constants.DUPX1:
+
+            if (wide) {
+                setOpcode(Constants.DUP2X1);
+            }
+
+            break;
+
+        case Constants.DUP2X1:
+
+            if (!wide) {
+                setOpcode(Constants.DUPX1);
+            }
+
+            break;
+
+        case Constants.DUPX2:
+
+            if (wide) {
+                setOpcode(Constants.DUP2X2);
+            }
+
+            break;
+
+        case Constants.DUP2X2:
+
+            if (!wide) {
+                setOpcode(Constants.DUPX2);
+            }
+
+            break;
+        }
+
+        return this;
+    }
+
+    public void acceptVisit(BCVisitor visit) {
+        visit.enterStackInstruction(this);
+        visit.exitStackInstruction(this);
+    }
+}

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

Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/State.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/State.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/State.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/State.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,208 @@
+/*
+ * 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;
+
+import serp.bytecode.lowlevel.*;
+
+import java.util.*;
+
+
+/**
+ *  <p>The State type is extended by various concrete types to change
+ *  the behavior of a {@link BCClass}.  All methods in this base
+ *  implementation throw an {@link UnsupportedOperationException}</p>
+ *
+ *  @author Abe White
+ */
+class State {
+    /**
+     *  A singleton instance of this type that can be used to make a
+     *  class invalid.
+     */
+    public static final State INVALID = new State();
+
+    /**
+     *  Return the magic number of the bytecode class.
+     */
+    public int getMagic() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     *  Set the magic number of the bytecode class.
+     */
+    public void setMagic(int magic) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     *  Return the major number of the bytecode class.
+     */
+    public int getMajorVersion() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     *  Set the major version of the bytecode class.
+     */
+    public void setMajorVersion(int major) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     *  Return the minor number of the bytecode class.
+     */
+    public int getMinorVersion() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     *  Set the minor version of the bytecode class.
+     */
+    public void setMinorVersion(int minor) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     *  Return the access flags of the bytecode class.
+     */
+    public int getAccessFlags() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     *  Set the access flags of the bytecode class.
+     */
+    public void setAccessFlags(int access) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     *  Return the {@link ConstantPool} index of the {@link ClassEntry}
+     *  for this class, or 0 if none.
+     */
+    public int getIndex() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     *  Set the {@link ConstantPool} index of the {@link ClassEntry}
+     *  for this class.
+     */
+    public void setIndex(int index) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     *  Return the {@link ConstantPool} index of the {@link ClassEntry}
+     *  for the superclass of this class, or 0 if none.
+     */
+    public int getSuperclassIndex() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     *  Set the {@link ConstantPool} index of the {@link ClassEntry}
+     *  for the superclass of this class.  Throws
+     *  {@link UnsupportedOperationException} by default.
+     */
+    public void setSuperclassIndex(int index) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     *  Return the {@link ConstantPool} indexes of the {@link ClassEntry}s
+     *  for the indexes of this class, or empty collection if none.  If the
+     *  state does not support changing the interfaces, the returned
+     *  collection should be immutable.
+     */
+    public Collection getInterfacesHolder() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     *  Return the {@link BCField}s of this class, or empty collection if none.
+     *  If the state does not support changing the fields, the returned
+     *  collection should be immutable.
+     */
+    public Collection getFieldsHolder() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     *  Return the {@link BCMethod}s of this class, or empty collection if none.
+     *  If the state does not support changing the methods, the returned
+     *  collection should be immutable.
+     */
+    public Collection getMethodsHolder() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     *  Return the {@link Attribute}s of this class, or empty collection if
+     *  none.  If the state does not support changing the attributes, the
+     *  returned collection should be immutable.
+     */
+    public Collection getAttributesHolder() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     *  Return the constant pool of the class.
+     */
+    public ConstantPool getPool() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     *  Return the name of the class.  The name should be in a form suitable
+     *  for a {@link Class#forName} call.
+     */
+    public String getName() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     *  Return the name of the superclass.  The name should be in a form
+     *  suitable for a {@link Class#forName} call, or null if none.
+     */
+    public String getSuperclassName() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     *  Return the name of the component type of this array, or null if not
+     *  an array.  The name should be in a form suitable for a
+     *  {@link Class#forName} call.
+     */
+    public String getComponentName() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     *  Return true if this class is a primitive.
+     */
+    public boolean isPrimitive() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     *  Return true if this class is an array.
+     */
+    public boolean isArray() {
+        throw new UnsupportedOperationException();
+    }
+}

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

Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/StoreInstruction.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/StoreInstruction.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/StoreInstruction.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/StoreInstruction.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,281 @@
+/*
+ * 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;
+
+import serp.bytecode.visitor.*;
+
+import java.io.*;
+
+
+/**
+ *  <p>An instruction to store a value from a local variable onto
+ *  the stack.</p>
+ *
+ *  @author Abe White
+ */
+public class StoreInstruction extends LocalVariableInstruction {
+    private static final Class[][] _mappings = new Class[][] {
+            { byte.class, int.class },
+            { boolean.class, int.class },
+            { char.class, int.class },
+            { short.class, int.class },
+            { void.class, int.class },
+        };
+    String _type = null;
+
+    StoreInstruction(Code owner) {
+        super(owner);
+    }
+
+    StoreInstruction(Code owner, int opcode) {
+        super(owner, opcode);
+    }
+
+    int getLength() {
+        switch (getOpcode()) {
+        case Constants.ISTORE:
+        case Constants.LSTORE:
+        case Constants.FSTORE:
+        case Constants.DSTORE:
+        case Constants.ASTORE:
+            return super.getLength() + 1;
+
+        default:
+            return super.getLength();
+        }
+    }
+
+    public int getLogicalStackChange() {
+        switch (getOpcode()) {
+        case Constants.NOP:
+            return 0;
+
+        default:
+            return -1;
+        }
+    }
+
+    public int getStackChange() {
+        switch (getOpcode()) {
+        case Constants.LSTORE:
+        case Constants.LSTORE0:
+        case Constants.LSTORE1:
+        case Constants.LSTORE2:
+        case Constants.LSTORE3:
+        case Constants.DSTORE:
+        case Constants.DSTORE0:
+        case Constants.DSTORE1:
+        case Constants.DSTORE2:
+        case Constants.DSTORE3:
+            return -2;
+
+        case Constants.NOP:
+            return 0;
+
+        default:
+            return -1;
+        }
+    }
+
+    public String getTypeName() {
+        switch (getOpcode()) {
+        case Constants.ISTORE:
+        case Constants.ISTORE0:
+        case Constants.ISTORE1:
+        case Constants.ISTORE2:
+        case Constants.ISTORE3:
+            return int.class.getName();
+
+        case Constants.LSTORE:
+        case Constants.LSTORE0:
+        case Constants.LSTORE1:
+        case Constants.LSTORE2:
+        case Constants.LSTORE3:
+            return long.class.getName();
+
+        case Constants.FSTORE:
+        case Constants.FSTORE0:
+        case Constants.FSTORE1:
+        case Constants.FSTORE2:
+        case Constants.FSTORE3:
+            return float.class.getName();
+
+        case Constants.DSTORE:
+        case Constants.DSTORE0:
+        case Constants.DSTORE1:
+        case Constants.DSTORE2:
+        case Constants.DSTORE3:
+            return double.class.getName();
+
+        case Constants.ASTORE:
+        case Constants.ASTORE0:
+        case Constants.ASTORE1:
+        case Constants.ASTORE2:
+        case Constants.ASTORE3:
+            return Object.class.getName();
+
+        default:
+            return _type;
+        }
+    }
+
+    public TypedInstruction setType(String type) {
+        type = mapType(type, _mappings, true);
+
+        int local = getLocal();
+
+        // if an invalid type or local, revert to nop
+        if ((type == null) || (local < 0)) {
+            _type = type;
+
+            return (TypedInstruction) setOpcode(Constants.NOP);
+        }
+
+        // valid opcode, unset saved type
+        _type = null;
+
+        switch (type.charAt(0)) {
+        case 'i':
+            return (TypedInstruction) setOpcode((local > 3) ? Constants.ISTORE
+                                                            : (Constants.ISTORE0 +
+                local));
+
+        case 'l':
+            return (TypedInstruction) setOpcode((local > 3) ? Constants.LSTORE
+                                                            : (Constants.LSTORE0 +
+                local));
+
+        case 'f':
+            return (TypedInstruction) setOpcode((local > 3) ? Constants.FSTORE
+                                                            : (Constants.FSTORE0 +
+                local));
+
+        case 'd':
+            return (TypedInstruction) setOpcode((local > 3) ? Constants.DSTORE
+                                                            : (Constants.DSTORE0 +
+                local));
+
+        default:
+            return (TypedInstruction) setOpcode((local > 3) ? Constants.ASTORE
+                                                            : (Constants.ASTORE0 +
+                local));
+        }
+    }
+
+    /**
+     *  StoreInstructions are equal if the type they reference the same
+     *  type and locals index or if either is unset.
+     */
+    public boolean equalsInstruction(Instruction other) {
+        if (other == this) {
+            return true;
+        }
+
+        if (!super.equalsInstruction(other)) {
+            return false;
+        }
+
+        String type = getTypeName();
+        String otherType = ((StoreInstruction) other).getTypeName();
+
+        return (type == null) || (otherType == null) || type.equals(otherType);
+    }
+
+    public void acceptVisit(BCVisitor visit) {
+        visit.enterStoreInstruction(this);
+        visit.exitStoreInstruction(this);
+    }
+
+    void read(Instruction orig) {
+        super.read(orig);
+
+        StoreInstruction ins = (StoreInstruction) orig;
+        _type = ins._type;
+    }
+
+    void read(DataInput in) throws IOException {
+        super.read(in);
+
+        switch (getOpcode()) {
+        case Constants.ISTORE:
+        case Constants.LSTORE:
+        case Constants.FSTORE:
+        case Constants.DSTORE:
+        case Constants.ASTORE:
+            setLocal(in.readUnsignedByte());
+
+            break;
+        }
+    }
+
+    void write(DataOutput out) throws IOException {
+        super.write(out);
+
+        switch (getOpcode()) {
+        case Constants.ISTORE:
+        case Constants.LSTORE:
+        case Constants.FSTORE:
+        case Constants.DSTORE:
+        case Constants.ASTORE:
+            out.writeByte(getLocal());
+        }
+    }
+
+    void calculateOpcode() {
+        // taken care of when setting type
+        setType(getTypeName());
+    }
+
+    void calculateLocal() {
+        switch (getOpcode()) {
+        case Constants.ISTORE0:
+        case Constants.LSTORE0:
+        case Constants.FSTORE0:
+        case Constants.DSTORE0:
+        case Constants.ASTORE0:
+            setLocal(0);
+
+            break;
+
+        case Constants.ISTORE1:
+        case Constants.LSTORE1:
+        case Constants.FSTORE1:
+        case Constants.DSTORE1:
+        case Constants.ASTORE1:
+            setLocal(1);
+
+            break;
+
+        case Constants.ISTORE2:
+        case Constants.LSTORE2:
+        case Constants.FSTORE2:
+        case Constants.DSTORE2:
+        case Constants.ASTORE2:
+            setLocal(2);
+
+            break;
+
+        case Constants.ISTORE3:
+        case Constants.LSTORE3:
+        case Constants.FSTORE3:
+        case Constants.DSTORE3:
+        case Constants.ASTORE3:
+            setLocal(3);
+
+            break;
+        }
+    }
+}

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

Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/SwitchInstruction.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/SwitchInstruction.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/SwitchInstruction.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/SwitchInstruction.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,247 @@
+/*
+ * 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;
+
+import java.io.DataInput;
+import java.io.IOException;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+
+/**
+ *  Contains functionality common to the different switch types
+ *  (TableSwitch and LookupSwitch).
+ *
+ *  @author Eric Lindauer
+ */
+public abstract class SwitchInstruction extends JumpInstruction {
+    private List _cases = new LinkedList();
+
+    public SwitchInstruction(Code owner, int opcode) {
+        super(owner, opcode);
+    }
+
+    /**
+     *  Returns the current byte offsets for the different
+     *  switch cases in this Instruction.
+     */
+    public int[] getOffsets() {
+        int bi = getByteIndex();
+        int[] offsets = new int[_cases.size()];
+
+        for (int i = 0; i < offsets.length; i++)
+            offsets[i] = ((InstructionPtrStrategy) _cases.get(i)).getByteIndex() -
+                bi;
+
+        return offsets;
+    }
+
+    /**
+     *  Sets the offsets for the instructions representing the different
+     *  switch statement cases.  WARNING: these offsets will not be changed
+     *  in the event that the code is modified following this call. It is
+     *  typically a good idea to follow this call with a call to updateTargets
+     *  as soon as the instructions at the given offsets are valid, at which
+     *  point the Instructions themselves will be used as the targets and the
+     *  offsets will be updated as expected.
+     */
+    public void setOffsets(int[] offsets) {
+        int bi = getByteIndex();
+        _cases.clear();
+
+        for (int i = 0; i < offsets.length; i++) {
+            InstructionPtrStrategy next = new InstructionPtrStrategy(this);
+            next.setByteIndex(offsets[i] + bi);
+            _cases.add(next);
+        }
+    }
+
+    public int countTargets() {
+        return _cases.size();
+    }
+
+    int getLength() {
+        // don't call super.getLength(), cause JumpInstruction will return
+        // value assuming this is an 'if' or 'goto' instruction
+        int length = 1;
+
+        // make the first byte of the 'default' a multiple of 4 from the
+        // start of the method
+        int byteIndex = getByteIndex() + 1;
+
+        for (; (byteIndex % 4) != 0; byteIndex++, length++)
+            ;
+
+        return length;
+    }
+
+    /**
+     *  Synonymous with {@link #getTarget}.
+     */
+    public Instruction getDefaultTarget() {
+        return getTarget();
+    }
+
+    /**
+     *  Synonymous with {@link #getOffset}.
+     */
+    public int getDefaultOffset() {
+        return getOffset();
+    }
+
+    /**
+     *  Synonymous with {@link #setOffset}.
+     */
+    public SwitchInstruction setDefaultOffset(int offset) {
+        setOffset(offset);
+
+        return this;
+    }
+
+    /**
+     *  Synonymous with {@link #setTarget}.
+     */
+    public SwitchInstruction setDefaultTarget(Instruction ins) {
+        return (SwitchInstruction) setTarget(ins);
+    }
+
+    /**
+     *  Return the targets for this switch, or empty array if not set.
+     */
+    public Instruction[] getTargets() {
+        Instruction[] result = new Instruction[_cases.size()];
+
+        for (int i = 0; i < _cases.size(); i++)
+            result[i] = ((InstructionPtrStrategy) _cases.get(i)).getTargetInstruction();
+
+        return result;
+    }
+
+    /**
+     *  Set the jump points for this switch.
+     *
+     *  @return this instruction, for method chaining
+     */
+    public SwitchInstruction setTargets(Instruction[] targets) {
+        _cases.clear();
+
+        if (targets != null) {
+            for (int i = 0; i < targets.length; i++)
+                addTarget(targets[i]);
+        }
+
+        return this;
+    }
+
+    /**
+     *  Add a target to this switch.
+     *
+     *  @return this instruction, for method chaining
+     */
+    public SwitchInstruction addTarget(Instruction target) {
+        _cases.add(new InstructionPtrStrategy(this, target));
+
+        return this;
+    }
+
+    public int getLogicalStackChange() {
+        return getStackChange();
+    }
+
+    public int getStackChange() {
+        return -1;
+    }
+
+    public void updateTargets() {
+        super.updateTargets();
+
+        for (Iterator itr = _cases.iterator(); itr.hasNext();)
+            ((InstructionPtrStrategy) itr.next()).updateTargets();
+    }
+
+    public void replaceTarget(Instruction oldTarget, Instruction newTarget) {
+        super.replaceTarget(oldTarget, newTarget);
+
+        for (Iterator itr = _cases.iterator(); itr.hasNext();)
+            ((InstructionPtrStrategy) itr.next()).replaceTarget(oldTarget,
+                newTarget);
+    }
+
+    void read(Instruction orig) {
+        super.read(orig);
+
+        SwitchInstruction ins = (SwitchInstruction) orig;
+        _cases.clear();
+
+        for (Iterator itr = ins._cases.iterator(); itr.hasNext();) {
+            InstructionPtrStrategy incoming = (InstructionPtrStrategy) itr.next();
+            InstructionPtrStrategy next = new InstructionPtrStrategy(this);
+            next.setByteIndex(incoming.getByteIndex());
+            _cases.add(next);
+        }
+    }
+
+    void clearTargets() {
+        _cases.clear();
+    }
+
+    void readTarget(DataInput in) throws IOException {
+        InstructionPtrStrategy next = new InstructionPtrStrategy(this);
+        next.setByteIndex(getByteIndex() + in.readInt());
+        _cases.add(next);
+    }
+
+    /**
+     *  Set the match-jumppt pairs for this switch.
+     *
+     *  @return this instruction, for method chaining
+     */
+    public SwitchInstruction setCases(int[] matches, Instruction[] targets) {
+        setMatches(matches);
+        setTargets(targets);
+
+        return this;
+    }
+
+    public SwitchInstruction setMatches(int[] matches) {
+        clearMatches();
+
+        for (int i = 0; i < matches.length; i++)
+            addMatch(matches[i]);
+
+        return this;
+    }
+
+    /**
+     *  Add a case to this switch.
+     *
+     *  @return this instruction, for method chaining
+     */
+    public SwitchInstruction addCase(int match, Instruction target) {
+        addMatch(match);
+        addTarget(target);
+
+        return this;
+    }
+
+    public abstract SwitchInstruction addMatch(int match);
+
+    public abstract int[] getMatches();
+
+    abstract void clearMatches();
+}

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

Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/Synthetic.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/Synthetic.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/Synthetic.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/Synthetic.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,36 @@
+/*
+ * 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;
+
+import serp.bytecode.visitor.*;
+
+
+/**
+ *  <p>Attribute marking a member as synthetic, or not present in the class
+ *  source code.</p>
+ *
+ *  @author Abe White
+ */
+public class Synthetic extends Attribute {
+    Synthetic(int nameIndex, Attributes owner) {
+        super(nameIndex, owner);
+    }
+
+    public void acceptVisit(BCVisitor visit) {
+        visit.enterSynthetic(this);
+        visit.exitSynthetic(this);
+    }
+}

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

Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/TableSwitchInstruction.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/TableSwitchInstruction.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/TableSwitchInstruction.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/TableSwitchInstruction.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,272 @@
+/*
+ * 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;
+
+import serp.bytecode.visitor.*;
+
+import java.io.*;
+
+import java.util.*;
+
+
+/**
+ *  <p>The <code>tableswitch</code> instruction.</p>
+ *
+ *  @author Abe White
+ */
+public class TableSwitchInstruction extends JumpInstruction {
+    // case info
+    private int _low = 0;
+    private int _high = 0;
+    private List _cases = new LinkedList();
+
+    TableSwitchInstruction(Code owner) {
+        super(owner, Constants.TABLESWITCH);
+    }
+
+    /**
+     *  Returns the current byte offsets for the different
+     *  switch cases in this Instruction.
+     */
+    public int[] getOffsets() {
+        int bi = getByteIndex();
+        int[] offsets = new int[_cases.size()];
+
+        for (int i = 0; i < _cases.size(); i++)
+            offsets[i] = ((InstructionPtrStrategy) _cases.get(i)).getByteIndex() -
+                bi;
+
+        return offsets;
+    }
+
+    /**
+     *  Sets the offsets for the instructions representing the different
+     *  switch statement cases.  WARNING: these offsets will not be changed
+     *  in the event that the code is modified following this call. It is
+     *  typically a good idea to follow this call with a call to updateTargets
+     *  as soon as the instructions at the given offsets are valid, at which
+     *  point the Instructions themselves will be used as the targets and the
+     *  offsets will be updated as expected.
+     */
+    public void setOffsets(int[] offsets) {
+        int bi = getByteIndex();
+        _cases.clear();
+
+        for (int i = 0; i < offsets.length; i++) {
+            InstructionPtrStrategy next = new InstructionPtrStrategy(this);
+            next.setByteIndex(offsets[i] + bi);
+            _cases.add(next);
+        }
+    }
+
+    int getLength() {
+        // don't call super
+        int length = 1;
+
+        // make the first byte of the 'default' a multiple of 4 from the
+        // start of the method
+        int byteIndex = getByteIndex() + 1;
+
+        for (; (byteIndex % 4) != 0; byteIndex++, length++)
+            ;
+
+        // default, low, high
+        length += 12;
+
+        // offsets
+        length += (4 * _cases.size());
+
+        return length;
+    }
+
+    /**
+     *  Synonymous with {@link #getTarget}.
+     */
+    public Instruction getDefaultTarget() {
+        return getTarget();
+    }
+
+    /**
+     *  Synonymous with {@link #setTarget}.
+     */
+    public TableSwitchInstruction setDefaultTarget(Instruction ins) {
+        return (TableSwitchInstruction) setTarget(ins);
+    }
+
+    /**
+     *  Synonymous with {@link #getOffset}.
+     */
+    public int getDefaultOffset() {
+        return getOffset();
+    }
+
+    /**
+     *  Synonymous with {@link #setOffset}.
+     */
+    public TableSwitchInstruction setDefaultOffset(int offset) {
+        setOffset(offset);
+
+        return this;
+    }
+
+    public int getLow() {
+        return _low;
+    }
+
+    public TableSwitchInstruction setLow(int low) {
+        _low = low;
+
+        return this;
+    }
+
+    public int getHigh() {
+        return _high;
+    }
+
+    public TableSwitchInstruction setHigh(int high) {
+        _high = high;
+
+        return this;
+    }
+
+    /**
+     *  Return the targets for this switch, or empty array if not set.
+     */
+    public Instruction[] getTargets() {
+        Instruction[] result = new Instruction[_cases.size()];
+
+        for (int i = 0; i < _cases.size(); i++)
+            result[i] = ((InstructionPtrStrategy) _cases.get(i)).getTargetInstruction();
+
+        return result;
+    }
+
+    /**
+     *  Set the jump points for this switch.
+     *
+     *  @return this instruction, for method chaining
+     */
+    public TableSwitchInstruction setTargets(Instruction[] targets) {
+        _cases.clear();
+
+        if (targets != null) {
+            for (int i = 0; i < targets.length; i++)
+                addTarget(targets[i]);
+        }
+
+        return this;
+    }
+
+    /**
+     *  Add a target to this switch.
+     *
+     *  @return this instruction, for method chaining
+     */
+    public TableSwitchInstruction addTarget(Instruction target) {
+        _cases.add(new InstructionPtrStrategy(this, target));
+
+        return this;
+    }
+
+    public int getStackChange() {
+        return -1;
+    }
+
+    private Instruction findTarget(int jumpByteIndex, List inss) {
+        Instruction ins;
+
+        for (Iterator itr = inss.iterator(); itr.hasNext();) {
+            ins = (Instruction) itr.next();
+
+            if (ins.getByteIndex() == jumpByteIndex) {
+                return ins;
+            }
+        }
+
+        return null;
+    }
+
+    public void updateTargets() {
+        super.updateTargets();
+
+        for (Iterator itr = _cases.iterator(); itr.hasNext();)
+            ((InstructionPtrStrategy) itr.next()).updateTargets();
+    }
+
+    public void replaceTarget(Instruction oldTarget, Instruction newTarget) {
+        super.replaceTarget(oldTarget, newTarget);
+
+        for (Iterator itr = _cases.iterator(); itr.hasNext();)
+            ((InstructionPtrStrategy) itr.next()).replaceTarget(oldTarget,
+                newTarget);
+    }
+
+    public void acceptVisit(BCVisitor visit) {
+        visit.enterTableSwitchInstruction(this);
+        visit.exitTableSwitchInstruction(this);
+    }
+
+    void read(Instruction orig) {
+        super.read(orig);
+
+        TableSwitchInstruction ins = (TableSwitchInstruction) orig;
+        setLow(ins.getLow());
+        setHigh(ins.getHigh());
+
+        for (Iterator itr = ins._cases.iterator(); itr.hasNext();) {
+            InstructionPtrStrategy incoming = (InstructionPtrStrategy) itr.next();
+            InstructionPtrStrategy next = new InstructionPtrStrategy(this);
+            next.setByteIndex(incoming.getByteIndex());
+            _cases.add(next);
+        }
+    }
+
+    void read(DataInput in) throws IOException {
+        // don't call super
+        int bi = getByteIndex();
+
+        for (int byteIndex = bi + 1; (byteIndex % 4) != 0; byteIndex++)
+            in.readByte();
+
+        setOffset(in.readInt());
+        setLow(in.readInt());
+        setHigh(in.readInt());
+
+        _cases.clear();
+
+        for (int i = 0; i < (_high - _low + 1); i++) {
+            InstructionPtrStrategy next = new InstructionPtrStrategy(this);
+            next.setByteIndex(bi + in.readInt());
+            _cases.add(next);
+        }
+    }
+
+    void write(DataOutput out) throws IOException {
+        // don't call super
+        int bi = getByteIndex();
+
+        for (int byteIndex = bi + 1; (byteIndex % 4) != 0; byteIndex++)
+            out.writeByte(0);
+
+        out.writeInt(getOffset());
+        out.writeInt(getLow());
+        out.writeInt(getHigh());
+
+        for (Iterator itr = _cases.iterator(); itr.hasNext();)
+            out.writeInt(((InstructionPtrStrategy) itr.next()).getByteIndex() -
+                bi);
+    }
+}

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

Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/TypedInstruction.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/TypedInstruction.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/TypedInstruction.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/TypedInstruction.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,157 @@
+/*
+ * 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;
+
+import serp.bytecode.lowlevel.*;
+
+import serp.util.*;
+
+import java.util.*;
+
+
+/**
+ *  <p>Any typed instruction.</p>
+ *
+ *  @author Abe White
+ */
+public abstract class TypedInstruction extends Instruction {
+    private static final Set _opcodeTypes = new HashSet();
+
+    static {
+        _opcodeTypes.add(int.class.getName());
+        _opcodeTypes.add(long.class.getName());
+        _opcodeTypes.add(float.class.getName());
+        _opcodeTypes.add(double.class.getName());
+        _opcodeTypes.add(Object.class.getName());
+        _opcodeTypes.add(byte.class.getName());
+        _opcodeTypes.add(char.class.getName());
+        _opcodeTypes.add(short.class.getName());
+        _opcodeTypes.add(boolean.class.getName());
+        _opcodeTypes.add(void.class.getName());
+    }
+
+    TypedInstruction(Code owner) {
+        super(owner);
+    }
+
+    TypedInstruction(Code owner, int opcode) {
+        super(owner, opcode);
+    }
+
+    /**
+     *  Return the type for the given name.  Takes into account
+     *  the given mappings and the demote flag.
+     *
+     *  @param mappings        mappings of one type to another; for example,
+     *                                          array instruction treat booleans as ints, so
+     *                                          to reflect that there should be an index x of the
+     *                                          array such that mappings[x][0] = boolean.class and
+     *                                          mappings[x][1] = int.class; may be null if
+     *                                          no special mappings are needed
+     *  @param demote                if true, all object types will be demoted to
+     *                                          Object.class
+     */
+    String mapType(String type, Class[][] mappings, boolean demote) {
+        if (type == null) {
+            return null;
+        }
+
+        type = getProject().getNameCache().getExternalForm(type, false);
+
+        if (!_opcodeTypes.contains(type) && demote) {
+            type = Object.class.getName();
+        }
+
+        if (mappings != null) {
+            for (int i = 0; i < mappings.length; i++)
+                if (mappings[i][0].getName().equals(type)) {
+                    type = mappings[i][1].getName();
+                }
+        }
+
+        return type;
+    }
+
+    /**
+     *  Return the type name for this instruction.
+     *  If the type has not been set, this method will return null.
+     */
+    public abstract String getTypeName();
+
+    /**
+     *  Return the type for this instruction.
+     *  If the type has not been set, this method will return null.
+     */
+    public Class getType() {
+        String type = getTypeName();
+
+        if (type == null) {
+            return null;
+        }
+
+        return Strings.toClass(type, getClassLoader());
+    }
+
+    /**
+     *  Return the type for this instruction.
+     *  If the type has not been set, this method will return null.
+     */
+    public BCClass getTypeBC() {
+        String type = getTypeName();
+
+        if (type == null) {
+            return null;
+        }
+
+        return getProject().loadClass(type, getClassLoader());
+    }
+
+    /**
+     *  Set the type of this instruction.  Types that have no direct
+     *  support will be converted accordingly.
+     *
+     *  @return this instruction, for method chaining
+     */
+    public abstract TypedInstruction setType(String type);
+
+    /**
+     *  Set the type of this instruction.  Types that have no direct
+     *  support will be converted accordingly.
+     *
+     *  @return this instruction, for method chaining
+     */
+    public TypedInstruction setType(Class type) {
+        if (type == null) {
+            return setType((String) null);
+        }
+
+        return setType(type.getName());
+    }
+
+    /**
+     *  Set the type of this instruction.  Types that have no direct
+     *  support will be converted accordingly.
+     *
+     *  @return this instruction, for method chaining
+     */
+    public TypedInstruction setType(BCClass type) {
+        if (type == null) {
+            return setType((String) null);
+        }
+
+        return setType(type.getName());
+    }
+}

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

Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/UnknownAttribute.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/UnknownAttribute.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/UnknownAttribute.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/UnknownAttribute.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,75 @@
+/*
+ * 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;
+
+import serp.bytecode.visitor.*;
+
+import java.io.*;
+
+
+/**
+ *  <p>An unrecognized attribute; class files are allowed to contain
+ *  attributes that are not recognized, and the JVM must ignore them.</p>
+ *
+ *  @author Abe White
+ */
+public class UnknownAttribute extends Attribute {
+    private byte[] _value = new byte[0];
+
+    UnknownAttribute(int nameIndex, Attributes owner) {
+        super(nameIndex, owner);
+    }
+
+    int getLength() {
+        return _value.length;
+    }
+
+    /**
+     *  The value is of unknown content, so it is stored as a byte array.
+     */
+    public byte[] getValue() {
+        return _value;
+    }
+
+    /**
+     *  The value is of unknown content, so it is stored as a byte array.
+     */
+    public void setValue(byte[] value) {
+        if (value == null) {
+            value = new byte[0];
+        }
+
+        _value = value;
+    }
+
+    public void acceptVisit(BCVisitor visit) {
+        visit.enterUnknownAttribute(this);
+        visit.exitUnknownAttribute(this);
+    }
+
+    void read(Attribute other) {
+        setValue(((UnknownAttribute) other).getValue());
+    }
+
+    void read(DataInput in, int length) throws IOException {
+        _value = new byte[length];
+        in.readFully(_value);
+    }
+
+    void write(DataOutput out, int length) throws IOException {
+        out.write(_value);
+    }
+}

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

Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/WideInstruction.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/WideInstruction.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/WideInstruction.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/WideInstruction.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,427 @@
+/*
+ * 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;
+
+import serp.bytecode.visitor.*;
+
+import java.io.*;
+
+
+/**
+ *  <p>The <code>wide</code> instruction, which is used to allow other
+ *  instructions to index values beyond what they can normally index baed
+ *  on the length of their arguments.</p>
+ *
+ *  @author Abe White
+ */
+public class WideInstruction extends LocalVariableInstruction {
+    private static final Class[][] _mappings = new Class[][] {
+            { byte.class, int.class },
+            { boolean.class, int.class },
+            { char.class, int.class },
+            { short.class, int.class },
+            { void.class, int.class },
+        };
+    private int _ins = Constants.NOP;
+    private int _inc = -1;
+
+    WideInstruction(Code owner) {
+        super(owner, Constants.WIDE);
+    }
+
+    int getLength() {
+        // opcode, ins, index
+        int length = super.getLength() + 1 + 2;
+
+        // increment
+        if (getInstruction() == Constants.IINC) {
+            length += 2;
+        }
+
+        return length;
+    }
+
+    public int getStackChange() {
+        switch (getInstruction()) {
+        case Constants.ILOAD:
+        case Constants.FLOAD:
+        case Constants.ALOAD:
+            return 1;
+
+        case Constants.LLOAD:
+        case Constants.DLOAD:
+            return 2;
+
+        case Constants.ISTORE:
+        case Constants.FSTORE:
+        case Constants.ASTORE:
+            return -1;
+
+        case Constants.LSTORE:
+        case Constants.DSTORE:
+            return -2;
+
+        default:
+            return 0;
+        }
+    }
+
+    public int getLogicalStackChange() {
+        switch (getInstruction()) {
+        case Constants.ILOAD:
+        case Constants.FLOAD:
+        case Constants.ALOAD:
+        case Constants.LLOAD:
+        case Constants.DLOAD:
+            return 1;
+
+        case Constants.ISTORE:
+        case Constants.FSTORE:
+        case Constants.ASTORE:
+        case Constants.LSTORE:
+        case Constants.DSTORE:
+            return -1;
+
+        default:
+            return 0;
+        }
+    }
+
+    public String getTypeName() {
+        switch (getInstruction()) {
+        case Constants.ILOAD:
+        case Constants.ISTORE:
+            return int.class.getName();
+
+        case Constants.LLOAD:
+        case Constants.LSTORE:
+            return long.class.getName();
+
+        case Constants.FLOAD:
+        case Constants.FSTORE:
+            return float.class.getName();
+
+        case Constants.DLOAD:
+        case Constants.DSTORE:
+            return double.class.getName();
+
+        case Constants.ALOAD:
+        case Constants.ASTORE:
+            return Object.class.getName();
+
+        default:
+            return null;
+        }
+    }
+
+    public TypedInstruction setType(String type) {
+        type = mapType(type, _mappings, true);
+
+        switch (getInstruction()) {
+        case Constants.ILOAD:
+        case Constants.LLOAD:
+        case Constants.FLOAD:
+        case Constants.DLOAD:
+        case Constants.ALOAD:
+
+            if (type == null) {
+                throw new IllegalStateException();
+            }
+
+            switch (type.charAt(0)) {
+            case 'i':
+                return (TypedInstruction) setInstruction(Constants.ILOAD);
+
+            case 'l':
+                return (TypedInstruction) setInstruction(Constants.LLOAD);
+
+            case 'f':
+                return (TypedInstruction) setInstruction(Constants.FLOAD);
+
+            case 'd':
+                return (TypedInstruction) setInstruction(Constants.DLOAD);
+
+            default:
+                return (TypedInstruction) setInstruction(Constants.ALOAD);
+            }
+
+        case Constants.ISTORE:
+        case Constants.LSTORE:
+        case Constants.FSTORE:
+        case Constants.DSTORE:
+        case Constants.ASTORE:
+
+            if (type == null) {
+                throw new IllegalStateException();
+            }
+
+            switch (type.charAt(0)) {
+            case 'i':
+                return (TypedInstruction) setInstruction(Constants.ISTORE);
+
+            case 'l':
+                return (TypedInstruction) setInstruction(Constants.LSTORE);
+
+            case 'f':
+                return (TypedInstruction) setInstruction(Constants.FSTORE);
+
+            case 'd':
+                return (TypedInstruction) setInstruction(Constants.DSTORE);
+
+            default:
+                return (TypedInstruction) setInstruction(Constants.ASTORE);
+            }
+
+        default:
+
+            if (type != null) {
+                throw new IllegalStateException("Augmented instruction not " +
+                    "typed");
+            }
+
+            return this;
+        }
+    }
+
+    /**
+      *  Return the opcode of the instruction to modify; this will return one
+     *  of the constants defined in        {@link Constants}.
+     */
+    public int getInstruction() {
+        return _ins;
+    }
+
+    /**
+     *  Set the type of instruction this wide instruction modifies.
+     */
+    public WideInstruction setInstruction(Instruction ins) {
+        if (ins == null) {
+            return setInstruction(Constants.NOP);
+        }
+
+        setInstruction(ins.getOpcode());
+
+        if (ins instanceof IIncInstruction) {
+            setIncrement(((IIncInstruction) ins).getIncrement());
+        }
+
+        return this;
+    }
+
+    /**
+     *  Set the type of instruction this wide instruction modifies.
+     */
+    public WideInstruction setInstruction(int opcode) {
+        _ins = opcode;
+
+        return this;
+    }
+
+    /**
+     *  Set the type of instruction this wide instruction modifies.
+     *
+     *  @return this instruction, for method chaining
+     */
+    public WideInstruction iinc() {
+        return setInstruction(Constants.IINC);
+    }
+
+    /**
+     *  Set the type of instruction this wide instruction modifies.
+     *
+     *  @return this instruction, for method chaining
+     */
+    public WideInstruction ret() {
+        return setInstruction(Constants.RET);
+    }
+
+    /**
+     *  Set the type of instruction this wide instruction modifies.
+     *
+     *  @return this instruction, for method chaining
+     */
+    public WideInstruction iload() {
+        return setInstruction(Constants.ILOAD);
+    }
+
+    /**
+     *  Set the type of instruction this wide instruction modifies.
+     *
+     *  @return this instruction, for method chaining
+     */
+    public WideInstruction fload() {
+        return setInstruction(Constants.FLOAD);
+    }
+
+    /**
+     *  Set the type of instruction this wide instruction modifies.
+     *
+     *  @return this instruction, for method chaining
+     */
+    public WideInstruction aload() {
+        return setInstruction(Constants.ALOAD);
+    }
+
+    /**
+     *  Set the type of instruction this wide instruction modifies.
+     *
+     *  @return this instruction, for method chaining
+     */
+    public WideInstruction lload() {
+        return setInstruction(Constants.LLOAD);
+    }
+
+    /**
+     *  Set the type of instruction this wide instruction modifies.
+     *
+     *  @return this instruction, for method chaining
+     */
+    public WideInstruction dload() {
+        return setInstruction(Constants.DLOAD);
+    }
+
+    /**
+     *  Set the type of instruction this wide instruction modifies.
+     *
+     *  @return this instruction, for method chaining
+     */
+    public WideInstruction istore() {
+        return setInstruction(Constants.ISTORE);
+    }
+
+    /**
+     *  Set the type of instruction this wide instruction modifies.
+     *
+     *  @return this instruction, for method chaining
+     */
+    public WideInstruction fstore() {
+        return setInstruction(Constants.FSTORE);
+    }
+
+    /**
+     *  Set the type of instruction this wide instruction modifies.
+     *
+     *  @return this instruction, for method chaining
+     */
+    public WideInstruction astore() {
+        return setInstruction(Constants.ASTORE);
+    }
+
+    /**
+     *  Set the type of instruction this wide instruction modifies.
+     *
+     *  @return this instruction, for method chaining
+     */
+    public WideInstruction lstore() {
+        return setInstruction(Constants.LSTORE);
+    }
+
+    /**
+     *  Set the type of instruction this wide instruction modifies.
+     *
+     *  @return this instruction, for method chaining
+     */
+    public WideInstruction dstore() {
+        return setInstruction(Constants.DSTORE);
+    }
+
+    /**
+     *  Return the increment for this instruction if it augments IINC, or -1
+     *  if unset.
+      */
+    public int getIncrement() {
+        return _inc;
+    }
+
+    /**
+     *  Set the increment on this instruction if it augments IINC.
+     *
+     *  @return this Instruction, for method chaining
+     */
+    public WideInstruction setIncrement(int val) {
+        _inc = val;
+
+        return this;
+    }
+
+    /**
+     *  WideInstructions are equal if the instruction they augment is the same
+     *  or unset.
+     */
+    public boolean equalsInstruction(Instruction other) {
+        if (other == this) {
+            return true;
+        }
+
+        if (!super.equalsInstruction(other)) {
+            return false;
+        }
+
+        if (!(other instanceof WideInstruction)) {
+            return false;
+        }
+
+        WideInstruction ins = (WideInstruction) other;
+
+        int code = getInstruction();
+        int otherCode = ins.getInstruction();
+
+        if (code != otherCode) {
+            return false;
+        }
+
+        if (code == Constants.IINC) {
+            int inc = getIncrement();
+            int otherInc = ins.getIncrement();
+
+            return (inc == -1) || (otherInc == -1) || (inc == otherInc);
+        }
+
+        return true;
+    }
+
+    public void acceptVisit(BCVisitor visit) {
+        visit.enterWideInstruction(this);
+        visit.exitWideInstruction(this);
+    }
+
+    void read(Instruction orig) {
+        super.read(orig);
+        setInstruction(((WideInstruction) orig).getInstruction());
+    }
+
+    void read(DataInput in) throws IOException {
+        super.read(in);
+
+        setInstruction(in.readUnsignedByte());
+        setLocal(in.readUnsignedShort());
+
+        if (getInstruction() == Constants.IINC) {
+            setIncrement(in.readUnsignedShort());
+        }
+    }
+
+    void write(DataOutput out) throws IOException {
+        super.write(out);
+
+        out.writeByte(getInstruction());
+        out.writeShort(getLocal());
+
+        if (getInstruction() == Constants.IINC) {
+            out.writeShort(getIncrement());
+        }
+    }
+}

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

Added: incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/ClassEntry.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/ClassEntry.java?rev=417860&view=auto
==============================================================================
--- incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/ClassEntry.java (added)
+++ incubator/openjpa/trunk/serp/src/main/java/serp/bytecode/lowlevel/ClassEntry.java Wed Jun 28 12:46:13 2006
@@ -0,0 +1,101 @@
+/*
+ * 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 pool entry describing a class.
+ *  Class entries are used to refer to the current class, the superclass,
+ *  implemented interfaces, etc.  Each class entry contains the constant pool
+ *  index of the {@link UTF8Entry} that stores the class name, which is
+ *  represented in internal form.</p>
+ *
+ *  @author Abe White
+ */
+public class ClassEntry extends Entry implements ConstantEntry {
+    private int _nameIndex = 0;
+
+    /**
+     *  Default constructor.
+     */
+    public ClassEntry() {
+    }
+
+    /**
+     *  Constructor.
+     *
+     *  @param nameIndex        the constant pool index of the {@link UTF8Entry}
+     *                                          containing the class name
+     */
+    public ClassEntry(int nameIndex) {
+        _nameIndex = nameIndex;
+    }
+
+    /**
+     *  Return the constant pool index of the {@link UTF8Entry}
+     *  containing the class name.  Defaults to 0.
+     */
+    public int getNameIndex() {
+        return _nameIndex;
+    }
+
+    /**
+     *  Set the constant pool index of the {@link UTF8Entry}
+     *  containing the class name.
+     */
+    public void setNameIndex(int nameIndex) {
+        Object key = beforeModify();
+        _nameIndex = nameIndex;
+        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 getNameEntry() {
+        return (UTF8Entry) getPool().getEntry(_nameIndex);
+    }
+
+    public int getType() {
+        return Entry.CLASS;
+    }
+
+    public Object getConstant() {
+        return getNameEntry().getValue();
+    }
+
+    public void setConstant(Object value) {
+        getNameEntry().setConstant(value);
+    }
+
+    public void acceptVisit(BCVisitor visit) {
+        visit.enterClassEntry(this);
+        visit.exitClassEntry(this);
+    }
+
+    void readData(DataInput in) throws IOException {
+        _nameIndex = in.readUnsignedShort();
+    }
+
+    void writeData(DataOutput out) throws IOException {
+        out.writeShort(_nameIndex);
+    }
+}

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



Mime
View raw message