Index: main/java/java/beans/Encoder.java =================================================================== --- main/java/java/beans/Encoder.java (revision 427130) +++ main/java/java/beans/Encoder.java (working copy) @@ -116,16 +116,20 @@ if (node != null) { try { + Statement statement; Object[] oldArgs = oldStm.getArguments(); + write(oldArgs); - - Statement statement = new Statement(node.getObjectValue(), + statement = new Statement(node.getObjectValue(), oldStm.getMethodName(), oldArgs); + statement.execute(); node.addStatement(statement); } catch (Exception e) { getExceptionListener().exceptionThrown(e); } } else { + // FIXME incompatible with RI, default constructor should be + // called instead System.out.println("no node is found for statement with target = " + oldStm.getTarget()); } @@ -161,7 +165,8 @@ // if an expression is not a constructor // FIXME prevents instance methods of Class and Method objects // from being handled correctly - if (!(oldExp.getTarget() instanceof Class || oldExp.getTarget() instanceof Field)) { + if (!(oldExp.getTarget() instanceof Class + || oldExp.getTarget() instanceof Field)) { ObjectNode parent = nodes.get(oldExp.getTarget()); parent.addExpression(oldExp); @@ -206,10 +211,8 @@ } ObjectNode node = nodes.get(oldInstance); + if (node == null) { - //XXX type is never used - //Class type = oldInstance.getClass(); - doWriteObject(oldInstance); node = nodes.get(oldInstance); } else { @@ -231,6 +234,10 @@ return null; } + /** + * @param node node to return the value for + * @return tentative object value for given node + */ private Object getValue(ObjectNode node) { if (node != null) { try { Index: main/java/java/beans/PersistenceDelegate.java =================================================================== --- main/java/java/beans/PersistenceDelegate.java (revision 427130) +++ main/java/java/beans/PersistenceDelegate.java (working copy) @@ -38,10 +38,11 @@ */ protected void initialize( Class type, Object oldInstance, Object newInstance, Encoder out) { - if((out != null) && (type != null)) { + if ((out != null) && (type != null)) { PersistenceDelegate pd = out.getPersistenceDelegate( type.getSuperclass()); - if(pd != null) { + + if (pd != null) { pd.initialize(type, oldInstance, newInstance, out); } } @@ -59,7 +60,7 @@ boolean bothInstancesAreNull = (oldInstance == null) && (newInstance == null); - if(bothInstancesAreNull) { + if (bothInstancesAreNull) { return false; } else { return (oldInstance != null) && (newInstance != null) ? @@ -71,29 +72,22 @@ * @com.intel.drl.spec_ref */ public void writeObject(Object oldInstance, Encoder out) { - Object newInstance = (oldInstance != null) ? out.get(oldInstance) - : null; + + // nulls are covered by NullPersistenceDelegate + assert oldInstance != null; + + Object newInstance = out.get(oldInstance); - // FIXME rewrite, handling of nulls is not obvious - if(mutatesTo(oldInstance, newInstance)) { - if(oldInstance != null) { - initialize(oldInstance.getClass(), oldInstance, newInstance, - out); - } else { - out.writeExpression(instantiate(oldInstance, out)); - } - } else { - if(newInstance != null) { + if (mutatesTo(oldInstance, newInstance)) { + initialize(oldInstance.getClass(), oldInstance, newInstance, out); + } else { + if (newInstance != null) { out.remove(newInstance); } out.writeExpression(instantiate(oldInstance, out)); - - if(oldInstance != null) { - newInstance = out.get(oldInstance); - initialize(oldInstance.getClass(), oldInstance, newInstance, - out); - } - } + newInstance = out.get(oldInstance); + initialize(oldInstance.getClass(), oldInstance, newInstance, out); + } } } Index: main/java/org/apache/harmony/beans/ArrayPersistenceDelegate.java =================================================================== --- main/java/org/apache/harmony/beans/ArrayPersistenceDelegate.java (revision 427130) +++ main/java/org/apache/harmony/beans/ArrayPersistenceDelegate.java (working copy) @@ -45,6 +45,9 @@ } protected Expression instantiate(Object oldInstance, Encoder out) { + assert oldInstance != null && + oldInstance.getClass().isArray() : oldInstance; + int length = Array.getLength(oldInstance); Class componentType = oldInstance.getClass().getComponentType(); @@ -54,26 +57,28 @@ protected void initialize( Class type, Object oldInstance, Object newInstance, Encoder out) { + + assert oldInstance != null && + oldInstance.getClass().isArray() : oldInstance; + assert newInstance != null && + newInstance.getClass().isArray() : newInstance; + int length = Array.getLength(oldInstance); Class componentType = type.getComponentType(); + Object nullValue = Array.get(Array.newInstance(componentType, 1), 0); - Object nullValue = null; - if(componentType != null) { // is array - Object array = Array.newInstance(componentType, 1); - nullValue = Array.get(array, 0); - } - - for(int i = 0; i < length; ++i) { + for (int i = 0; i < length; ++i) { Object oldValue = Array.get(oldInstance, i); Object newValue = Array.get(newInstance, i); - if(oldValue != null && !oldValue.equals(newValue) || + if (oldValue != null && !oldValue.equals(newValue) || oldValue == null && newValue != null) { - if(nullValue == null || !nullValue.equals(oldValue)) { + if (nullValue == null || !nullValue.equals(oldValue)) { Statement s = new Statement(oldInstance, "set", new Object[]{ new Integer(i), oldValue }); + out.writeStatement(s); } } @@ -82,18 +87,19 @@ } protected boolean mutatesTo(Object oldInstance, Object newInstance) { - if (oldInstance != null && newInstance != null) { - Class oldCl = oldInstance.getClass(); + assert oldInstance != null && + oldInstance.getClass().isArray() : oldInstance; + + if (newInstance != null) { Class newCl = newInstance.getClass(); - if (oldCl.isArray() && !newCl.isArray() || - newCl.isArray() && !oldCl.isArray()) { + if (!newCl.isArray()) { return false; - } else if (oldCl.isArray() && newCl.isArray()) { + } else { // both are arrays int l1 = Array.getLength(oldInstance); int l2 = Array.getLength(newInstance); - Class cType1 = oldCl.getComponentType(); + Class cType1 = oldInstance.getClass().getComponentType(); Class cType2 = newCl.getComponentType(); if (l1 == l2 && cType1.equals(cType2)) { @@ -102,8 +108,8 @@ return false; } } + } else { + return false; } - // both are nulls or have non-Array type - return super.mutatesTo(oldInstance, newInstance); } } Index: main/java/org/apache/harmony/beans/NullPersistenceDelegate.java =================================================================== --- main/java/org/apache/harmony/beans/NullPersistenceDelegate.java (revision 427130) +++ main/java/org/apache/harmony/beans/NullPersistenceDelegate.java (working copy) @@ -32,10 +32,16 @@ public class NullPersistenceDelegate extends PersistenceDelegate { protected Expression instantiate(Object oldInstance, Encoder out) { + assert oldInstance == null; return new Expression(null, null, null, null); } protected void initialize( Class type, Object oldInstance, Object newInstance, Encoder out) { } + + public void writeObject(Object oldInstance, Encoder out) { + assert oldInstance == null; + out.writeExpression(instantiate(null, out)); + } } Index: test/java/org/apache/harmony/beans/tests/java/beans/CustomizedPersistenceDelegateTest.java =================================================================== --- test/java/org/apache/harmony/beans/tests/java/beans/CustomizedPersistenceDelegateTest.java (revision 427130) +++ test/java/org/apache/harmony/beans/tests/java/beans/CustomizedPersistenceDelegateTest.java (working copy) @@ -15,25 +15,25 @@ package org.apache.harmony.beans.tests.java.beans; -import java.beans.DefaultPersistenceDelegate; +//import java.beans.DefaultPersistenceDelegate; import java.beans.Encoder; import java.beans.Expression; import java.beans.PersistenceDelegate; import java.beans.Statement; -import java.beans.XMLEncoder; -import java.io.ByteArrayOutputStream; +//import java.beans.XMLEncoder; +//import java.io.ByteArrayOutputStream; import java.lang.reflect.Field; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; -import java.util.AbstractList; -import java.util.ArrayList; +//import java.util.AbstractList; +//import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import java.util.Vector; +//import java.util.Collection; +//import java.util.Iterator; +//import java.util.List; +//import java.util.ListIterator; +//import java.util.Vector; import junit.framework.TestCase; @@ -170,53 +170,54 @@ enc.writeObject(f); assertEquals(f, enc.get(f)); } + - static class MockPersistenceDelegate extends DefaultPersistenceDelegate { - public MockPersistenceDelegate(String s) { - } +// static class MockPersistenceDelegate extends DefaultPersistenceDelegate { +// public MockPersistenceDelegate(String s) { +// } +// +// protected void initialize(Class type, Object oldInstance, +// Object newInstance, Encoder enc) { +// // System.out.println(name + " initialize called: " + type); +// // new Throwable().printStackTrace(); +// super.initialize(type, oldInstance, newInstance, enc); +// // System.out.println(name + " initialize exited"); +// } +// +// protected Expression instantiate(Object oldInstance, Encoder enc) { +// // System.out.println(name + " instantiate called"); +// return super.instantiate(oldInstance, enc); +// } +// +// protected boolean mutatesTo(Object o1, Object o2) { +// // System.out.println(name + " mutatesTo called"); +// return super.mutatesTo(o1, o2); +// } +// } - protected void initialize(Class type, Object oldInstance, - Object newInstance, Encoder enc) { - // System.out.println(name + " initialize called: " + type); - // new Throwable().printStackTrace(); - super.initialize(type, oldInstance, newInstance, enc); - // System.out.println(name + " initialize exited"); - } +// static class MockPersistenceDelegate2 extends PersistenceDelegate { +// public MockPersistenceDelegate2(String s) { +// } +// +// protected void initialize(Class type, Object oldInstance, +// Object newInstance, Encoder enc) { +// // System.out.println(name + " initialize called: " + type); +// // new Throwable().printStackTrace(); +// super.initialize(type, oldInstance, newInstance, enc); +// // System.out.println(name + " initialize exited"); +// } +// +// protected Expression instantiate(Object oldInstance, Encoder enc) { +// // System.out.println(name + " instantiate called"); +// return null; +// } +// +// protected boolean mutatesTo(Object o1, Object o2) { +// // System.out.println(name + " mutatesTo called"); +// return super.mutatesTo(o1, o2); +// } +// } - protected Expression instantiate(Object oldInstance, Encoder enc) { - // System.out.println(name + " instantiate called"); - return super.instantiate(oldInstance, enc); - } - - protected boolean mutatesTo(Object o1, Object o2) { - // System.out.println(name + " mutatesTo called"); - return super.mutatesTo(o1, o2); - } - } - - static class MockPersistenceDelegate2 extends PersistenceDelegate { - public MockPersistenceDelegate2(String s) { - } - - protected void initialize(Class type, Object oldInstance, - Object newInstance, Encoder enc) { - // System.out.println(name + " initialize called: " + type); - // new Throwable().printStackTrace(); - super.initialize(type, oldInstance, newInstance, enc); - // System.out.println(name + " initialize exited"); - } - - protected Expression instantiate(Object oldInstance, Encoder enc) { - // System.out.println(name + " instantiate called"); - return null; - } - - protected boolean mutatesTo(Object o1, Object o2) { - // System.out.println(name + " mutatesTo called"); - return super.mutatesTo(o1, o2); - } - } - static class MockEncoder extends Encoder { public void writeObject(Object o) { // System.out.println("write object: " + o); @@ -261,153 +262,153 @@ /* * Mock grand parent. */ - public static class MockGrandParent { - boolean b; +// public static class MockGrandParent { +// boolean b; +// +// public boolean getPropb() { +// return this.b; +// } +// +// public void setPropb(boolean b) { +// this.b = b; +// } +// } - public boolean getPropb() { - return this.b; - } - - public void setPropb(boolean b) { - this.b = b; - } - } - /* * Mock parent. */ - public static class MockParent extends MockGrandParent { - String s; +// public static class MockParent extends MockGrandParent { +// String s; +// +// int i; +// +// public int getProp() { +// return 2; +// } +// +// public void setProp(int i) { +// this.i = i; +// } +// +// public String getProps() { +// return this.s; +// } +// +// public void setProps(String s) { +// this.s = s; +// } +// } - int i; - - public int getProp() { - return 2; - } - - public void setProp(int i) { - this.i = i; - } - - public String getProps() { - return this.s; - } - - public void setProps(String s) { - this.s = s; - } - } - /* * Mock object. */ - public static class MockObject extends AbstractList implements MyInterface, - List { - int i; +// public static class MockObject extends AbstractList implements MyInterface, +// List { +// int i; +// +// Vector v = new Vector(); +// +// public void add(int location, Object object) { +// v.add(location, object); +// } +// +// public boolean add(Object object) { +// return v.add(object); +// } +// +// public boolean addAll(Collection collection) { +// return v.addAll(collection); +// } +// +// public boolean addAll(int location, Collection collection) { +// return v.addAll(location, collection); +// } +// +// public void clear() { +// v.clear(); +// } +// +// public boolean contains(Object object) { +// return v.contains(object); +// } +// +// public boolean containsAll(Collection collection) { +// return v.containsAll(collection); +// } +// +// public Object get(int location) { +// return v.get(location); +// } +// +// public int indexOf(Object object) { +// return v.indexOf(object); +// } +// +// public boolean isEmpty() { +// return v.isEmpty(); +// } +// +// public Iterator iterator() { +// return v.iterator(); +// } +// +// public int lastIndexOf(Object object) { +// return v.lastIndexOf(object); +// } +// +// public ListIterator listIterator() { +// return v.listIterator(); +// } +// +// public ListIterator listIterator(int location) { +// return v.listIterator(location); +// } +// +// public Object remove(int location) { +// return v.remove(location); +// } +// +// public boolean remove(Object object) { +// return v.remove(object); +// } +// +// public boolean removeAll(Collection collection) { +// return v.removeAll(collection); +// } +// +// public boolean retainAll(Collection collection) { +// return v.retainAll(collection); +// } +// +// public Object set(int location, Object object) { +// return v.set(location, object); +// } +// +// public int size() { +// return v.size(); +// } +// +// public List subList(int start, int end) { +// return v.subList(start, end); +// } +// +// public Object[] toArray() { +// return v.toArray(); +// } +// +// public Object[] toArray(Object[] array) { +// return v.toArray(array); +// } +// +// public int getProp() { +// return i; +// } +// +// public void setProp(int i) { +// this.i = i; +// } +// } - Vector v = new Vector(); - - public void add(int location, Object object) { - v.add(location, object); - } - - public boolean add(Object object) { - return v.add(object); - } - - public boolean addAll(Collection collection) { - return v.addAll(collection); - } - - public boolean addAll(int location, Collection collection) { - return v.addAll(location, collection); - } - - public void clear() { - v.clear(); - } - - public boolean contains(Object object) { - return v.contains(object); - } - - public boolean containsAll(Collection collection) { - return v.containsAll(collection); - } - - public Object get(int location) { - return v.get(location); - } - - public int indexOf(Object object) { - return v.indexOf(object); - } - - public boolean isEmpty() { - return v.isEmpty(); - } - - public Iterator iterator() { - return v.iterator(); - } - - public int lastIndexOf(Object object) { - return v.lastIndexOf(object); - } - - public ListIterator listIterator() { - return v.listIterator(); - } - - public ListIterator listIterator(int location) { - return v.listIterator(location); - } - - public Object remove(int location) { - return v.remove(location); - } - - public boolean remove(Object object) { - return v.remove(object); - } - - public boolean removeAll(Collection collection) { - return v.removeAll(collection); - } - - public boolean retainAll(Collection collection) { - return v.retainAll(collection); - } - - public Object set(int location, Object object) { - return v.set(location, object); - } - - public int size() { - return v.size(); - } - - public List subList(int start, int end) { - return v.subList(start, end); - } - - public Object[] toArray() { - return v.toArray(); - } - - public Object[] toArray(Object[] array) { - return v.toArray(array); - } - - public int getProp() { - return i; - } - - public void setProp(int i) { - this.i = i; - } - } - /* * Handler for the proxy class. */ @@ -443,93 +444,124 @@ } } - public static void main1(String[] args) throws Exception { - ByteArrayOutputStream os = new ByteArrayOutputStream(); - XMLEncoder enc = new XMLEncoder(os); - MockEncoder enc2 = new MockEncoder(); - enc2.setPersistenceDelegate(MyInterface.class, - new MockPersistenceDelegate("interface")); - enc2.setPersistenceDelegate(MockParent.class, - new MockPersistenceDelegate("parent class")); - enc2.setPersistenceDelegate(MockGrandParent.class, - new MockPersistenceDelegate("grand parent class")); +// public static void main1(String[] args) throws Exception { +// ByteArrayOutputStream os = new ByteArrayOutputStream(); +// XMLEncoder enc = new XMLEncoder(os); +// MockEncoder enc2 = new MockEncoder(); +// enc2.setPersistenceDelegate(MyInterface.class, +// new MockPersistenceDelegate("interface")); +// enc2.setPersistenceDelegate(MockParent.class, +// new MockPersistenceDelegate("parent class")); +// enc2.setPersistenceDelegate(MockGrandParent.class, +// new MockPersistenceDelegate("grand parent class")); +// +// // Vector +// Vector v = new Vector(); +// v.add("hehe"); +// // enc.writeObject(v); +// +// // ArrayList +// ArrayList al = new ArrayList(); +// al.add("hehe"); +// // enc.writeObject(al); +// +// // Field +// Integer.class.getDeclaredField("TYPE"); +// // enc.writeObject(m); +// +// // Complex bean with indexed properties +// ComplexBean cb = new ComplexBean(); +// cb.setI(0, true); +// // enc.writeObject(cb); +// +// MockObject o = new MockObject(); +// o.add("haha"); +// o.setProp(3); +// // o.setProps("test"); +// // o.setPropb(true); +// // Menu mm = new Menu("MyMenu"); +// // MenuItem mi = new MenuItem("menu1"); +// // mm.add(mi); +// // enc.writeObject(mm); +// +// // enc2.writeObject(o); +// // enc.writeObject(o); +// // new MockPersistenceDelegate2("PD").initialize(AbstractList.class, v, +// // new Vector(), enc2); +// +// enc.close(); +// +// System.out.println(os.toString()); +// // System.out.println(enc2.getPersistenceDelegate(MyInterface.class)); +// // System.out.println(enc2.getPersistenceDelegate(Vector.class)); +// // System.out.println(enc2.getPersistenceDelegate(List.class)); +// // System.out.println(enc2.getPersistenceDelegate(Collection.class)); +// // System.out.println(enc2 +// // .getPersistenceDelegate(AbstractCollection.class)); +// // System.out.println(enc2.getPersistenceDelegate(AbstractList.class)); +// // System.out.println(enc2.getPersistenceDelegate(Map.class)); +// // System.out.println(enc2.getPersistenceDelegate(Hashtable.class)); +// // System.out.println(enc2.getPersistenceDelegate(HashMap.class)); +// // System.out.println(enc2.getPersistenceDelegate(Component.class)); +// +// } - // Vector - Vector v = new Vector(); - v.add("hehe"); - // enc.writeObject(v); +// public static void main(String[] args) throws Exception { +// XMLEncoder e = new XMLEncoder(System.out); +// e.writeStatement(new Expression(Integer.class, "getField", +// new Object[] { "TYPE" })); +// // e.writeObject(Integer.TYPE); +// e.close(); +// } - // ArrayList - ArrayList al = new ArrayList(); - al.add("hehe"); - // enc.writeObject(al); +// public static class ComplexBean { +// boolean[] ba = new boolean[2]; +// +// public void setI(int i, boolean b) { +// ba[i] = b; +// } +// +// public boolean getI(int i) { +// return ba[i]; +// } +// // +// // public void setI(boolean[] ba) { +// // this.ba = ba; +// // } +// // +// // public boolean[] getI() { +// // return ba; +// // } +// } + + public static class MockBean { + String str; - // Field - Integer.class.getDeclaredField("TYPE"); - // enc.writeObject(m); + public MockBean() { + this.str = ""; + } - // Complex bean with indexed properties - ComplexBean cb = new ComplexBean(); - cb.setI(0, true); - // enc.writeObject(cb); + public String getStr() { + return str; + } + + public void addStr(String s) { + str += s; + } - MockObject o = new MockObject(); - o.add("haha"); - o.setProp(3); - // o.setProps("test"); - // o.setPropb(true); - // Menu mm = new Menu("MyMenu"); - // MenuItem mi = new MenuItem("menu1"); - // mm.add(mi); - // enc.writeObject(mm); + public MockBean side() { + str += "side"; + return new MockBean(); + } - // enc2.writeObject(o); - // enc.writeObject(o); - // new MockPersistenceDelegate2("PD").initialize(AbstractList.class, v, - // new Vector(), enc2); + public MockBean side2() { + str += "side2"; + return new MockBean(); + } + + public String toString() { + return str; + } + } - enc.close(); - - System.out.println(os.toString()); - // System.out.println(enc2.getPersistenceDelegate(MyInterface.class)); - // System.out.println(enc2.getPersistenceDelegate(Vector.class)); - // System.out.println(enc2.getPersistenceDelegate(List.class)); - // System.out.println(enc2.getPersistenceDelegate(Collection.class)); - // System.out.println(enc2 - // .getPersistenceDelegate(AbstractCollection.class)); - // System.out.println(enc2.getPersistenceDelegate(AbstractList.class)); - // System.out.println(enc2.getPersistenceDelegate(Map.class)); - // System.out.println(enc2.getPersistenceDelegate(Hashtable.class)); - // System.out.println(enc2.getPersistenceDelegate(HashMap.class)); - // System.out.println(enc2.getPersistenceDelegate(Component.class)); - - } - - public static void main(String[] args) throws Exception { - XMLEncoder e = new XMLEncoder(System.out); - e.writeStatement(new Expression(Integer.class, "getField", - new Object[] { "TYPE" })); - // e.writeObject(Integer.TYPE); - e.close(); - } - - public static class ComplexBean { - boolean[] ba = new boolean[2]; - - public void setI(int i, boolean b) { - ba[i] = b; - } - - public boolean getI(int i) { - return ba[i]; - } - // - // public void setI(boolean[] ba) { - // this.ba = ba; - // } - // - // public boolean[] getI() { - // return ba; - // } - } }