Author: aadamchik
Date: Mon Oct 9 20:59:01 2006
New Revision: 454601
URL: http://svn.apache.org/viewvc?view=rev&rev=454601
Log:
working simple properties interceptor
Added:
incubator/cayenne/sandbox/asm-enhancer/src/main/java/org/apache/cayenne/enhancer/ClassVisitorHelper.java
- copied, changed from r454593,
incubator/cayenne/sandbox/asm-enhancer/src/main/java/org/apache/cayenne/enhancer/ClassBuilder.java
Removed:
incubator/cayenne/sandbox/asm-enhancer/src/main/java/org/apache/cayenne/enhancer/ClassBuilder.java
Modified:
incubator/cayenne/sandbox/asm-enhancer/src/main/java/org/apache/cayenne/enhancer/PersistentClassVisitor.java
incubator/cayenne/sandbox/asm-enhancer/src/main/java/org/apache/cayenne/enhancer/PersistentGetterVisitor.java
incubator/cayenne/sandbox/asm-enhancer/src/main/java/org/apache/cayenne/enhancer/PersistentSetterVisitor.java
incubator/cayenne/sandbox/asm-enhancer/src/test/java/org/apache/cayenne/enhancer/CayenneEnhancerTest.java
incubator/cayenne/sandbox/asm-enhancer/src/test/java/org/apache/cayenne/enhancer/EnhancingClassLoader.java
incubator/cayenne/sandbox/asm-enhancer/src/test/java/org/apache/cayenne/enhancer/MockEnhancedPojo.java
incubator/cayenne/sandbox/asm-enhancer/src/test/java/org/apache/cayenne/enhancer/MockObjectContext.java
Copied:
incubator/cayenne/sandbox/asm-enhancer/src/main/java/org/apache/cayenne/enhancer/ClassVisitorHelper.java
(from r454593,
incubator/cayenne/sandbox/asm-enhancer/src/main/java/org/apache/cayenne/enhancer/ClassBuilder.java)
URL:
http://svn.apache.org/viewvc/incubator/cayenne/sandbox/asm-enhancer/src/main/java/org/apache/cayenne/enhancer/ClassVisitorHelper.java?view=diff&rev=454601&p1=incubator/cayenne/sandbox/asm-enhancer/src/main/java/org/apache/cayenne/enhancer/ClassBuilder.java&r1=454593&p2=incubator/cayenne/sandbox/asm-enhancer/src/main/java/org/apache/cayenne/enhancer/ClassVisitorHelper.java&r2=454601
==============================================================================
---
incubator/cayenne/sandbox/asm-enhancer/src/main/java/org/apache/cayenne/enhancer/ClassBuilder.java
(original)
+++
incubator/cayenne/sandbox/asm-enhancer/src/main/java/org/apache/cayenne/enhancer/ClassVisitorHelper.java
Mon Oct 9 20:59:01 2006
@@ -26,20 +26,29 @@
import org.objectweb.asm.Type;
/**
- * A builder that encapsulates common class enhancement operations.
+ * A helper for the ASM ClassVisitor that encapsulates common class enhancement
+ * operations.
*
* @author Andrus Adamchik
*/
-class ClassBuilder {
+class ClassVisitorHelper {
private String fieldPrefix = "$cay_";
private ClassVisitor classVisitor;
private Type currentClass;
- ClassBuilder(ClassVisitor classVisitor) {
+ ClassVisitorHelper(ClassVisitor classVisitor) {
this.classVisitor = classVisitor;
}
+ Type getCurrentClass() {
+ return currentClass;
+ }
+
+ String getPropertyField(String propertyName) {
+ return fieldPrefix + propertyName;
+ }
+
void reset(String className) {
// assuming no primitives or arrays
this.currentClass = Type.getType("L" + className + ";");
@@ -93,7 +102,7 @@
mv.visitLabel(l0);
mv.visitVarInsn(Opcodes.ALOAD, 0);
- // TODO: other opcodes
+ // TODO: andrus, 10/9/2006 other opcodes
if ("I".equals(asmType.getDescriptor())) {
mv.visitVarInsn(Opcodes.ILOAD, 1);
}
@@ -101,8 +110,11 @@
mv.visitVarInsn(Opcodes.ALOAD, 1);
}
- mv.visitFieldInsn(Opcodes.PUTFIELD, currentClass.getInternalName(),
fieldPrefix
- + propertyName, asmType.getDescriptor());
+ mv.visitFieldInsn(
+ Opcodes.PUTFIELD,
+ currentClass.getInternalName(),
+ getPropertyField(propertyName),
+ asmType.getDescriptor());
mv.visitInsn(Opcodes.RETURN);
Label l1 = new Label();
mv.visitLabel(l1);
@@ -126,10 +138,13 @@
Label l0 = new Label();
mv.visitLabel(l0);
mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitFieldInsn(Opcodes.GETFIELD, currentClass.getInternalName(),
fieldPrefix
- + propertyName, asmType.getDescriptor());
+ mv.visitFieldInsn(
+ Opcodes.GETFIELD,
+ currentClass.getInternalName(),
+ getPropertyField(propertyName),
+ asmType.getDescriptor());
- // TODO: other return opcodes
+ // TODO: andrus, 10/9/2006 other return opcodes
if ("I".equals(asmType.getDescriptor())) {
mv.visitInsn(Opcodes.IRETURN);
}
@@ -147,7 +162,7 @@
private void createField(String propertyName, Type asmType, int access) {
FieldVisitor fv = classVisitor.visitField(
access,
- fieldPrefix + propertyName,
+ getPropertyField(propertyName),
asmType.getDescriptor(),
null,
null);
Modified:
incubator/cayenne/sandbox/asm-enhancer/src/main/java/org/apache/cayenne/enhancer/PersistentClassVisitor.java
URL:
http://svn.apache.org/viewvc/incubator/cayenne/sandbox/asm-enhancer/src/main/java/org/apache/cayenne/enhancer/PersistentClassVisitor.java?view=diff&rev=454601&r1=454600&r2=454601
==============================================================================
---
incubator/cayenne/sandbox/asm-enhancer/src/main/java/org/apache/cayenne/enhancer/PersistentClassVisitor.java
(original)
+++
incubator/cayenne/sandbox/asm-enhancer/src/main/java/org/apache/cayenne/enhancer/PersistentClassVisitor.java
Mon Oct 9 20:59:01 2006
@@ -35,12 +35,12 @@
class PersistentClassVisitor extends ClassAdapter {
private Collection<String> enhancedProperties;
- private ClassBuilder builder;
+ private ClassVisitorHelper helper;
PersistentClassVisitor(ClassVisitor visitor, Collection<String>
enhancedProperties) {
super(visitor);
this.enhancedProperties = enhancedProperties;
- this.builder = new ClassBuilder(this);
+ this.helper = new ClassVisitorHelper(this);
}
/**
@@ -55,14 +55,14 @@
String superName,
String[] interfaces) {
- builder.reset(name);
- interfaces = builder.addInterface(interfaces, Persistent.class);
-
+ helper.reset(name);
+ interfaces = helper.addInterface(interfaces, Persistent.class);
+
super.visit(version, access, name, signature, superName, interfaces);
- builder.createProperty(ObjectId.class, "objectId");
- builder.createProperty(ObjectContext.class, "objectContext", true);
- builder.createProperty(Integer.TYPE, "persistenceState");
+ helper.createProperty(ObjectId.class, "objectId");
+ helper.createProperty(ObjectContext.class, "objectContext", true);
+ helper.createProperty(Integer.TYPE, "persistenceState");
}
/**
@@ -81,15 +81,15 @@
// TODO: andrus, 10/8/2006 - check method sig for real... just checking
// the name is not enough
- // String getProperty = EnhancerUtil.propertyNameForGetter(name);
- // if (getProperty != null &&
enhancedProperties.contains(getProperty)) {
- // return new PersistentGetterVisitor(mv, className, getProperty);
- // }
- //
- // String setProperty = EnhancerUtil.propertyNameForSetter(name);
- // if (setProperty != null &&
enhancedProperties.contains(setProperty)) {
- // return new PersistentSetterVisitor(mv, className, setProperty);
- // }
+ String getProperty = EnhancerUtil.propertyNameForGetter(name);
+ if (getProperty != null && enhancedProperties.contains(getProperty)) {
+ return new PersistentGetterVisitor(mv, helper, getProperty);
+ }
+
+ String setProperty = EnhancerUtil.propertyNameForSetter(name);
+ if (setProperty != null && enhancedProperties.contains(setProperty)) {
+ return new PersistentSetterVisitor(mv, helper, setProperty);
+ }
return mv;
}
Modified:
incubator/cayenne/sandbox/asm-enhancer/src/main/java/org/apache/cayenne/enhancer/PersistentGetterVisitor.java
URL:
http://svn.apache.org/viewvc/incubator/cayenne/sandbox/asm-enhancer/src/main/java/org/apache/cayenne/enhancer/PersistentGetterVisitor.java?view=diff&rev=454601&r1=454600&r2=454601
==============================================================================
---
incubator/cayenne/sandbox/asm-enhancer/src/main/java/org/apache/cayenne/enhancer/PersistentGetterVisitor.java
(original)
+++
incubator/cayenne/sandbox/asm-enhancer/src/main/java/org/apache/cayenne/enhancer/PersistentGetterVisitor.java
Mon Oct 9 20:59:01 2006
@@ -18,17 +18,22 @@
****************************************************************/
package org.apache.cayenne.enhancer;
+import org.apache.cayenne.ObjectContext;
+import org.objectweb.asm.Label;
import org.objectweb.asm.MethodAdapter;
import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
class PersistentGetterVisitor extends MethodAdapter {
- private String className;
+ private ClassVisitorHelper helper;
private String propertyName;
- PersistentGetterVisitor(MethodVisitor mv, String className, String
propertyName) {
+ PersistentGetterVisitor(MethodVisitor mv, ClassVisitorHelper helper,
+ String propertyName) {
super(mv);
- this.className = className;
+ this.helper = helper;
this.propertyName = propertyName;
}
@@ -36,20 +41,33 @@
public void visitCode() {
super.visitCode();
- // mv.visitVarInsn(Opcodes.ALOAD, 0);
- // mv.visitFieldInsn(Opcodes.GETFIELD, className,
- // "$cayenne_persistenceDelegate",
- // "Lorg/apache/cayenne/jpa/enhancer/PersistenceDelegate;");
- // Label l1 = new Label();
- // mv.visitJumpInsn(Opcodes.IFNULL, l1);
- // mv.visitVarInsn(Opcodes.ALOAD, 0);
- // mv.visitFieldInsn(Opcodes.GETFIELD, className,
- // PojoAdapterFactory.PERSISTENCE_DELEGATE_FIELD,
- // "Lorg/apache/cayenne/jpa/enhancer/PersistenceDelegate;");
- // mv.visitLdcInsn(propertyName);
- // mv.visitMethodInsn(Opcodes.INVOKEINTERFACE,
- // "org/apache/cayenne/jpa/enhancer/PersistenceDelegate",
- // "prepareForAccess", "(Ljava/lang/String;)V");
- // mv.visitLabel(l1);
+ String field = helper.getPropertyField("objectContext");
+ Type objectContextType = Type.getType(ObjectContext.class);
+
+ mv.visitVarInsn(Opcodes.ALOAD, 0);
+ mv.visitFieldInsn(
+ Opcodes.GETFIELD,
+ helper.getCurrentClass().getInternalName(),
+ field,
+ objectContextType.getDescriptor());
+ Label l1 = new Label();
+ mv.visitJumpInsn(Opcodes.IFNULL, l1);
+ Label l2 = new Label();
+ mv.visitLabel(l2);
+ mv.visitLineNumber(42, l2);
+ mv.visitVarInsn(Opcodes.ALOAD, 0);
+ mv.visitFieldInsn(
+ Opcodes.GETFIELD,
+ helper.getCurrentClass().getInternalName(),
+ field,
+ objectContextType.getDescriptor());
+ mv.visitVarInsn(Opcodes.ALOAD, 0);
+ mv.visitLdcInsn(propertyName);
+ mv.visitMethodInsn(
+ Opcodes.INVOKEINTERFACE,
+ objectContextType.getInternalName(),
+ "prepareForAccess",
+ "(Lorg/apache/cayenne/Persistent;Ljava/lang/String;)V");
+ mv.visitLabel(l1);
}
}
Modified:
incubator/cayenne/sandbox/asm-enhancer/src/main/java/org/apache/cayenne/enhancer/PersistentSetterVisitor.java
URL:
http://svn.apache.org/viewvc/incubator/cayenne/sandbox/asm-enhancer/src/main/java/org/apache/cayenne/enhancer/PersistentSetterVisitor.java?view=diff&rev=454601&r1=454600&r2=454601
==============================================================================
---
incubator/cayenne/sandbox/asm-enhancer/src/main/java/org/apache/cayenne/enhancer/PersistentSetterVisitor.java
(original)
+++
incubator/cayenne/sandbox/asm-enhancer/src/main/java/org/apache/cayenne/enhancer/PersistentSetterVisitor.java
Mon Oct 9 20:59:01 2006
@@ -18,17 +18,22 @@
****************************************************************/
package org.apache.cayenne.enhancer;
+import org.apache.cayenne.ObjectContext;
+import org.objectweb.asm.Label;
import org.objectweb.asm.MethodAdapter;
import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
class PersistentSetterVisitor extends MethodAdapter {
- private String className;
+ private ClassVisitorHelper helper;
private String propertyName;
- PersistentSetterVisitor(MethodVisitor mv, String className, String
propertyName) {
+ PersistentSetterVisitor(MethodVisitor mv, ClassVisitorHelper helper,
+ String propertyName) {
super(mv);
- this.className = className;
+ this.helper = helper;
this.propertyName = propertyName;
}
@@ -36,20 +41,39 @@
public void visitCode() {
super.visitCode();
- // mv.visitVarInsn(Opcodes.ALOAD, 0);
- // mv.visitFieldInsn(Opcodes.GETFIELD, className,
- // PojoAdapterFactory.PERSISTENCE_DELEGATE_FIELD,
- // "Lorg/apache/cayenne/jpa/enhancer/PersistenceDelegate;");
- // Label l1 = new Label();
- // mv.visitJumpInsn(Opcodes.IFNULL, l1);
- // mv.visitVarInsn(Opcodes.ALOAD, 0);
- // mv.visitFieldInsn(Opcodes.GETFIELD, className,
- // PojoAdapterFactory.PERSISTENCE_DELEGATE_FIELD,
- // "Lorg/apache/cayenne/jpa/enhancer/PersistenceDelegate;");
- // mv.visitLdcInsn(propertyName);
- // mv.visitMethodInsn(Opcodes.INVOKEINTERFACE,
- // "org/apache/cayenne/jpa/enhancer/PersistenceDelegate",
- // "prepareForUpdate", "(Ljava/lang/String;)V");
- // mv.visitLabel(l1);
+ String field = helper.getPropertyField("objectContext");
+ Type objectContextType = Type.getType(ObjectContext.class);
+
+ mv.visitVarInsn(Opcodes.ALOAD, 0);
+ mv.visitFieldInsn(
+ Opcodes.GETFIELD,
+ helper.getCurrentClass().getInternalName(),
+ field,
+ objectContextType.getDescriptor());
+ Label l1 = new Label();
+ mv.visitJumpInsn(Opcodes.IFNULL, l1);
+ mv.visitVarInsn(Opcodes.ALOAD, 0);
+ mv.visitFieldInsn(
+ Opcodes.GETFIELD,
+ helper.getCurrentClass().getInternalName(),
+ field,
+ objectContextType.getDescriptor());
+ mv.visitVarInsn(Opcodes.ALOAD, 0);
+ mv.visitLdcInsn("attribute1");
+ mv.visitVarInsn(Opcodes.ALOAD, 0);
+ mv.visitFieldInsn(
+ Opcodes.GETFIELD,
+ helper.getCurrentClass().getInternalName(),
+ propertyName,
+ "Ljava/lang/String;");
+ mv.visitVarInsn(Opcodes.ALOAD, 1);
+ mv
+ .visitMethodInsn(
+ Opcodes.INVOKEINTERFACE,
+ objectContextType.getInternalName(),
+ "propertyChanged",
+
"(Lorg/apache/cayenne/Persistent;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V");
+ mv.visitLabel(l1);
+
}
}
Modified:
incubator/cayenne/sandbox/asm-enhancer/src/test/java/org/apache/cayenne/enhancer/CayenneEnhancerTest.java
URL:
http://svn.apache.org/viewvc/incubator/cayenne/sandbox/asm-enhancer/src/test/java/org/apache/cayenne/enhancer/CayenneEnhancerTest.java?view=diff&rev=454601&r1=454600&r2=454601
==============================================================================
---
incubator/cayenne/sandbox/asm-enhancer/src/test/java/org/apache/cayenne/enhancer/CayenneEnhancerTest.java
(original)
+++
incubator/cayenne/sandbox/asm-enhancer/src/test/java/org/apache/cayenne/enhancer/CayenneEnhancerTest.java
Mon Oct 9 20:59:01 2006
@@ -117,4 +117,100 @@
Object state = getPersistenceState.invoke(o, (Object[]) null);
assertEquals(PersistenceState.DELETED, state);
}
+
+ public void testGetterIntercepted() throws Exception {
+
+ Class e1Class = Class.forName(C1, true, loader);
+ assertNotNull(e1Class);
+ assertEquals(C1, e1Class.getName());
+
+ Object o = e1Class.newInstance();
+
+ // attempt calling on detached object - must not fail
+ Method getAttribute1 = e1Class.getDeclaredMethod("getAttribute1",
(Class[]) null);
+ assertEquals(null, getAttribute1.invoke(o, (Object[]) null));
+
+ // now call on attached object
+
+ final Object[] prepared = new Object[2];
+ ObjectContext context = new MockObjectContext() {
+
+ @Override
+ public void prepareForAccess(Persistent object, String property) {
+ prepared[0] = object;
+ prepared[1] = property;
+ }
+ };
+
+ Method setObjectContext = e1Class.getDeclaredMethod(
+ "setObjectContext",
+ new Class[] {
+ ObjectContext.class
+ });
+
+ setObjectContext.invoke(o, new Object[] {
+ context
+ });
+
+ assertEquals(null, getAttribute1.invoke(o, (Object[]) null));
+ assertSame(o, prepared[0]);
+ assertEquals("attribute1", prepared[1]);
+ }
+
+ public void testSetterIntercepted() throws Exception {
+
+ Class e1Class = Class.forName(C1, true, loader);
+ assertNotNull(e1Class);
+ assertEquals(C1, e1Class.getName());
+
+ Object o = e1Class.newInstance();
+
+ // attempt calling on detached object - must not fail
+ Method getAttribute1 = e1Class.getDeclaredMethod("getAttribute1",
(Class[]) null);
+ Method setAttribute1 = e1Class.getDeclaredMethod("setAttribute1", new
Class[] {
+ String.class
+ });
+
+ assertEquals(null, getAttribute1.invoke(o, (Object[]) null));
+ setAttribute1.invoke(o, new Object[] {
+ "x"
+ });
+ assertEquals("x", getAttribute1.invoke(o, (Object[]) null));
+
+ // now call on attached object
+ final Object[] change = new Object[4];
+ ObjectContext context = new MockObjectContext() {
+
+ @Override
+ public void propertyChanged(
+ Persistent object,
+ String property,
+ Object oldValue,
+ Object newValue) {
+ change[0] = object;
+ change[1] = property;
+ change[2] = oldValue;
+ change[3] = newValue;
+ }
+ };
+
+ Method setObjectContext = e1Class.getDeclaredMethod(
+ "setObjectContext",
+ new Class[] {
+ ObjectContext.class
+ });
+
+ setObjectContext.invoke(o, new Object[] {
+ context
+ });
+
+ setAttribute1.invoke(o, new Object[] {
+ "y"
+ });
+ assertEquals("y", getAttribute1.invoke(o, (Object[]) null));
+ assertSame(o, change[0]);
+ assertEquals("attribute1", change[1]);
+ assertEquals("x", change[2]);
+ assertEquals("y", change[3]);
+ }
}
Modified:
incubator/cayenne/sandbox/asm-enhancer/src/test/java/org/apache/cayenne/enhancer/EnhancingClassLoader.java
URL:
http://svn.apache.org/viewvc/incubator/cayenne/sandbox/asm-enhancer/src/test/java/org/apache/cayenne/enhancer/EnhancingClassLoader.java?view=diff&rev=454601&r1=454600&r2=454601
==============================================================================
---
incubator/cayenne/sandbox/asm-enhancer/src/test/java/org/apache/cayenne/enhancer/EnhancingClassLoader.java
(original)
+++
incubator/cayenne/sandbox/asm-enhancer/src/test/java/org/apache/cayenne/enhancer/EnhancingClassLoader.java
Mon Oct 9 20:59:01 2006
@@ -26,107 +26,111 @@
import java.lang.instrument.IllegalClassFormatException;
import java.security.SecureClassLoader;
-public class EnhancingClassLoader extends SecureClassLoader {
+class EnhancingClassLoader extends SecureClassLoader {
- protected ClassFileTransformer transformer;
+ protected ClassFileTransformer transformer;
- public EnhancingClassLoader(ClassFileTransformer transformer) {
- super(Thread.currentThread().getContextClassLoader());
- this.transformer = transformer;
- }
-
- /**
- * Returns true if the class does not need to be enhanced.
- */
- protected boolean skipClassEnhancement(String className) {
- return transformer == null;
- }
-
- @Override
- protected synchronized Class<?> loadClass(String name, boolean resolve)
- throws ClassNotFoundException {
-
- if (skipClassEnhancement(name)) {
- return super.loadClass(name, resolve);
- }
-
- Class c = findLoadedClass(name);
-
- if (c == null) {
- c = findClass(name);
- }
-
- if (resolve) {
- resolveClass(c);
- }
-
- return c;
- }
-
- /**
- * If a class name is one of the managed classes, loads it
- */
- @Override
- protected Class<?> findClass(String name) throws ClassNotFoundException
{
- if (skipClassEnhancement(name)) {
- return Class.forName(name, true, getParent());
- } else {
- return findEnhancedClass(name);
- }
- }
-
- /**
- * Loads class bytes, and passes them through the registered
- * ClassTransformers.
- */
- protected Class<?> findEnhancedClass(String name)
- throws ClassNotFoundException {
- String path = name.replace('.', '/') + ".class";
-
- InputStream in = getResourceAsStream(path);
- if (in == null) {
- return Class.forName(name, true, getParent());
- }
-
- try {
-
- ByteArrayOutputStream out = new
ByteArrayOutputStream(1024);
- byte[] buffer = new byte[1024];
- int read;
-
- while ((read = in.read(buffer, 0, 1024)) > 0) {
- out.write(buffer, 0, read);
- }
-
- out.close();
- byte[] classBytes = out.toByteArray();
-
- byte[] bytes;
- try {
- bytes = transformer.transform(getParent(),
name, null, null,
- classBytes);
- } catch (IllegalClassFormatException e) {
- throw new ClassNotFoundException("Could not
transform class '"
- + name + "' due to invalid
format", e);
- }
-
- if (bytes != null) {
- classBytes = bytes;
- } else {
- // if transformer didn't transform ... this is
suboptimal as
- // we've already read the bytes from
classfile...
- return Class.forName(name, true, getParent());
- }
-
- return defineClass(name, classBytes, 0,
classBytes.length);
- } catch (IOException e) {
- throw new ClassNotFoundException(name, e);
- } finally {
- try {
- in.close();
- } catch (IOException e) {
- // ignore close exceptions...
- }
- }
- }
+ public EnhancingClassLoader(ClassFileTransformer transformer) {
+ super(Thread.currentThread().getContextClassLoader());
+ this.transformer = transformer;
+ }
+
+ /**
+ * Returns true if the class does not need to be enhanced.
+ */
+ protected boolean skipClassEnhancement(String className) {
+ return transformer == null;
+ }
+
+ @Override
+ protected synchronized Class<?> loadClass(String name, boolean resolve)
+ throws ClassNotFoundException {
+
+ if (skipClassEnhancement(name)) {
+ return super.loadClass(name, resolve);
+ }
+
+ Class c = findLoadedClass(name);
+
+ if (c == null) {
+ c = findClass(name);
+ }
+
+ if (resolve) {
+ resolveClass(c);
+ }
+
+ return c;
+ }
+
+ /**
+ * If a class name is one of the managed classes, loads it
+ */
+ @Override
+ protected Class<?> findClass(String name) throws ClassNotFoundException {
+ if (skipClassEnhancement(name)) {
+ return Class.forName(name, true, getParent());
+ }
+ else {
+ return findEnhancedClass(name);
+ }
+ }
+
+ /**
+ * Loads class bytes, and passes them through the registered
ClassTransformers.
+ */
+ protected Class<?> findEnhancedClass(String name) throws
ClassNotFoundException {
+ String path = name.replace('.', '/') + ".class";
+
+ InputStream in = getResourceAsStream(path);
+ if (in == null) {
+ return Class.forName(name, true, getParent());
+ }
+
+ try {
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
+ byte[] buffer = new byte[1024];
+ int read;
+
+ while ((read = in.read(buffer, 0, 1024)) > 0) {
+ out.write(buffer, 0, read);
+ }
+
+ out.close();
+ byte[] classBytes = out.toByteArray();
+
+ byte[] bytes;
+ try {
+ bytes = transformer.transform(getParent(), name, null, null,
classBytes);
+ }
+ catch (IllegalClassFormatException e) {
+ throw new ClassNotFoundException("Could not transform class '"
+ + name
+ + "' due to invalid format", e);
+ }
+
+ if (bytes != null) {
+ classBytes = bytes;
+ }
+ else {
+ // if transformer didn't transform ... this is suboptimal as
+ // we've already read the bytes from classfile...
+ return Class.forName(name, true, getParent());
+ }
+
+ return defineClass(name, classBytes, 0, classBytes.length);
+ }
+ catch (IOException e) {
+ throw new ClassNotFoundException(name, e);
+ }
+ finally {
+ try {
+ in.close();
+ }
+ catch (IOException e) {
+ // ignore close exceptions...
+ }
+ }
+ }
}
Modified:
incubator/cayenne/sandbox/asm-enhancer/src/test/java/org/apache/cayenne/enhancer/MockEnhancedPojo.java
URL:
http://svn.apache.org/viewvc/incubator/cayenne/sandbox/asm-enhancer/src/test/java/org/apache/cayenne/enhancer/MockEnhancedPojo.java?view=diff&rev=454601&r1=454600&r2=454601
==============================================================================
---
incubator/cayenne/sandbox/asm-enhancer/src/test/java/org/apache/cayenne/enhancer/MockEnhancedPojo.java
(original)
+++
incubator/cayenne/sandbox/asm-enhancer/src/test/java/org/apache/cayenne/enhancer/MockEnhancedPojo.java
Mon Oct 9 20:59:01 2006
@@ -25,7 +25,8 @@
/**
* This class in combination with the ASM Eclipse plugin is used as a
reference for
- * building parts of the ASM enhancer.
+ * building parts of the ASM enhancer. It demonstrates how a pojo should look
like after
+ * the enhancement.
*
* @author Andrus Adamchik
*/
Modified:
incubator/cayenne/sandbox/asm-enhancer/src/test/java/org/apache/cayenne/enhancer/MockObjectContext.java
URL:
http://svn.apache.org/viewvc/incubator/cayenne/sandbox/asm-enhancer/src/test/java/org/apache/cayenne/enhancer/MockObjectContext.java?view=diff&rev=454601&r1=454600&r2=454601
==============================================================================
---
incubator/cayenne/sandbox/asm-enhancer/src/test/java/org/apache/cayenne/enhancer/MockObjectContext.java
(original)
+++
incubator/cayenne/sandbox/asm-enhancer/src/test/java/org/apache/cayenne/enhancer/MockObjectContext.java
Mon Oct 9 20:59:01 2006
@@ -32,8 +32,6 @@
import org.apache.cayenne.query.Query;
public class MockObjectContext implements ObjectContext {
-
- protected boolean preparedForAccess;
public void prepareForAccess(Persistent object, String property) {
}