Added: labs/fluid/src/main/java/serp/bytecode/Annotation.java
URL:
http://svn.apache.org/viewvc/labs/fluid/src/main/java/serp/bytecode/Annotation.java?rev=886691&view=auto
==============================================================================
--- labs/fluid/src/main/java/serp/bytecode/Annotation.java (added)
+++ labs/fluid/src/main/java/serp/bytecode/Annotation.java Thu Dec 3 07:41:56
2009
@@ -0,0 +1,1010 @@
+package serp.bytecode;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import serp.bytecode.lowlevel.*;
+import serp.bytecode.visitor.*;
+import serp.util.*;
+
+/**
+ * A declared annotation.
+ *
+ * @author Abe White
+ */
+public class Annotation implements BCEntity, VisitAcceptor {
+ private static Method ENUM_VALUEOF = null;
+ private static Method ENUM_NAME = null;
+ static {
+ try {
+ Class c = Class.forName("java.lang.Enum");
+ ENUM_VALUEOF = c.getMethod("valueOf", new Class[] {
+ Class.class, String.class });
+ ENUM_NAME = c.getMethod("name", (Class[]) null);
+ } catch (Throwable t) {
+ // pre-1.5 JDK
+ }
+ }
+
+ private BCEntity _owner = null;
+ private int _typeIndex = 0;
+ private List _properties = null;
+
+ Annotation(BCEntity owner) {
+ _owner = owner;
+ }
+
+ /**
+ * Annotations are stored in an {...@link Annotations} table or as
+ * part of an {...@link Annotation} property value.
+ */
+ public BCEntity getOwner() {
+ return _owner;
+ }
+
+ void invalidate() {
+ _owner = null;
+ }
+
+ /**
+ * The index in the class {...@link ConstantPool} of the
+ * {...@link UTF8Entry} holding the type of this annotation.
+ */
+ public int getTypeIndex() {
+ return _typeIndex;
+ }
+
+ /**
+ * The index in the class {...@link ConstantPool} of the
+ * {...@link UTF8Entry} holding the type of this annotation.
+ */
+ public void setTypeIndex(int index) {
+ _typeIndex = index;
+ }
+
+ /**
+ * The name of this annotation's type.
+ */
+ public String getTypeName() {
+ String desc = ((UTF8Entry) getPool().getEntry(_typeIndex)).getValue();
+ return getProject().getNameCache().getExternalForm(desc, false);
+ }
+
+ /**
+ * The {...@link Class} object for this annotation's type.
+ */
+ public Class getType() {
+ return Strings.toClass(getTypeName(), getClassLoader());
+ }
+
+ /**
+ * The bytecode for the type of this annotation.
+ */
+ public BCClass getTypeBC() {
+ return getProject().loadClass(getTypeName(), getClassLoader());
+ }
+
+ /**
+ * This annotation's type.
+ */
+ public void setType(String type) {
+ type = getProject().getNameCache().getInternalForm(type, true);
+ _typeIndex = getPool().findUTF8Entry(type, true);
+ }
+
+ /**
+ * This annotation's type.
+ */
+ public void setType(Class type) {
+ setType(type.getName());
+ }
+
+ /**
+ * This annotation's type.
+ */
+ public void setType(BCClass type) {
+ setType(type.getName());
+ }
+
+ /**
+ * All declared properties.
+ */
+ public Property[] getProperties() {
+ if (_properties == null)
+ return new Property[0];
+ return (Property[]) _properties.toArray
+ (new Property[_properties.size()]);
+ }
+
+ /**
+ * Set the annotation properties. This method is useful when
+ * importing properties from another instance.
+ */
+ public void setProperties(Property[] props) {
+ clearProperties();
+ if (props != null)
+ for (int i = 0; i < props.length; i++)
+ addProperty(props[i]);
+ }
+
+ /**
+ * Return the property with the given name, or null if none.
+ */
+ public Property getProperty(String name) {
+ if (_properties == null)
+ return null;
+ Property prop;
+ for (int i = 0; i < _properties.size(); i++) {
+ prop = (Property) _properties.get(i);
+ if (prop.getName().equals(name))
+ return prop;
+ }
+ return null;
+ }
+
+ /**
+ * Import a property from another instance.
+ *
+ * @return the newly added property
+ */
+ public Property addProperty(Property p) {
+ Property prop = addProperty(p.getName());
+ prop.setValue(p.getValue());
+ return prop;
+ }
+
+ /**
+ * Add a new property.
+ */
+ public Property addProperty(String name) {
+ Property prop = new Property(this);
+ prop.setName(name);
+ if (_properties == null)
+ _properties = new ArrayList();
+ _properties.add(prop);
+ return prop;
+ }
+
+ /**
+ * Clear all annotation properties.
+ */
+ public void clearProperties() {
+ if (_properties == null)
+ return;
+ for (int i = 0; i < _properties.size(); i++)
+ ((Property) _properties.get(i)).invalidate();
+ _properties.clear();
+ }
+
+ /**
+ * Remove the given property.
+ *
+ * @return true if an property was removed, false otherwise
+ */
+ public boolean removeProperty(Property prop) {
+ return prop != null && removeProperty(prop.getName());
+ }
+
+ /**
+ * Remove the property with the given name.
+ *
+ * @return true if a property was removed, false otherwise
+ */
+ public boolean removeProperty(String name) {
+ if (name == null || _properties == null)
+ return false;
+ Property prop;
+ for (int i = 0; i < _properties.size(); i++) {
+ prop = (Property) _properties.get(i);
+ if (prop.getName().equals(name)) {
+ prop.invalidate();
+ _properties.remove(i);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public Project getProject() {
+ return _owner.getProject();
+ }
+
+ public ConstantPool getPool() {
+ return _owner.getPool();
+ }
+
+ public ClassLoader getClassLoader() {
+ return _owner.getClassLoader();
+ }
+
+ public boolean isValid() {
+ return _owner != null;
+ }
+
+ public void acceptVisit(BCVisitor visit) {
+ visit.enterAnnotation(this);
+ if (_properties != null)
+ for (int i = 0; i < _properties.size(); i++)
+ ((Property) _properties.get(i)).acceptVisit(visit);
+ visit.exitAnnotation(this);
+ }
+
+ int getLength() {
+ int len = 4;
+ if (_properties != null)
+ for (int i = 0; i < _properties.size(); i++)
+ len += ((Property) _properties.get(i)).getLength();
+ return len;
+ }
+
+ void read(DataInput in) throws IOException {
+ _typeIndex = in.readUnsignedShort();
+ clearProperties();
+ int props = in.readUnsignedShort();
+ if (props > 0) {
+ if (_properties == null)
+ _properties = new ArrayList(props);
+ Property prop;
+ for (int i = 0; i < props; i++) {
+ prop = new Property(this);
+ prop.read(in);
+ _properties.add(prop);
+ }
+ }
+ }
+
+ void write(DataOutput out) throws IOException {
+ out.writeShort(_typeIndex);
+ out.writeShort((_properties == null) ? 0 : _properties.size());
+ if (_properties != null) {
+ for (int i = 0; i < _properties.size(); i++)
+ ((Property) _properties.get(i)).write(out);
+ }
+ }
+
+ /**
+ * An annotation property.
+ */
+ public static class Property implements BCEntity, VisitAcceptor {
+ private Annotation _owner = null;
+ private int _nameIndex = 0;
+ private final Value _value = new Value();
+ private Value[] _values = null;
+
+ Property(Annotation owner) {
+ _owner = owner;
+ }
+
+ /**
+ * The owning annotation.
+ */
+ public Annotation getAnnotation() {
+ return _owner;
+ }
+
+ void invalidate() {
+ _owner = null;
+ }
+
+ /**
+ * Return the index in the class {...@link ConstantPool} of the
+ * {...@link UTF8Entry} holding the name of this property.
+ */
+ public int getNameIndex() {
+ return _nameIndex;
+ }
+
+ /**
+ * Set the index in the class {...@link ConstantPool} of the
+ * {...@link UTF8Entry} holding the name of this property.
+ */
+ public void setNameIndex(int index) {
+ _nameIndex = index;
+ }
+
+ /**
+ * Return the name of this property.
+ */
+ public String getName() {
+ return ((UTF8Entry) getPool().getEntry(_nameIndex)).getValue();
+ }
+
+ /**
+ * Set the name of this property.
+ */
+ public void setName(String name) {
+ _nameIndex = getPool().findUTF8Entry(name, true);
+ }
+
+ /**
+ * Return the value of the property as its wrapper type.
+ * Returns class values as the class name.
+ */
+ public Object getValue() {
+ if (_values == null)
+ return getValue(_value);
+ Object[] vals = new Object[_values.length];
+ for (int i = 0; i < vals.length; i++)
+ vals[i] = getValue(_values[i]);
+ return vals;
+ }
+
+ /**
+ * Extract the Java value.
+ */
+ private Object getValue(Value val) {
+ if (val.index == -1)
+ return val.value;
+
+ Object o = ((ConstantEntry) getPool().getEntry(val.index)).
+ getConstant();
+ if (val.index2 != -1) {
+ // enum value
+ String e = getProject().getNameCache().
+ getExternalForm((String) o, false);
+ String name = ((UTF8Entry) getPool().getEntry(val.index2)).
+ getValue();
+ try {
+ Class cls = Class.forName(e, true, getClassLoader());
+ return ENUM_VALUEOF.invoke(null, new Object[] {cls, name});
+ } catch (Throwable t) {
+ return e + "." + name;
+ }
+ }
+ if (val.type == null)
+ return o;
+
+ switch (val.type.getName().charAt(0)) {
+ case 'b':
+ if (val.type == boolean.class)
+ return (((Number) o).intValue() != 0) ? Boolean.TRUE
+ : Boolean.FALSE;
+ return new Byte(((Number) o).byteValue());
+ case 'c':
+ return new Character((char) ((Number) o).intValue());
+ case 'j': // java.lang.Class
+ return getProject().getNameCache().getExternalForm((String) o,
+ false);
+ case 's':
+ return new Short(((Number) o).shortValue());
+ default:
+ return o;
+ }
+ }
+
+ /**
+ * Set value of this property. The value should be an instance of any
+ * primitive wrapper type, String, Class, BCClass, an enum constant,
+ * an annotation, or an array of any of these types.
+ */
+ public void setValue(Object value) {
+ if (!value.getClass().isArray()) {
+ _values = null;
+ setValue(_value, value);
+ } else {
+ _value.value = null;
+ _values = new Value[Array.getLength(value)];
+ for (int i = 0; i < _values.length; i++) {
+ _values[i] = new Value();
+ setValue(_values[i], Array.get(value, i));
+ }
+ }
+ }
+
+ /**
+ * Set the given value.
+ */
+ private void setValue(Value val, Object o) {
+ if (o instanceof String)
+ setValue(val, (String) o);
+ else if (o instanceof Boolean)
+ setValue(val, ((Boolean) o).booleanValue());
+ else if (o instanceof Byte)
+ setValue(val, ((Byte) o).byteValue());
+ else if (o instanceof Character)
+ setValue(val, ((Character) o).charValue());
+ else if (o instanceof Double)
+ setValue(val, ((Double) o).doubleValue());
+ else if (o instanceof Float)
+ setValue(val, ((Float) o).floatValue());
+ else if (o instanceof Integer)
+ setValue(val, ((Integer) o).intValue());
+ else if (o instanceof Long)
+ setValue(val, ((Long) o).longValue());
+ else if (o instanceof Short)
+ setValue(val, ((Short) o).shortValue());
+ else if (o instanceof Class)
+ setClassNameValue(val, ((Class) o).getName());
+ else if (o instanceof BCClass)
+ setClassNameValue(val, ((BCClass) o).getName());
+ else if (o instanceof Annotation)
+ setValue(val, (Annotation) o);
+ else {
+ String name = getEnumName(o);
+ if (name != null) {
+ String type = getProject().getNameCache().
+ getInternalForm(o.getClass().getName(), true);
+ val.index = getPool().findUTF8Entry(type, true);
+ val.index2 = getPool().findUTF8Entry(name, true);
+ val.value = null;
+ val.type = null;
+ } else {
+ val.index = -1;
+ val.index2 = -1;
+ val.value = o;
+ val.type = o.getClass();
+ }
+ }
+ }
+
+ /**
+ * Return the name of this enum value, or null if not an enum.
+ */
+ private static String getEnumName(Object o) {
+ for (Class c = o.getClass(); true; c = c.getSuperclass()) {
+ if (c == Object.class || c == null)
+ return null;
+ if ("java.lang.Enum".equals(c.getName()))
+ break;
+ }
+ try {
+ return (String) ENUM_NAME.invoke(o, (Object[]) null);
+ } catch (Throwable t) {
+ return o.toString();
+ }
+ }
+
+ /**
+ * Return the string value of this property, or null if not set.
+ */
+ public String getStringValue() {
+ return (String) getValue();
+ }
+
+ /**
+ * Return the boolean value of this property, or false if not set.
+ */
+ public boolean getBooleanValue() {
+ Object value = getValue();
+ return (value == null) ? false : ((Boolean) value).booleanValue();
+ }
+
+ /**
+ * Return the byte value of this property, or false if not set.
+ */
+ public byte getByteValue() {
+ Object value = getValue();
+ return (value == null) ? (byte) 0 : ((Number) value).byteValue();
+ }
+
+ /**
+ * Return the int value of this property, or 0 if not set.
+ */
+ public int getIntValue() {
+ Object value = getValue();
+ return (value == null) ? 0 : ((Number) value).intValue();
+ }
+
+ /**
+ * Return the long value of this property, or 0 if not set.
+ */
+ public long getLongValue() {
+ Object value = getValue();
+ return (value == null) ? 0L : ((Number) value).longValue();
+ }
+
+ /**
+ * Return the float value of this property, or 0 if not set.
+ */
+ public float getFloatValue() {
+ Object value = getValue();
+ return (value == null) ? 0F : ((Number) value).floatValue();
+ }
+
+ /**
+ * Return the double value of this property, or 0 if not set.
+ */
+ public double getDoubleValue() {
+ Object value = getValue();
+ return (value == null) ? 0D : ((Number) value).doubleValue();
+ }
+
+ /**
+ * Return the short value of this property, or 0 if not set.
+ */
+ public short getShortValue() {
+ Object value = getValue();
+ return (value == null) ? (short) 0 : ((Number) value).shortValue();
+ }
+
+ /**
+ * Return the class value of this property, or null if not set.
+ */
+ public String getClassNameValue() {
+ return (String) getValue();
+ }
+
+ /**
+ * Return the annotation value of this property, or null if not set.
+ */
+ public Annotation getAnnotationValue() {
+ return (Annotation) getValue();
+ }
+
+ /**
+ * Set the string value of this property.
+ */
+ public void setValue(String value) {
+ _values = null;
+ setValue(_value, value);
+ }
+
+ /**
+ * Set the string value of this property.
+ */
+ private void setValue(Value val, String o) {
+ val.index = getPool().findUTF8Entry(o, true);
+ val.index2 = -1;
+ val.value = null;
+ val.type = null;
+ }
+
+ /**
+ * Set the boolean value of this property.
+ */
+ public void setValue(boolean value) {
+ _values = null;
+ setValue(_value, value);
+ }
+
+ /**
+ * Set the boolean value of this property.
+ */
+ private void setValue(Value val, boolean o) {
+ setValue(val, (o) ? 1 : 0);
+ val.type = boolean.class;
+ }
+
+ /**
+ * Set the byte value of this property.
+ */
+ public void setValue(byte value) {
+ _values = null;
+ setValue(_value, value);
+ }
+
+ /**
+ * Set the byte value of this property.
+ */
+ private void setValue(Value val, byte o) {
+ setValue(val, (int) o);
+ val.type = byte.class;
+ }
+
+ /**
+ * Set the int value of this property.
+ */
+ public void setValue(int value) {
+ _values = null;
+ setValue(_value, value);
+ }
+
+ /**
+ * Set the int value of this property.
+ */
+ private void setValue(Value val, int o) {
+ val.index = getPool().findIntEntry(o, true);
+ val.index2 = -1;
+ val.value = null;
+ val.type = null;
+ }
+
+ /**
+ * Set the long value of this property.
+ */
+ public void setValue(long value) {
+ _values = null;
+ setValue(_value, value);
+ }
+
+ /**
+ * Set the long value of this property.
+ */
+ private void setValue(Value val, long o) {
+ val.index = getPool().findLongEntry(o, true);
+ val.index2 = -1;
+ val.value = null;
+ val.type = null;
+ }
+
+ /**
+ * Set the float value of this property.
+ */
+ public void setValue(float value) {
+ _values = null;
+ setValue(_value, value);
+ }
+
+ /**
+ * Set the float value of this property.
+ */
+ private void setValue(Value val, float o) {
+ val.index = getPool().findFloatEntry(o, true);
+ val.index2 = -1;
+ val.value = null;
+ val.type = null;
+ }
+
+ /**
+ * Set the double value of this property.
+ */
+ public void setValue(double value) {
+ _values = null;
+ setValue(_value, value);
+ }
+
+ /**
+ * Set the double value of this property.
+ */
+ private void setValue(Value val, double o) {
+ val.index = getPool().findDoubleEntry(o, true);
+ val.index2 = -1;
+ val.value = null;
+ val.type = null;
+ }
+
+ /**
+ * Set the short value of this property.
+ */
+ public void setValue(short value) {
+ _values = null;
+ setValue(_value, value);
+ }
+
+ /**
+ * Set the short value of this property.
+ */
+ private void setValue(Value val, short o) {
+ setValue(val, (int) o);
+ val.type = short.class;
+ }
+
+ /**
+ * Set the class value of this property.
+ */
+ public void setValue(Class value) {
+ setClassNameValue(value.getName());
+ }
+
+ /**
+ * Set the class value of this property.
+ */
+ public void setValue(BCClass value) {
+ setClassNameValue(value.getName());
+ }
+
+ /**
+ * Set the class value of this property.
+ */
+ public void setClassNameValue(String value) {
+ _values = null;
+ setClassNameValue(_value, value);
+ }
+
+ /**
+ * Set the class value of this property.
+ */
+ private void setClassNameValue(Value val, String o) {
+ o = getProject().getNameCache().getInternalForm(o, true);
+ val.index = getPool().findUTF8Entry(o, true);
+ val.index2 = -1;
+ val.value = null;
+ val.type = Class.class;
+ }
+
+ /**
+ * Set the annotation value of this property by importing the given
+ * annotation from another instance.
+ */
+ public Annotation setValue(Annotation value) {
+ _values = null;
+ return setValue(_value, value);
+ }
+
+ /**
+ * Set the annotation value of this property by importing the given
+ * annotation from another instance.
+ */
+ private Annotation setValue(Value val, Annotation o) {
+ Annotation anno = new Annotation(this);
+ anno.setType(o.getTypeName());
+ anno.setProperties(o.getProperties());
+ val.index = -1;
+ val.index2 = -1;
+ val.value = anno;
+ val.type = null;
+ return anno;
+ }
+
+ /**
+ * Set the annotation value of this property by importing the given
+ * annotation from another instance.
+ */
+ public Annotation[] setValue(Annotation[] value) {
+ _value.value = null;
+ _values = new Value[value.length];
+ Annotation[] ret = new Annotation[value.length];
+ for (int i = 0; i < _values.length; i++) {
+ _values[i] = new Value();
+ ret[i] = setValue(_values[i], value[i]);
+ }
+ return ret;
+ }
+
+ /**
+ * Set this property value to a new annotation of the given type,
+ * returning the annotation for manipulation.
+ */
+ public Annotation newAnnotationValue(Class type) {
+ return newAnnotationValue(type.getName());
+ }
+
+ /**
+ * Set this property value to a new annotation of the given type,
+ * returning the annotation for manipulation.
+ */
+ public Annotation newAnnotationValue(BCClass type) {
+ return newAnnotationValue(type.getName());
+ }
+
+ /**
+ * Set this property value to a new annotation of the given type,
+ * returning the annotation for manipulation.
+ */
+ public Annotation newAnnotationValue(String type) {
+ Annotation anno = new Annotation(this);
+ anno.setType(type);
+ _values = null;
+ _value.index = -1;
+ _value.index2 = -1;
+ _value.value = anno;
+ _value.type = null;
+ return anno;
+ }
+
+ /**
+ * Set this property value to a new annotation array of the given type
+ * and length, returning the annotations for manipulation.
+ */
+ public Annotation[] newAnnotationArrayValue(Class type, int length) {
+ return newAnnotationArrayValue(type.getName(), length);
+ }
+
+ /**
+ * Set this property value to a new annotation array of the given type
+ * and length, returning the annotations for manipulation.
+ */
+ public Annotation[] newAnnotationArrayValue(BCClass type, int length) {
+ return newAnnotationArrayValue(type.getName(), length);
+ }
+
+ /**
+ * Set this property value to a new annotation array of the given type
+ * and length, returning the annotations for manipulation.
+ */
+ public Annotation[] newAnnotationArrayValue(String type, int length) {
+ _value.value = null;
+ _values = new Value[length];
+ Annotation[] ret = new Annotation[length];
+ for (int i = 0; i < length; i++) {
+ ret[i] = new Annotation(this);
+ ret[i].setType(type);
+ _values[i] = new Value();
+ _values[i].index = -1;
+ _values[i].index2 = -1;
+ _values[i].value = ret[i];
+ _values[i].type = null;
+ }
+ return ret;
+ }
+
+ public Project getProject() {
+ return _owner.getProject();
+ }
+
+ public ConstantPool getPool() {
+ return _owner.getPool();
+ }
+
+ public ClassLoader getClassLoader() {
+ return _owner.getClassLoader();
+ }
+
+ public boolean isValid() {
+ return _owner != null && (_values != null || _value.index != -1
+ || _value.value != null);
+ }
+
+ public void acceptVisit(BCVisitor visit) {
+ visit.enterAnnotationProperty(this);
+ visit.exitAnnotationProperty(this);
+ }
+
+ int getLength() {
+ if (!isValid())
+ throw new IllegalStateException();
+
+ int len = 2; // name
+ if (_values == null)
+ len += getLength(_value);
+ else {
+ len += 3; // arr length + tag
+ for (int i = 0; i < _values.length; i++)
+ len += getLength(_values[i]);
+ }
+ return len;
+ }
+
+ /**
+ * Return the length of the given value.
+ */
+ private int getLength(Value val) {
+ if (val.index2 != -1)
+ return 5; // tag + enum type + enum name
+ if (val.index != -1)
+ return 3; // tag + constant or class
+ return 1 + ((Annotation) val.value).getLength(); // tag + anno
+ }
+
+ void read(DataInput in) throws IOException {
+ _nameIndex = in.readUnsignedShort();
+ int tag = in.readByte();
+ if (tag == '[') {
+ int len = in.readUnsignedShort();
+ _values = new Value[len];
+ for (int i = 0; i < len; i++) {
+ _values[i] = new Value();
+ read(_values[i], in.readByte(), in);
+ }
+ } else
+ read(_value, tag, in);
+ }
+
+ /**
+ * Read data into the given value.
+ */
+ private void read(Value val, int tag, DataInput in) throws IOException
{
+ switch (tag) {
+ case 'B':
+ val.index = in.readUnsignedShort();
+ val.index2 = -1;
+ val.value = null;
+ val.type = byte.class;
+ break;
+ case 'C':
+ val.index = in.readUnsignedShort();
+ val.index2 = -1;
+ val.value = null;
+ val.type = char.class;
+ break;
+ case 'D':
+ case 'F':
+ case 'I':
+ case 'J':
+ case 'S':
+ case 's':
+ val.index = in.readUnsignedShort();
+ val.index2 = -1;
+ val.value = null;
+ val.type = null;
+ break;
+ case 'Z':
+ val.index = in.readUnsignedShort();
+ val.index2 = -1;
+ val.value = null;
+ val.type = boolean.class;
+ break;
+ case 'c':
+ val.index = in.readUnsignedShort();
+ val.index2 = -1;
+ val.value = null;
+ val.type = Class.class;
+ break;
+ case 'e':
+ val.index = in.readUnsignedShort();
+ val.index2 = in.readUnsignedShort();
+ val.value = null;
+ val.type = null;
+ break;
+ case '@':
+ Annotation anno = new Annotation(this);
+ anno.read(in);
+ val.index = -1;
+ val.index2 = -1;
+ val.value = anno;
+ val.type = null;
+ break;
+ default:
+ throw new IllegalStateException(String.valueOf(tag));
+ }
+ }
+
+ void write(DataOutput out) throws IOException {
+ if (!isValid())
+ throw new IllegalStateException();
+
+ out.writeShort(_nameIndex);
+ if (_values == null)
+ write(_value, out);
+ else {
+ out.writeByte('[');
+ out.writeShort(_values.length);
+ for (int i = 0; i < _values.length; i++)
+ write(_values[i], out);
+ }
+ }
+
+ /**
+ * Write the data for the given value to the stream.
+ */
+ private void write(Value val, DataOutput out) throws IOException {
+ if (val.index2 != -1) {
+ out.writeByte('e');
+ out.writeShort(val.index);
+ out.writeShort(val.index2);
+ } else if (val.index != -1) {
+ if (val.type != null) {
+ switch (val.type.getName().charAt(0)) {
+ case 'b':
+ if (val.type == byte.class)
+ out.writeByte('B');
+ else
+ out.writeByte('Z');
+ break;
+ case 'c':
+ out.writeByte('C');
+ break;
+ case 'j': // java.lang.Class
+ out.writeByte('c');
+ break;
+ case 's':
+ out.writeByte('S');
+ break;
+ default:
+ throw new IllegalStateException(val.type.getName());
+ }
+ } else {
+ Entry entry = getPool().getEntry(val.index);
+ if (entry instanceof DoubleEntry)
+ out.writeByte('D');
+ else if (entry instanceof FloatEntry)
+ out.writeByte('F');
+ else if (entry instanceof IntEntry)
+ out.writeByte('I');
+ else if (entry instanceof LongEntry)
+ out.writeByte('J');
+ else if (entry instanceof UTF8Entry)
+ out.writeByte('s');
+ else
+ throw new IllegalStateException(entry.getClass().
+ getName());
+ }
+ out.writeShort(val.index);
+ } else {
+ out.writeByte('@');
+ ((Annotation) val.value).write(out);
+ }
+ }
+
+ /**
+ * Property value struct.
+ */
+ private static class Value {
+ public int index = -1;
+ public int index2 = -1;
+ public Class type = null;
+ public Object value = null;
+ }
+ }
+}
Propchange: labs/fluid/src/main/java/serp/bytecode/Annotation.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified:
labs/fluid/src/main/resources/org/apache/openjpa/sdo/localizer.properties
URL:
http://svn.apache.org/viewvc/labs/fluid/src/main/resources/org/apache/openjpa/sdo/localizer.properties?rev=886691&r1=886690&r2=886691&view=diff
==============================================================================
--- labs/fluid/src/main/resources/org/apache/openjpa/sdo/localizer.properties
(original)
+++ labs/fluid/src/main/resources/org/apache/openjpa/sdo/localizer.properties
Thu Dec 3 07:41:56 2009
@@ -1,3 +1,8 @@
+generate-unenhanced: Generating dynamic Java class {0} using classloader {1}
child of {2}.
+generate-enhanced: Enhancing dynamic Java class {0} using classloader {1}
child of {2}.
+load-enhanced: Loaded dynamic, enhanced Java class {0} into JVM using
classloader {1} child of {2}.
+load-enhanced-error: Error while loading dynamic, enhanced Java class {0} into
JVM using classloader {1} child of {2}.
+
type-mapping-new: Creating new SDO Type Mapping for "{0}" mapped to "{1}"
type-mapping-resolve: Resolving SDO Type Mapping for "{0}" mapped to "{1}"
resolve-mapping-failed: No cached metadata found for "{0}" in "{1}"
Modified: labs/fluid/src/test/java/example/basic/TestCRUD.java
URL:
http://svn.apache.org/viewvc/labs/fluid/src/test/java/example/basic/TestCRUD.java?rev=886691&r1=886690&r2=886691&view=diff
==============================================================================
--- labs/fluid/src/test/java/example/basic/TestCRUD.java (original)
+++ labs/fluid/src/test/java/example/basic/TestCRUD.java Thu Dec 3 07:41:56
2009
@@ -13,8 +13,7 @@
import test.common.AbstractSDOTest;
/**
- * Test basic CRUD operation with a simpleton Type that has no relation but
- * primitive properties.
+ * Test basic CRUD operation with a simpleton SDO Type that has no relation
but primitive properties.
*
* @author Pinaki Poddar
*
@@ -99,9 +98,10 @@
dataObject.setString("firstName", "Ron");
em.getTransaction().begin();
DataObject merged = em.merge(dataObject);
- int v1 = ImplHelper.getVersion(merged);
- assertTrue(v1>v0);
+ assertNotSame(merged, dataObject);
em.getTransaction().commit();
+ int v1 = ImplHelper.getVersion(merged);
+ assertTrue(v1>v0);
assertEquals("Ron", merged.getString("firstName"));
int after = count("Person");
assertEquals(before, after);
@@ -138,7 +138,7 @@
*/
// START SNIPPET:createPerson
DataObject createPerson(String ssn, String first, String last, int age)
{
- Type type = getType("Person");
+ Type type = getSDOType("Person");
DataObject data = DataFactory.INSTANCE.create(type);
data.set("ssn", ssn);
data.setString("firstName", first);
Added: labs/fluid/src/test/java/example/basic/TestConfiguration.java
URL:
http://svn.apache.org/viewvc/labs/fluid/src/test/java/example/basic/TestConfiguration.java?rev=886691&view=auto
==============================================================================
--- labs/fluid/src/test/java/example/basic/TestConfiguration.java (added)
+++ labs/fluid/src/test/java/example/basic/TestConfiguration.java Thu Dec 3
07:41:56 2009
@@ -0,0 +1,27 @@
+package example.basic;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+import org.apache.openjpa.sdo.SDODynamicClassResolver;
+import org.apache.openjpa.sdo.SDOEntityManager;
+import org.apache.openjpa.sdo.SDOEntityManagerFactory;
+
+import test.common.AbstractSDOTest;
+
+public class TestConfiguration extends AbstractSDOTest {
+ public void testEntityManagerFactory() {
+ assertNotNull(emf);
+ assertTrue(emf instanceof SDOEntityManagerFactory);
+ }
+
+ public void testEntityManager() {
+ EntityManager em = emf.createEntityManager();
+ assertNotNull(em);
+ assertTrue(em instanceof SDOEntityManager);
+ }
+
+ public void testClassResolver() {
+ assertTrue(emf.getConfiguration().getClassResolverInstance() instanceof
SDODynamicClassResolver);
+ }
+}
Propchange: labs/fluid/src/test/java/example/basic/TestConfiguration.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: labs/fluid/src/test/java/example/basic/TestRelation.java
URL:
http://svn.apache.org/viewvc/labs/fluid/src/test/java/example/basic/TestRelation.java?rev=886691&r1=886690&r2=886691&view=diff
==============================================================================
--- labs/fluid/src/test/java/example/basic/TestRelation.java (original)
+++ labs/fluid/src/test/java/example/basic/TestRelation.java Thu Dec 3
07:41:56 2009
@@ -149,8 +149,7 @@
*
*/
DataObject createPurchaseOrder() {
- DataObject purchaseOrder = DataFactory.INSTANCE.create(
- getType("PurchaseOrderType"));
+ DataObject purchaseOrder =
DataFactory.INSTANCE.create(getSDOType("PurchaseOrderType"));
purchaseOrder.setString("orderDate", "1999-10-20");
Modified: labs/fluid/src/test/java/org/apache/openjpa/sdo/TestSDO.java
URL:
http://svn.apache.org/viewvc/labs/fluid/src/test/java/org/apache/openjpa/sdo/TestSDO.java?rev=886691&r1=886690&r2=886691&view=diff
==============================================================================
--- labs/fluid/src/test/java/org/apache/openjpa/sdo/TestSDO.java (original)
+++ labs/fluid/src/test/java/org/apache/openjpa/sdo/TestSDO.java Thu Dec 3
07:41:56 2009
@@ -37,20 +37,20 @@
public class TestSDO extends AbstractSDOTest {
public void testPackage() {
- Type addressType = getType("USAddress");
+ Type addressType = getSDOType("USAddress");
assertNotNull(addressType);
String pkg = ImplHelper.getPackageName(addressType);
assertEquals("example.domain",pkg);
}
public void testInstanceClassIsNullForUserType() {
- Type addressType = getType("USAddress");
+ Type addressType = getSDOType("USAddress");
assertFalse(addressType.isDataType());
assertNull(addressType.getInstanceClass());
}
public void testIdentityType() {
- Type poType = getType("PurchaseOrderType");
+ Type poType = getSDOType("PurchaseOrderType");
assertNotNull(poType);
Property id2 = ImplHelper.getIdentityProperty(poType);
assertNotNull(id2);
@@ -64,8 +64,7 @@
*
*/
public void testCreateModel() {
- DataObject purchaseOrder = DataFactory.INSTANCE.create(
- getType("PurchaseOrderType"));
+ DataObject purchaseOrder =
DataFactory.INSTANCE.create(getSDOType("PurchaseOrderType"));
purchaseOrder.setString("orderDate", "1999-10-20");
Modified: labs/fluid/src/test/java/org/apache/openjpa/sdo/TestSourceCode.java
URL:
http://svn.apache.org/viewvc/labs/fluid/src/test/java/org/apache/openjpa/sdo/TestSourceCode.java?rev=886691&r1=886690&r2=886691&view=diff
==============================================================================
--- labs/fluid/src/test/java/org/apache/openjpa/sdo/TestSourceCode.java
(original)
+++ labs/fluid/src/test/java/org/apache/openjpa/sdo/TestSourceCode.java Thu Dec
3 07:41:56 2009
@@ -90,20 +90,20 @@
}
}
- public void testDuplicateMethod() {
- SourceCode code = new SourceCode("some.pkg", "SomeClass");
- try {
- code.addMethod("add", "int")
- .makePublic()
- .makeStatic()
- .addArgument("int", "a")
- .addArgument("int", "b");
- code.addMethod("add", "float")
- .addArgument("int", "a")
- .addArgument("int", "b");
- fail("Expected DuplicateField exception");
- } catch (IllegalArgumentException e) {
- //good
- }
- }
+// public void testDuplicateMethod() {
+// SourceCode code = new SourceCode("some.pkg", "SomeClass");
+// try {
+// code.addMethod("add", "int")
+// .makePublic()
+// .makeStatic()
+// .addArgument("int", "a")
+// .addArgument("int", "b");
+// code.addMethod("add", "float")
+// .addArgument("int", "a")
+// .addArgument("int", "b");
+// fail("Expected DuplicateField exception");
+// } catch (IllegalArgumentException e) {
+// //good
+// }
+// }
}
Modified: labs/fluid/src/test/java/test/common/AbstractSDOTest.java
URL:
http://svn.apache.org/viewvc/labs/fluid/src/test/java/test/common/AbstractSDOTest.java?rev=886691&r1=886690&r2=886691&view=diff
==============================================================================
--- labs/fluid/src/test/java/test/common/AbstractSDOTest.java (original)
+++ labs/fluid/src/test/java/test/common/AbstractSDOTest.java Thu Dec 3
07:41:56 2009
@@ -25,16 +25,15 @@
import junit.framework.TestCase;
import org.apache.openjpa.meta.MetaDataFactory;
-import org.apache.openjpa.meta.MetaDataRepository;
import org.apache.openjpa.persistence.OpenJPAEntityManager;
import org.apache.openjpa.sdo.SDOEntityManagerFactory;
-import org.apache.openjpa.sdo.SDOMappingRepository;
import org.apache.openjpa.sdo.SDOMetaDataFactory;
+import org.apache.openjpa.sdo.SDOTypeParser;
import commonj.sdo.Type;
/**
- * Abstract Test case sets up JPA persitence unt and SDO metadata from XML
+ * Abstract Test case sets up JPA persistence unit and SDO meta data from XML
* schema.
*
* @author Pinaki Poddar
@@ -42,7 +41,7 @@
*/
public abstract class AbstractSDOTest extends TestCase {
protected static SDOEntityManagerFactory emf;
- protected static SDOMappingRepository repos;
+ protected static SDOMetaDataFactory repos;
/**
* Obtain a EntityManagerFactory and initialize SDO Types.
@@ -54,26 +53,24 @@
assertNotNull(tmp);
assertTrue(tmp instanceof SDOEntityManagerFactory);
emf = (SDOEntityManagerFactory)tmp;
+ emf.createEntityManager();
}
}
- SDOMappingRepository getRepos() {
+ SDOMetaDataFactory getRepos() {
if (repos == null) {
MetaDataFactory mdf = emf.getConfiguration()
.getMetaDataRepositoryInstance().getMetaDataFactory();
assertTrue(mdf instanceof SDOMetaDataFactory);
- repos =
((SDOMetaDataFactory)mdf).getSDOMappingRepository();
+ repos = (SDOMetaDataFactory)mdf;
}
return repos;
}
- /**
- * Gets the type of given name.
- */
- protected Type getType(String name) {
- return getRepos().getType(name);
- }
+ protected Type getSDOType(String name) {
+ return SDOTypeParser.findType(name);
+ }
/**
* Count number of persistent instances of the given alias.
@@ -88,6 +85,6 @@
* Get the name of the persistence unit to be used by this receiver.
*/
protected String getPersistenceUnitName() {
- return System.getProperty("persistence.unit", "test");
+ return System.getProperty("persistence.unit", "sdo");
}
}
Modified: labs/fluid/src/test/resources/META-INF/persistence.xml
URL:
http://svn.apache.org/viewvc/labs/fluid/src/test/resources/META-INF/persistence.xml?rev=886691&r1=886690&r2=886691&view=diff
==============================================================================
--- labs/fluid/src/test/resources/META-INF/persistence.xml (original)
+++ labs/fluid/src/test/resources/META-INF/persistence.xml Thu Dec 3 07:41:56
2009
@@ -1,19 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
- <persistence-unit name="test">
+ <persistence-unit name="sdo">
+ <description>
+ Persistence unit for testing Fluid.
+ The configuration properties are essentially same as any
other JPA application except
+ i) openjpa.EntityManagerFactory must be set to "sdo"
+ and ii) openjpa.MetaDataFactory must be set as shown with
XML schema definitions.
+
+ Also set openjpa.DynamicEnhancementAgent to "false" because
Fluid generates the
+ enhanced bytecode for SDO Types dynamically.
+ </description>
<properties>
- <property name="openjpa.EntityManagerFactory"
value="sdo"/>
- <property name="openjpa.MetaDataFactory"
value="sdo(Resources=META-INF/person.xsd)"/>
+ <property name="openjpa.EntityManagerFactory"
value="sdo"/>
+ <property name="openjpa.MetaDataFactory"
value="sdo(Resources=META-INF/person.xsd;META-INF/po.xsd)"/>
+ <property name="openjpa.DynamicEnhancementAgent"
value="false"/>
+
<property name="openjpa.ConnectionDriverName"
value="com.mysql.jdbc.Driver"/>
- <property name="openjpa.ConnectionURL"
value="jdbc:mysql://localhost/SDO2"/>
- <property name="openjpa.ConnectionUserName"
value="root"/>
- <property name="openjpa.ConnectionPassword"
value="hello"/>
+ <property name="openjpa.ConnectionURL"
value="jdbc:mysql://localhost/fluid"/>
+ <property name="openjpa.ConnectionUserName"
value="root"/>
+ <property name="openjpa.ConnectionPassword" value=""/>
+
<property name="openjpa.jdbc.SynchronizeMappings"
value="buildSchema"/>
- <property name="openjpa.QueryCompilationCache"
value="false"/>
- <property name="openjpa.Log" value="DefaultLevel=TRACE,
SQL=TRACE, Query=TRACE"/>
- <property name="openjpa.BrokerImpl"
value="non-finalizing"/>
-
+ <property name="openjpa.QueryCompilationCache"
value="false"/>
+ <property name="openjpa.Log"
value="DefaultLevel=WARN, SQL=TRACE, Query=TRACE"/>
</properties>
</persistence-unit>
</persistence>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]