[jboss-cvs] JBossAS SVN: r59240 - in projects/aop/branches/arrays/aop/src: main/org/jboss/aop/array main/org/jboss/aop/instrument resources/test/array test/org/jboss/test/aop/array
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Thu Dec 28 16:18:19 EST 2006
Author: kabir.khan at jboss.com
Date: 2006-12-28 16:18:10 -0500 (Thu, 28 Dec 2006)
New Revision: 59240
Modified:
projects/aop/branches/arrays/aop/src/main/org/jboss/aop/array/ArrayAdvisor.java
projects/aop/branches/arrays/aop/src/main/org/jboss/aop/array/ArrayElementInvocation.java
projects/aop/branches/arrays/aop/src/main/org/jboss/aop/array/ArrayRegistry.java
projects/aop/branches/arrays/aop/src/main/org/jboss/aop/array/ArrayRegistryEntry.java
projects/aop/branches/arrays/aop/src/main/org/jboss/aop/array/ElementArrayRegistryEntry.java
projects/aop/branches/arrays/aop/src/main/org/jboss/aop/array/FieldArrayRegistryEntry.java
projects/aop/branches/arrays/aop/src/main/org/jboss/aop/instrument/FieldAccessTransformer.java
projects/aop/branches/arrays/aop/src/main/org/jboss/aop/instrument/GeneratedAdvisorFieldAccessTransformer.java
projects/aop/branches/arrays/aop/src/resources/test/array/jboss-aop.xml
projects/aop/branches/arrays/aop/src/test/org/jboss/test/aop/array/AOPArrayTestCase.java
projects/aop/branches/arrays/aop/src/test/org/jboss/test/aop/array/ClassWithArrayFields.java
Log:
Avoid duplicate interception if an array element is set to the same as its existing value
Add method to ArrayRegistry to get hold of references to an advised array
Modified: projects/aop/branches/arrays/aop/src/main/org/jboss/aop/array/ArrayAdvisor.java
===================================================================
--- projects/aop/branches/arrays/aop/src/main/org/jboss/aop/array/ArrayAdvisor.java 2006-12-27 18:02:24 UTC (rev 59239)
+++ projects/aop/branches/arrays/aop/src/main/org/jboss/aop/array/ArrayAdvisor.java 2006-12-28 21:18:10 UTC (rev 59240)
@@ -57,25 +57,27 @@
{
//The old value might be an array, remove references to that
Object oldValue = ((Object[])array)[index];
- registry.removeElementReference(array, index, oldValue);
-
- //The new value might be an array
- if (value.getClass().isArray())
+ boolean ignoreUpdate = (oldValue == value);
+ if (!ignoreUpdate)
{
- registry.addElementReference(array, index, value);
+ registry.removeElementReference(array, index, oldValue);
+
+ //The new value might be an array
+ if (value != null && value.getClass().isArray())
+ {
+ registry.addElementReference(array, index, value);
+ }
+ ObjectArrayElementWriteInvocation invocation = new ObjectArrayElementWriteInvocation(interceptors, (Object[])array, index, value);
+ invocation.invokeNext();
+ return;
}
- ObjectArrayElementWriteInvocation invocation = new ObjectArrayElementWriteInvocation(interceptors, (Object[])array, index, value);
- invocation.invokeNext();
}
- else
- {
- ((Object[])array)[index] = value;
- }
+ ((Object[])array)[index] = value;
}
public static void arrayWriteInt(Object array, int index, int value) throws Throwable
{
- if (ArrayRegistry.getInstance().isRegistered(array))
+ if (ArrayRegistry.getInstance().isRegistered(array) && ((int[])array)[index] != value)
{
IntArrayElementWriteInvocation invocation = new IntArrayElementWriteInvocation(interceptors, ((int[])array), index, value);
invocation.invokeNext();
@@ -92,23 +94,23 @@
{
if (array instanceof boolean[])
{
- BooleanArrayElementWriteInvocation invocation = new BooleanArrayElementWriteInvocation(interceptors, ((boolean[])array), index, ByteBooleanConverter.toBoolean(value));
- invocation.invokeNext();
- }
- else
- {
- ByteArrayElementWriteInvocation invocation = new ByteArrayElementWriteInvocation(interceptors, ((byte[])array), index, value);
- invocation.invokeNext();
- }
- }
- else
- {
- if (array instanceof boolean[])
- {
+ if (((boolean[])array)[index] != ByteBooleanConverter.toBoolean(value))
+
+ {
+ BooleanArrayElementWriteInvocation invocation = new BooleanArrayElementWriteInvocation(interceptors, ((boolean[])array), index, ByteBooleanConverter.toBoolean(value));
+ invocation.invokeNext();
+ return;
+ }
((boolean[])array)[index] = ByteBooleanConverter.toBoolean(value);
}
- else
+ else
{
+ if (((byte[])array)[index] != value)
+ {
+ ByteArrayElementWriteInvocation invocation = new ByteArrayElementWriteInvocation(interceptors, ((byte[])array), index, value);
+ invocation.invokeNext();
+ return;
+ }
((byte[])array)[index] = value;
}
}
@@ -116,7 +118,7 @@
public static void arrayWriteChar(Object array, int index, char value) throws Throwable
{
- if (ArrayRegistry.getInstance().isRegistered(array))
+ if (ArrayRegistry.getInstance().isRegistered(array) && ((char[])array)[index] != value)
{
CharArrayElementWriteInvocation invocation = new CharArrayElementWriteInvocation(interceptors, ((char[])array), index, value);
invocation.invokeNext();
@@ -129,7 +131,7 @@
public static void arrayWriteDouble(Object array, int index, double value) throws Throwable
{
- if (ArrayRegistry.getInstance().isRegistered(array))
+ if (ArrayRegistry.getInstance().isRegistered(array) && ((double[])array)[index] != value)
{
DoubleArrayElementWriteInvocation invocation = new DoubleArrayElementWriteInvocation(interceptors, ((double[])array), index, value);
invocation.invokeNext();
@@ -142,7 +144,7 @@
public static void arrayWriteShort(Object array, int index, short value) throws Throwable
{
- if (ArrayRegistry.getInstance().isRegistered(array))
+ if (ArrayRegistry.getInstance().isRegistered(array) && ((short[])array)[index] != value)
{
ShortArrayElementWriteInvocation invocation = new ShortArrayElementWriteInvocation(interceptors, ((short[])array), index, value);
invocation.invokeNext();
@@ -155,7 +157,7 @@
public static void arrayWriteFloat(Object array, int index, float value) throws Throwable
{
- if (ArrayRegistry.getInstance().isRegistered(array))
+ if (ArrayRegistry.getInstance().isRegistered(array) && ((float[])array)[index] != value)
{
FloatArrayElementWriteInvocation invocation = new FloatArrayElementWriteInvocation(interceptors, ((float[])array), index, value);
invocation.invokeNext();
@@ -168,7 +170,7 @@
public static void arrayWriteLong(Object array, int index, long value) throws Throwable
{
- if (ArrayRegistry.getInstance().isRegistered(array))
+ if (ArrayRegistry.getInstance().isRegistered(array) && ((long[])array)[index] != value)
{
LongArrayElementWriteInvocation invocation = new LongArrayElementWriteInvocation(interceptors, ((long[])array), index, value);
invocation.invokeNext();
Modified: projects/aop/branches/arrays/aop/src/main/org/jboss/aop/array/ArrayElementInvocation.java
===================================================================
--- projects/aop/branches/arrays/aop/src/main/org/jboss/aop/array/ArrayElementInvocation.java 2006-12-27 18:02:24 UTC (rev 59239)
+++ projects/aop/branches/arrays/aop/src/main/org/jboss/aop/array/ArrayElementInvocation.java 2006-12-28 21:18:10 UTC (rev 59240)
@@ -164,4 +164,10 @@
{
throw new NotImplementedException();
}
+
+ public void getReferences()
+ {
+ ArrayRegistry registry = ArrayRegistry.getInstance();
+ registry.getArrayOwners(targetObject);
+ }
}
Modified: projects/aop/branches/arrays/aop/src/main/org/jboss/aop/array/ArrayRegistry.java
===================================================================
--- projects/aop/branches/arrays/aop/src/main/org/jboss/aop/array/ArrayRegistry.java 2006-12-27 18:02:24 UTC (rev 59239)
+++ projects/aop/branches/arrays/aop/src/main/org/jboss/aop/array/ArrayRegistry.java 2006-12-28 21:18:10 UTC (rev 59240)
@@ -21,8 +21,9 @@
*/
package org.jboss.aop.array;
-import java.util.HashSet;
-import java.util.Set;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
import java.util.WeakHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
@@ -35,9 +36,12 @@
*/
public class ArrayRegistry
{
+ private final static ArrayRegistryEntryFactory ELEMENT_ARRAY_REGISTRY_ENTRY_FACTORY = new ElementArrayRegistryEntryFactory();
+ private final static ArrayRegistryEntryFactory FIELD_ARRAY_REGISTRY_ENTRY_FACTORY = new FieldArrayRegistryEntryFactory();
+ private ArrayReferenceBuilder referenceBuilder = new ArrayReferenceBuilder();
private static ArrayRegistry singleton = new ArrayRegistry();
private ReadWriteLock lock = new ReentrantReadWriteLock();
- private WeakHashMap<Object, WeakHashMap<Object, ArrayRegistryEntry>> cache = new WeakHashMap<Object, WeakHashMap<Object, ArrayRegistryEntry>>();
+ private WeakHashMap<Object, WeakHashMap<Object, HashMap<Object, ArrayRegistryEntry>>> cache = new WeakHashMap<Object, WeakHashMap<Object, HashMap<Object, ArrayRegistryEntry>>>();
public static ArrayRegistry getInstance()
{
@@ -55,24 +59,47 @@
{
return;
}
+ addReference(owner, fieldName, array, FIELD_ARRAY_REGISTRY_ENTRY_FACTORY);
+ }
+
+ public void addElementReference(Object owner, int index, Object array)
+ {
+ if (array == null)
+ {
+ return;
+ }
+ addReference(owner, new Integer(index), array, ELEMENT_ARRAY_REGISTRY_ENTRY_FACTORY);
+ }
+
+ public void addReference(Object owner, Object qualifier, Object array, ArrayRegistryEntryFactory factory)
+ {
+ if (array == null)
+ {
+ return;
+ }
Lock writeLock = lock.writeLock();
writeLock.lock();
try
{
- WeakHashMap<Object, ArrayRegistryEntry> arrayReferences = cache.get(array);
+ WeakHashMap<Object, HashMap<Object, ArrayRegistryEntry>> arrayReferences = cache.get(array);
if (arrayReferences == null)
{
- arrayReferences = new WeakHashMap<Object, ArrayRegistryEntry>();
+ arrayReferences = new WeakHashMap<Object, HashMap<Object, ArrayRegistryEntry>>();
cache.put(array, arrayReferences);
}
- ArrayRegistryEntry regEntry = arrayReferences.get(owner);
- if (regEntry != null)
+
+ HashMap<Object, ArrayRegistryEntry> ownerReferences = arrayReferences.get(owner);
+ if (ownerReferences == null)
{
- ((FieldArrayRegistryEntry)regEntry).addFieldName(fieldName);
+ ownerReferences = new HashMap<Object, ArrayRegistryEntry>();
+ arrayReferences.put(owner, ownerReferences);
}
- else
+
+ ArrayRegistryEntry regEntry = ownerReferences.get(qualifier);
+ if (regEntry == null || regEntry.getArray() != array)
{
- arrayReferences.put(owner, new FieldArrayRegistryEntry(owner, fieldName, array));
+ ArrayRegistryEntry entry = factory.createArrayRegistryEntry(owner, qualifier, factory);
+ ownerReferences.put(qualifier, entry);
}
addNestedArrays(array);
}
@@ -82,72 +109,27 @@
}
}
- public void removeFieldReference(Object owner, String field, Object array)
+ public void removeFieldReference(Object owner, String fieldName, Object array)
{
if (array == null)
{
return;
}
- Lock writeLock = lock.writeLock();
- writeLock.lock();
- try
- {
- WeakHashMap<Object, ArrayRegistryEntry> arrayReferences = cache.get(array);
- if (arrayReferences != null)
- {
- ArrayRegistryEntry regEntry = arrayReferences.get(owner);
- if (owner != null)
- {
- ((FieldArrayRegistryEntry)regEntry).removeFieldName(field);
- if (!regEntry.ownerHasReferences())
- {
- arrayReferences.remove(owner);
- }
- }
- }
- removeNestedArrays(owner, array);
- }
- finally
- {
- writeLock.unlock();
- }
+ removeReference(owner, fieldName, array);
}
- public void addElementReference(Object owner, int index, Object array)
+ public void removeElementReference(Object owner, int index, Object array)
{
if (array == null)
{
return;
}
- Lock writeLock = lock.writeLock();
- writeLock.lock();
- try
- {
- WeakHashMap<Object, ArrayRegistryEntry> arrayReferences = cache.get(array);
- if (arrayReferences == null)
- {
- arrayReferences = new WeakHashMap<Object, ArrayRegistryEntry>();
- cache.put(array, arrayReferences);
- }
- ArrayRegistryEntry regEntry = arrayReferences.get(owner);
- if (regEntry != null)
- {
- ((ElementArrayRegistryEntry)regEntry).addIndex(index);
- }
- else
- {
- arrayReferences.put(owner, new ElementArrayRegistryEntry(owner, index, array));
- }
- addNestedArrays(array);
- }
- finally
- {
- writeLock.unlock();
- }
+
+ removeReference(owner, new Integer(index), array);
}
-
- public void removeElementReference(Object owner, int index, Object array)
+
+ public void removeReference(Object owner, Object qualifier, Object array)
{
if (array == null)
{
@@ -158,20 +140,31 @@
writeLock.lock();
try
{
- WeakHashMap<Object, ArrayRegistryEntry> arrayReferences = cache.get(array);
+ WeakHashMap<Object, HashMap<Object,ArrayRegistryEntry>> arrayReferences = cache.get(array);
if (arrayReferences != null)
{
- ArrayRegistryEntry regEntry = arrayReferences.get(owner);
- if (owner != null)
+ HashMap<Object,ArrayRegistryEntry> ownerReferences = arrayReferences.get(owner);
+ if (ownerReferences != null)
{
- ((ElementArrayRegistryEntry)regEntry).removeIndex(index);
- if (!regEntry.ownerHasReferences())
+ ArrayRegistryEntry regEntry = ownerReferences.remove(qualifier);
+ if (regEntry != null)
{
- arrayReferences.remove(owner);
+ if (ownerReferences.size() == 0)
+ {
+ arrayReferences.remove(owner);
+
+ if (arrayReferences.size() == 0)
+ {
+ cache.remove(array);
+ }
+ }
+ ///Should this be here or below?
+ removeNestedArrays(array);
}
+
}
}
- removeNestedArrays(owner, array);
+// removeNestedArrays(owner, array);
}
finally
{
@@ -186,8 +179,8 @@
try
{
- WeakHashMap<Object, ArrayRegistryEntry> arrayReferences = cache.get(array);
- if (arrayReferences == null || arrayReferences.size() == 0)
+ WeakHashMap<Object, HashMap<Object, ArrayRegistryEntry>> arrayReferences = cache.get(array);
+ if (arrayReferences == null)
{
return false;
}
@@ -198,36 +191,31 @@
readLock.unlock();
}
}
-
- public Set getOwners(Object owner, Object array)
+
+ public List<ArrayReference> getArrayOwners(Object array)
{
+ System.out.println("----> getArrayOwners " + array);
Lock readLock = lock.readLock();
readLock.lock();
try
{
- WeakHashMap<Object, ArrayRegistryEntry> arrayReferences = cache.get(array);
- if (arrayReferences != null)
- {
- HashSet set = new HashSet();
- set.addAll(arrayReferences.keySet());
- return set;
- }
- return null;
+ return referenceBuilder.getArrayReferences(array);
}
finally
{
readLock.unlock();
}
}
-
+
private void addNestedArrays(Object array)
{
if (array == null)
{
return;
}
- if (isArray(array))
+ ArrayType type = isArray(array);
+ if (type == ArrayType.MULTIDIM_ARRAY)
{
for (int i = 0 ; i < ((Object[])array).length ; i++)
{
@@ -235,32 +223,165 @@
addNestedArrays(((Object[])array)[i]);
}
}
+ else if (type == ArrayType.OBJECT_ARRAY)
+ {
+ for (int i = 0 ; i < ((Object[])array).length ; i++)
+ {
+ Object val = ((Object[])array)[i];
+ if (val != null && val.getClass().isArray())
+ {
+ addElementReference(array, i, ((Object[])array)[i]);
+ addNestedArrays(((Object[])array)[i]);
+ }
+ }
+ }
}
- private void removeNestedArrays(Object owner, Object array)
+ private void removeNestedArrays(Object array)
{
if (array == null)
{
return;
}
- if (isArray(array))
+ ArrayType type = isArray(array);
+ if (type == ArrayType.MULTIDIM_ARRAY)
{
for (int i = 0 ; i < ((Object[])array).length ; i++)
{
removeElementReference(array, i, ((Object[])array)[i]);
- removeNestedArrays(array, ((Object[])array)[i]);
+ removeNestedArrays(((Object[])array)[i]);
}
}
+ else if (type == ArrayType.OBJECT_ARRAY)
+ {
+ for (int i = 0 ; i < ((Object[])array).length ; i++)
+ {
+ Object val = ((Object[])array)[i];
+ if (val != null && val.getClass().isArray())
+ {
+ removeElementReference(array, i, ((Object[])array)[i]);
+ removeNestedArrays(((Object[])array)[i]);
+ }
+ }
+ }
}
- private boolean isArray(Object arrayCandidate)
+ private ArrayType isArray(Object arrayCandidate)
{
Class candidateClass = arrayCandidate.getClass();
if (candidateClass.isArray())
{
Class componentType = candidateClass.getComponentType();
- return componentType.isArray();
+ if (componentType.isArray())
+ {
+ return ArrayType.MULTIDIM_ARRAY;
+ }
+ if (componentType == Object.class)
+ {
+ return ArrayType.OBJECT_ARRAY;
+ }
}
- return false;
+ return ArrayType.NOT_ARRAY;
}
+
+ private interface ArrayRegistryEntryFactory
+ {
+ ArrayRegistryEntry createArrayRegistryEntry(Object owner, Object qualifier, Object array);
+ }
+
+ private static class FieldArrayRegistryEntryFactory implements ArrayRegistryEntryFactory
+ {
+ public ArrayRegistryEntry createArrayRegistryEntry(Object owner, Object qualifier, Object array)
+ {
+ return new FieldArrayRegistryEntry(owner, (String)qualifier, array);
+ }
+ }
+
+ private static class ElementArrayRegistryEntryFactory implements ArrayRegistryEntryFactory
+ {
+ public ArrayRegistryEntry createArrayRegistryEntry(Object owner, Object qualifier, Object array)
+ {
+ return new ElementArrayRegistryEntry(owner, (Integer)qualifier, array);
+ }
+ }
+
+ private class ArrayReferenceBuilder
+ {
+ private List<ArrayReference> getArrayReferences(Object array)
+ {
+ List<ArrayReference> references = null;
+ WeakHashMap<Object, HashMap<Object, ArrayRegistryEntry>> arrayReferences = cache.get(array);
+ if (arrayReferences != null && arrayReferences.size() > 0)
+ {
+ for (Object owner : arrayReferences.keySet())
+ {
+ HashMap<Object, ArrayRegistryEntry> ownerReferences = arrayReferences.get(owner);
+ for (Object qualifier : ownerReferences.keySet())
+ {
+ ArrayRegistryEntry regEntry = ownerReferences.get(qualifier);
+
+ if (regEntry.isOwnerRoot())
+ {
+ ArrayReference reference = getRootReference((FieldArrayRegistryEntry)regEntry);
+ if (reference != null)
+ {
+ if (references == null)
+ {
+ references = new ArrayList<ArrayReference>();
+ }
+ references.add(reference);
+ }
+ }
+ else
+ {
+ List<ArrayReference> parentReferences = getElementReferences((ElementArrayRegistryEntry)regEntry);
+ if (parentReferences != null)
+ {
+ if (references == null)
+ {
+ references = new ArrayList<ArrayReference>();
+ }
+ references.addAll(parentReferences);
+ }
+ }
+ }
+ }
+ }
+ return references;
+ }
+
+ private ArrayReference getRootReference(FieldArrayRegistryEntry regEntry)
+ {
+ Object root = regEntry.getOwner();
+ if (root != null)
+ {
+ String fieldName = regEntry.getFieldName();
+ return new ArrayReferenceImpl(root, fieldName);
+ }
+ return null;
+ }
+
+ private List<ArrayReference> getElementReferences(ElementArrayRegistryEntry regEntry)
+ {
+ Object ownerArray = regEntry.getOwner();
+ if (ownerArray != null)
+ {
+ List<ArrayReference> references = getArrayReferences(ownerArray);
+ if (references != null && references.size() > 0)
+ {
+ for (ArrayReference reference : references)
+ {
+ ((ArrayReferenceImpl)reference).addNestedArrayIndex(regEntry.getIndex());
+ }
+ }
+ return references;
+ }
+ return null;
+ }
+ }
+
+ private enum ArrayType
+ {
+ NOT_ARRAY,MULTIDIM_ARRAY,OBJECT_ARRAY;
+ }
}
Modified: projects/aop/branches/arrays/aop/src/main/org/jboss/aop/array/ArrayRegistryEntry.java
===================================================================
--- projects/aop/branches/arrays/aop/src/main/org/jboss/aop/array/ArrayRegistryEntry.java 2006-12-27 18:02:24 UTC (rev 59239)
+++ projects/aop/branches/arrays/aop/src/main/org/jboss/aop/array/ArrayRegistryEntry.java 2006-12-28 21:18:10 UTC (rev 59240)
@@ -52,20 +52,26 @@
}
}
- public WeakReference getArray()
+ public Object getArray()
{
- return array;
+ if (array != null)
+ {
+ return array.get();
+ }
+ return null;
}
- public WeakReference getOwner()
+ public Object getOwner()
{
- return owner;
+ if (owner != null)
+ {
+ return owner.get();
+ }
+ return null;
}
public boolean isOwnerRoot()
{
return ownerIsRoot;
}
-
- public abstract boolean ownerHasReferences();
}
Modified: projects/aop/branches/arrays/aop/src/main/org/jboss/aop/array/ElementArrayRegistryEntry.java
===================================================================
--- projects/aop/branches/arrays/aop/src/main/org/jboss/aop/array/ElementArrayRegistryEntry.java 2006-12-27 18:02:24 UTC (rev 59239)
+++ projects/aop/branches/arrays/aop/src/main/org/jboss/aop/array/ElementArrayRegistryEntry.java 2006-12-28 21:18:10 UTC (rev 59240)
@@ -30,27 +30,16 @@
*/
public class ElementArrayRegistryEntry extends ArrayRegistryEntry
{
- HashSet<Integer> indices = new HashSet<Integer>();
+ Integer index;;
- ElementArrayRegistryEntry(Object owner, int index, Object array)
+ ElementArrayRegistryEntry(Object owner, Integer index, Object array)
{
super(owner, false, array);
- this.indices.add(index);
+ this.index = index;
}
-
- public void addIndex(int index)
- {
- indices.add(index);
- }
-
- public void removeIndex(int index)
- {
- indices.remove(index);
- }
- @Override
- public boolean ownerHasReferences()
+ public Integer getIndex()
{
- return indices.size() > 0;
+ return index;
}
}
Modified: projects/aop/branches/arrays/aop/src/main/org/jboss/aop/array/FieldArrayRegistryEntry.java
===================================================================
--- projects/aop/branches/arrays/aop/src/main/org/jboss/aop/array/FieldArrayRegistryEntry.java 2006-12-27 18:02:24 UTC (rev 59239)
+++ projects/aop/branches/arrays/aop/src/main/org/jboss/aop/array/FieldArrayRegistryEntry.java 2006-12-28 21:18:10 UTC (rev 59240)
@@ -30,28 +30,17 @@
*/
public class FieldArrayRegistryEntry extends ArrayRegistryEntry
{
- HashSet fields = new HashSet<String>();
+ String fieldName;
FieldArrayRegistryEntry(Object owner, String fieldName, Object array)
{
// FIXME FieldArrayRegistryEntry constructor
super(owner, true, array);
- this.fields.add(fieldName);
+ this.fieldName = fieldName;
}
- public void addFieldName(String fieldName)
+ public String getFieldName()
{
- fields.add(fieldName);
+ return fieldName;
}
-
- public void removeFieldName(String fieldName)
- {
- fields.remove(fieldName);
- }
-
- @Override
- public boolean ownerHasReferences()
- {
- return fields.size() > 0;
- }
}
\ No newline at end of file
Modified: projects/aop/branches/arrays/aop/src/main/org/jboss/aop/instrument/FieldAccessTransformer.java
===================================================================
--- projects/aop/branches/arrays/aop/src/main/org/jboss/aop/instrument/FieldAccessTransformer.java 2006-12-27 18:02:24 UTC (rev 59239)
+++ projects/aop/branches/arrays/aop/src/main/org/jboss/aop/instrument/FieldAccessTransformer.java 2006-12-28 21:18:10 UTC (rev 59240)
@@ -118,11 +118,10 @@
protected abstract void doBuildFieldWrappers(CtClass clazz, CtField field, int index, boolean shouldReplaceArrayAccess, JoinpointClassification classificationGet, JoinpointClassification classificationSet) throws NotFoundException, CannotCompileException;
- protected String getArrayWriteRegistration(boolean shouldReplaceArrayAccess, CtField field, String oldValue, String newValue) throws NotFoundException
+ protected String getArrayWriteRegistration(boolean shouldReplaceArrayAccess, String target, CtField field, String oldValue, String newValue) throws NotFoundException
{
- if (field.getType().isArray() && shouldReplaceArrayAccess)
+ if (shouldReplaceArrayAccess && (field.getType().isArray() || field.getType().getName().equals("java.lang.Object")))
{
- String target = Modifier.isStatic(field.getModifiers()) ? "java.lang.Class.forName(" + field.getType().getName() + ")" : "this";
return "org.jboss.aop.array.ArrayAdvisor.updateArrayField(" + target + ", \"" + field.getName() + "\", " + oldValue + ", " + newValue + ");";
}
return "";
Modified: projects/aop/branches/arrays/aop/src/main/org/jboss/aop/instrument/GeneratedAdvisorFieldAccessTransformer.java
===================================================================
--- projects/aop/branches/arrays/aop/src/main/org/jboss/aop/instrument/GeneratedAdvisorFieldAccessTransformer.java 2006-12-27 18:02:24 UTC (rev 59239)
+++ projects/aop/branches/arrays/aop/src/main/org/jboss/aop/instrument/GeneratedAdvisorFieldAccessTransformer.java 2006-12-28 21:18:10 UTC (rev 59240)
@@ -307,10 +307,11 @@
String generatorName = FieldJoinPointGenerator.getJoinPointGeneratorFieldName(field.getName(), false);
if (isStatic)
{
- String fieldString = clazz.getName() + "." + field.getName();
+ String targetString = "java.lang.Class.forName(\"" + clazz.getName() + "\")";
+ String fieldString = clazz.getName() + "." + field.getName();
code =
"{" +
- " " + getArrayWriteRegistration(shouldReplaceArrayAccess, field, fieldString, "$2") +
+ " " + getArrayWriteRegistration(shouldReplaceArrayAccess, targetString, field, fieldString, "$2") +
" if (" + infoName + " == null && " + generatorName + " != null)" +
" {" +
" " + generatorName + "." + JoinPointGenerator.GENERATE_JOINPOINT_CLASS + "(this.getClass().getClassLoader());" +
@@ -327,10 +328,11 @@
}
else
{
- String fieldString = "((" + clazz.getName() + ")$1)." + field.getName();
+ String targetString = "((" + clazz.getName() + ")$1)";
+ String fieldString = targetString + "." + field.getName();
code =
"{" +
- " " + getArrayWriteRegistration(shouldReplaceArrayAccess, field, fieldString, "$2") +
+ " " + getArrayWriteRegistration(shouldReplaceArrayAccess, targetString, field, fieldString, "$2") +
" if (" + infoName + " == null && " + generatorName + " != null)" +
" {" +
" " + generatorName + "." + JoinPointGenerator.GENERATE_JOINPOINT_CLASS + "(this.getClass().getClassLoader());" +
Modified: projects/aop/branches/arrays/aop/src/resources/test/array/jboss-aop.xml
===================================================================
--- projects/aop/branches/arrays/aop/src/resources/test/array/jboss-aop.xml 2006-12-27 18:02:24 UTC (rev 59239)
+++ projects/aop/branches/arrays/aop/src/resources/test/array/jboss-aop.xml 2006-12-28 21:18:10 UTC (rev 59240)
@@ -1,7 +1,10 @@
<aop>
<arrayreplacement class="org.jboss.test.aop.array.AOPArrayTestCase"/>
+ <arrayreplacement class="org.jboss.test.aop.array.ArrayReferenceTestCase"/>
<arrayreplacement expr="class(org.jboss.test.aop.array.ClassWithArrayFields) OR class(org.jboss.test.aop.array.ClassWithSeveralReferencesToSameArray)"/>
+ <arrayreplacement expr="class($instanceof{org.jboss.test.aop.array.ClassForReference})"/>
<prepare expr="field(* org.jboss.test.aop.array.ClassWithArrayFields->*)"/>
<prepare expr="field(* org.jboss.test.aop.array.ClassWithSeveralReferencesToSameArray->*)"/>
+ <prepare expr="field(* org.jboss.test.aop.array.ClassForReference->*)"/>
</aop>
Modified: projects/aop/branches/arrays/aop/src/test/org/jboss/test/aop/array/AOPArrayTestCase.java
===================================================================
--- projects/aop/branches/arrays/aop/src/test/org/jboss/test/aop/array/AOPArrayTestCase.java 2006-12-27 18:02:24 UTC (rev 59239)
+++ projects/aop/branches/arrays/aop/src/test/org/jboss/test/aop/array/AOPArrayTestCase.java 2006-12-28 21:18:10 UTC (rev 59240)
@@ -29,6 +29,7 @@
/**
+ * Test that arrays get advised properly
*
* @author <a href="kabir.khan at jboss.com">Kabir Khan</a>
* @version $Revision: 1.1 $
@@ -101,14 +102,14 @@
{
ClassWithArrayFields obj = new ClassWithArrayFields();
TestArrayElementInterceptor.clear();
- obj.booleans[1] = false;
+ obj.booleans[1] = true;
assertEquals(1, TestArrayElementInterceptor.index);
assertNotNull(TestArrayElementInterceptor.value);
- assertEquals(false, ((Boolean)TestArrayElementInterceptor.value).booleanValue());
+ assertEquals(true, ((Boolean)TestArrayElementInterceptor.value).booleanValue());
TestArrayElementInterceptor.clear();
boolean val = obj.booleans[1];
- assertEquals(false, val);
+ assertEquals(true, val);
assertEquals(1, TestArrayElementInterceptor.index);
assertNull(TestArrayElementInterceptor.value);
}
@@ -472,6 +473,305 @@
}
+ public void testObjectArrayWithArrayAsObjectEntry2()
+ {
+ ClassWithArrayFields obj = new ClassWithArrayFields();
+ Object[] original = obj.objects;
+ obj.objects = new Object[] {new int[] {1,2,3}};
+
+ //Add an array as one of the elements in the object array
+ TestArrayElementInterceptor.clear();
+ original[0] = "X";
+ assertEquals(-1, TestArrayElementInterceptor.index);
+ assertNull(TestArrayElementInterceptor.value);
+
+ TestArrayElementInterceptor.clear();
+ Object val = original[0];
+ assertEquals("X", val);
+ assertEquals(-1, TestArrayElementInterceptor.index);
+ assertNull(TestArrayElementInterceptor.value);
+
+ TestArrayElementInterceptor.clear();
+ int[] i = (int[])obj.objects[0];
+ assertEquals(0, TestArrayElementInterceptor.index);
+ assertNull(TestArrayElementInterceptor.value);
+
+ TestArrayElementInterceptor.clear();
+ i[1] = 10;
+ assertEquals(1, TestArrayElementInterceptor.index);
+ assertEquals(10, TestArrayElementInterceptor.value);
+
+ TestArrayElementInterceptor.clear();
+ int ival = i[1];
+ assertEquals(10, ival);
+ assertEquals(1, TestArrayElementInterceptor.index);
+ assertNull(TestArrayElementInterceptor.value);
+ }
+
+ public void testObjectFieldWithArray()
+ {
+ ClassWithArrayFields obj = new ClassWithArrayFields();
+ obj.objectField = new int[] {1,2,3};
+
+ TestArrayElementInterceptor.clear();
+ ((int[])obj.objectField)[1] = 10;
+ assertEquals(1, TestArrayElementInterceptor.index);
+ assertEquals(10, TestArrayElementInterceptor.value);
+
+ TestArrayElementInterceptor.clear();
+ int val = ((int[])obj.objectField)[2];
+ assertEquals(3, val);
+ assertEquals(2, TestArrayElementInterceptor.index);
+ assertNull(TestArrayElementInterceptor.value);
+
+ int[] array = (int[])obj.objectField;
+ TestArrayElementInterceptor.clear();
+ val = array[2];
+ assertEquals(3, val);
+ assertEquals(2, TestArrayElementInterceptor.index);
+ assertNull(TestArrayElementInterceptor.value);
+
+ obj.objectField = null;
+ TestArrayElementInterceptor.clear();
+ val = array[2];
+ assertEquals(3, val);
+ assertEquals(-1, TestArrayElementInterceptor.index);
+ assertNull(TestArrayElementInterceptor.value);
+ }
+
+ public void testObjectFieldWithNestedArrays()
+ {
+ ClassWithArrayFields obj = new ClassWithArrayFields();
+ obj.objectField = new Object[] {new int[] {1, 2}, new Object[] {"X", "Y"}};
+
+ Object[] objArray = (Object[])obj.objectField;
+
+ TestArrayElementInterceptor.clear();
+ int[] intArray = (int[])((Object[])obj.objectField)[0];
+ assertEquals(0, TestArrayElementInterceptor.index);
+
+ TestArrayElementInterceptor.clear();
+ Object[] objArray2 = (Object[])((Object[])obj.objectField)[1];
+ assertEquals(1, TestArrayElementInterceptor.index);
+
+ TestArrayElementInterceptor.clear();
+ intArray[1] = 10;
+ assertEquals(1, TestArrayElementInterceptor.index);
+ assertEquals(10, TestArrayElementInterceptor.value);
+
+ TestArrayElementInterceptor.clear();
+ int val = intArray[1];
+ assertEquals(10, val);
+ assertEquals(1, TestArrayElementInterceptor.index);
+ assertNull(TestArrayElementInterceptor.value);
+
+ TestArrayElementInterceptor.clear();
+ objArray2[1] = "ZZZ";
+ assertEquals(1, TestArrayElementInterceptor.index);
+ assertEquals("ZZZ", TestArrayElementInterceptor.value);
+
+ TestArrayElementInterceptor.clear();
+ Object oval = objArray2[1];
+ assertEquals("ZZZ", oval);
+ assertEquals(1, TestArrayElementInterceptor.index);
+ assertNull(TestArrayElementInterceptor.value);
+
+ TestArrayElementInterceptor.clear();
+ int[] intArray2 = new int[] {11, 22};
+ objArray[0] = intArray2;
+ assertEquals(0, TestArrayElementInterceptor.index);
+ assertEquals(intArray2, TestArrayElementInterceptor.value);
+
+ TestArrayElementInterceptor.clear();
+ intArray2[1] = 10;
+ assertEquals(1, TestArrayElementInterceptor.index);
+ assertEquals(10, TestArrayElementInterceptor.value);
+
+ TestArrayElementInterceptor.clear();
+ val = intArray2[1];
+ assertEquals(10, val);
+ assertEquals(1, TestArrayElementInterceptor.index);
+ assertNull(TestArrayElementInterceptor.value);
+
+ TestArrayElementInterceptor.clear();
+ intArray[1] = 10;
+ assertEquals(-1, TestArrayElementInterceptor.index);
+ assertNull(TestArrayElementInterceptor.value);
+
+ TestArrayElementInterceptor.clear();
+ val = intArray[1];
+ assertEquals(10, val);
+ assertEquals(-1, TestArrayElementInterceptor.index);
+ assertNull(TestArrayElementInterceptor.value);
+
+ TestArrayElementInterceptor.clear();
+ objArray[0] = null;
+ assertEquals(0, TestArrayElementInterceptor.index);
+ assertNull(TestArrayElementInterceptor.value);
+
+ TestArrayElementInterceptor.clear();
+ objArray[1] = null;
+ assertEquals(1, TestArrayElementInterceptor.index);
+ assertNull(TestArrayElementInterceptor.value);
+
+ TestArrayElementInterceptor.clear();
+ intArray2[1] = 10;
+ assertEquals(-1, TestArrayElementInterceptor.index);
+ assertNull(TestArrayElementInterceptor.value);
+
+ TestArrayElementInterceptor.clear();
+ val = intArray2[1];
+ assertEquals(10, val);
+ assertEquals(-1, TestArrayElementInterceptor.index);
+ assertNull(TestArrayElementInterceptor.value);
+
+ TestArrayElementInterceptor.clear();
+ objArray2[1] = "ZZZ";
+ assertEquals(-1, TestArrayElementInterceptor.index);
+ assertNull(TestArrayElementInterceptor.value);
+
+ TestArrayElementInterceptor.clear();
+ oval = objArray2[1];
+ assertEquals("ZZZ", oval);
+ assertEquals(-1, TestArrayElementInterceptor.index);
+ assertNull(TestArrayElementInterceptor.value);
+ }
+
+ public void testIgnoreDoubleUpdate()
+ {
+ ClassWithArrayFields obj = new ClassWithArrayFields();
+
+ String sval = "X";
+ TestArrayElementInterceptor.clear();
+ obj.objects[0] = sval;
+ assertEquals(0, TestArrayElementInterceptor.index);
+ assertEquals(sval, TestArrayElementInterceptor.value);
+ TestArrayElementInterceptor.clear();
+ obj.objects[0] = sval;
+ assertEquals(-1, TestArrayElementInterceptor.index);
+ assertNull(TestArrayElementInterceptor.value);
+
+ byte byteVal = 10;
+ TestArrayElementInterceptor.clear();
+ obj.bytes[0] = byteVal;
+ assertEquals(0, TestArrayElementInterceptor.index);
+ assertEquals(byteVal, TestArrayElementInterceptor.value);
+ TestArrayElementInterceptor.clear();
+ obj.bytes[0] = byteVal;
+ assertEquals(-1, TestArrayElementInterceptor.index);
+ assertNull(TestArrayElementInterceptor.value);
+
+ //Set the value to be different
+ obj.booleans[0] = false;
+ boolean booleanVal = true;
+ TestArrayElementInterceptor.clear();
+ obj.booleans[0] = booleanVal;
+ assertEquals(0, TestArrayElementInterceptor.index);
+ assertEquals(booleanVal, TestArrayElementInterceptor.value);
+ TestArrayElementInterceptor.clear();
+ obj.booleans[0] = booleanVal;
+ assertEquals(-1, TestArrayElementInterceptor.index);
+ assertNull(TestArrayElementInterceptor.value);
+ booleanVal = false;
+ TestArrayElementInterceptor.clear();
+ obj.booleans[0] = booleanVal;
+ assertEquals(0, TestArrayElementInterceptor.index);
+ assertEquals(booleanVal, TestArrayElementInterceptor.value);
+ TestArrayElementInterceptor.clear();
+ obj.booleans[0] = booleanVal;
+ assertEquals(-1, TestArrayElementInterceptor.index);
+ assertNull(TestArrayElementInterceptor.value);
+
+ char charVal = 'h';
+ TestArrayElementInterceptor.clear();
+ obj.chars[0] = charVal;
+ assertEquals(0, TestArrayElementInterceptor.index);
+ assertEquals(charVal, TestArrayElementInterceptor.value);
+ TestArrayElementInterceptor.clear();
+ obj.chars[0] = charVal;
+ assertEquals(-1, TestArrayElementInterceptor.index);
+ assertNull(TestArrayElementInterceptor.value);
+
+ double doubleVal = 101.1d;
+ TestArrayElementInterceptor.clear();
+ obj.doubles[0] = doubleVal;
+ assertEquals(0, TestArrayElementInterceptor.index);
+ assertEquals(doubleVal, TestArrayElementInterceptor.value);
+ TestArrayElementInterceptor.clear();
+ obj.doubles[0] = doubleVal;
+ assertEquals(-1, TestArrayElementInterceptor.index);
+ assertNull(TestArrayElementInterceptor.value);
+
+ float floatVal = 66.6f;
+ TestArrayElementInterceptor.clear();
+ obj.floats[0] = floatVal;
+ assertEquals(0, TestArrayElementInterceptor.index);
+ assertEquals(floatVal, TestArrayElementInterceptor.value);
+ TestArrayElementInterceptor.clear();
+ obj.floats[0] = floatVal;
+ assertEquals(-1, TestArrayElementInterceptor.index);
+ assertNull(TestArrayElementInterceptor.value);
+
+ int intVal = 1000;
+ TestArrayElementInterceptor.clear();
+ obj.ints[0] = intVal;
+ assertEquals(0, TestArrayElementInterceptor.index);
+ assertEquals(intVal, TestArrayElementInterceptor.value);
+ TestArrayElementInterceptor.clear();
+ obj.ints[0] = intVal;
+ assertEquals(-1, TestArrayElementInterceptor.index);
+ assertNull(TestArrayElementInterceptor.value);
+
+ int[][] intVal2d = new int[][]{new int[]{1}, new int[]{2}};
+ TestArrayElementInterceptor.clear();
+ obj.ints3d[0] = intVal2d;
+ assertEquals(0, TestArrayElementInterceptor.index);
+ assertEquals(intVal2d, TestArrayElementInterceptor.value);
+ TestArrayElementInterceptor.clear();
+ obj.ints3d[0] = intVal2d;
+ assertEquals(-1, TestArrayElementInterceptor.index);
+ assertNull(TestArrayElementInterceptor.value);
+
+ long longVal = 10001;
+ TestArrayElementInterceptor.clear();
+ obj.longs[0] = longVal;
+ assertEquals(0, TestArrayElementInterceptor.index);
+ assertEquals(longVal, TestArrayElementInterceptor.value);
+ TestArrayElementInterceptor.clear();
+ obj.longs[0] = longVal;
+ assertEquals(-1, TestArrayElementInterceptor.index);
+ assertNull(TestArrayElementInterceptor.value);
+
+ short shortVal = 999;
+ TestArrayElementInterceptor.clear();
+ obj.shorts[0] = shortVal;
+ assertEquals(0, TestArrayElementInterceptor.index);
+ assertEquals(shortVal, TestArrayElementInterceptor.value);
+ TestArrayElementInterceptor.clear();
+ obj.shorts[0] = shortVal;
+ assertEquals(-1, TestArrayElementInterceptor.index);
+ assertNull(TestArrayElementInterceptor.value);
+
+ Object objectVal = new int[] {1,2,3};
+ TestArrayElementInterceptor.clear();
+ obj.objects[0] = objectVal;
+ assertEquals(0, TestArrayElementInterceptor.index);
+ assertEquals(objectVal, TestArrayElementInterceptor.value);
+ TestArrayElementInterceptor.clear();
+ obj.objects[0] = objectVal;
+ assertEquals(-1, TestArrayElementInterceptor.index);
+ assertNull(TestArrayElementInterceptor.value);
+ intVal = 100;
+ TestArrayElementInterceptor.clear();
+ ((int[])objectVal)[0] = intVal;
+ assertEquals(0, TestArrayElementInterceptor.index);
+ assertEquals(intVal, TestArrayElementInterceptor.value);
+ TestArrayElementInterceptor.clear();
+ ((int[])objectVal)[0] = intVal;
+ assertEquals(-1, TestArrayElementInterceptor.index);
+ assertNull(TestArrayElementInterceptor.value);
+ }
+
public void testUnadvisedArrayFields()
{
ClassWithUnadvisedArrayFields obj = new ClassWithUnadvisedArrayFields();
@@ -520,6 +820,6 @@
obj.shorts[0] = 100;
assertEquals(100, obj.shorts[0]);
assertEquals(-1, TestArrayElementInterceptor.index);
-
}
+
}
Modified: projects/aop/branches/arrays/aop/src/test/org/jboss/test/aop/array/ClassWithArrayFields.java
===================================================================
--- projects/aop/branches/arrays/aop/src/test/org/jboss/test/aop/array/ClassWithArrayFields.java 2006-12-27 18:02:24 UTC (rev 59239)
+++ projects/aop/branches/arrays/aop/src/test/org/jboss/test/aop/array/ClassWithArrayFields.java 2006-12-28 21:18:10 UTC (rev 59240)
@@ -21,8 +21,6 @@
*/
package org.jboss.test.aop.array;
-import java.util.Arrays;
-
/**
*
* @author <a href="kabir.khan at jboss.com">Kabir Khan</a>
@@ -51,6 +49,7 @@
};
public long[] longs = new long[] {1L, 2L, 3L};
public short[] shorts = new short[] {1,2,3};
+ public Object objectField = new int[] {1, 2, 3};
public ClassWithArrayFields()
{
More information about the jboss-cvs-commits
mailing list