You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by hi...@apache.org on 2010/09/29 19:00:10 UTC
svn commit: r1002734 - in /harmony/enhanced/java/branches/java6: ./
classlib/ classlib/depends/libs/
classlib/modules/beans/src/main/java/java/beans/ drlvm/ jdktools/
Author: hindessm
Date: Wed Sep 29 17:00:09 2010
New Revision: 1002734
URL: http://svn.apache.org/viewvc?rev=1002734&view=rev
Log:
Merge change from trunk@1002511:
r1002511 | zhoukevin | 2010-09-29 09:10:27 +0100 (Wed, 29 Sep 2010) | 1 line
Apply the patch for HARMONY-6664: Poor performance of
java.beans.XMLEncoder.writeObject() method. This reduce the time of
writing a list of 25000 integers from 30 seconds to 3 seconds, improve
the performance of XMLEncoder.writeObject() to some extent.
Removed:
harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/ReferenceMap.java
Modified:
harmony/enhanced/java/branches/java6/ (props changed)
harmony/enhanced/java/branches/java6/classlib/ (props changed)
harmony/enhanced/java/branches/java6/classlib/depends/libs/ (props changed)
harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/DefaultPersistenceDelegate.java
harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/Encoder.java
harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/PersistenceDelegate.java
harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/XMLEncoder.java
harmony/enhanced/java/branches/java6/drlvm/ (props changed)
harmony/enhanced/java/branches/java6/jdktools/ (props changed)
Propchange: harmony/enhanced/java/branches/java6/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Sep 29 17:00:09 2010
@@ -1,4 +1,4 @@
/harmony/enhanced/java/branches/mrh:935751-941490
-/harmony/enhanced/java/trunk:929253-997624,997759,997980,997986,998010,998030,998619,998628,998759,998804,998822,999260,999286,999306,999591,999601,999623,999715-999716,999724,999793,1000005,1000169,1000213,1000229,1000231,1000233,1000240,1000245,1000248,1000265,1000527,1000689,1000696,1000699-1000700,1000705,1000708,1001065,1001080,1001153,1001187,1001490,1001609,1001638,1001652,1001723,1001741,1001744-1001745,1001751,1002080,1002189,1002476,1002480,1002488,1002506
+/harmony/enhanced/java/trunk:929253-997624,997759,997980,997986,998010,998030,998619,998628,998759,998804,998822,999260,999286,999306,999591,999601,999623,999715-999716,999724,999793,1000005,1000169,1000213,1000229,1000231,1000233,1000240,1000245,1000248,1000265,1000527,1000689,1000696,1000699-1000700,1000705,1000708,1001065,1001080,1001153,1001187,1001490,1001609,1001638,1001652,1001723,1001741,1001744-1001745,1001751,1002080,1002189,1002476,1002480,1002488,1002506,1002511
/harmony/enhanced/trunk:476395-929252
/incubator/harmony/enhanced/trunk:292550-476394
Propchange: harmony/enhanced/java/branches/java6/classlib/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Sep 29 17:00:09 2010
@@ -1,7 +1,7 @@
/harmony/enhanced/classlib/trunk:713674-735919,765923-926091,926318-926838
/harmony/enhanced/classlib/trunk/working_classlib:884014-884286
/harmony/enhanced/java/branches/mrh/classlib:935751-941490
-/harmony/enhanced/java/trunk/classlib:929253-997624,997759,997980,997986,998010,998030,998619,998628,998759,998804,998822,999260,999286,999306,999591,999601,999623,999715-999716,999724,999793,1000005,1000169,1000213,1000229,1000231,1000233,1000240,1000245,1000248,1000265,1000527,1000689,1000696,1000699-1000700,1000705,1000708,1001065,1001080,1001153,1001187,1001490,1001609,1001638,1001652,1001723,1001741,1001744-1001745,1001751,1002080,1002189,1002476,1002480,1002488,1002506
+/harmony/enhanced/java/trunk/classlib:929253-997624,997759,997980,997986,998010,998030,998619,998628,998759,998804,998822,999260,999286,999306,999591,999601,999623,999715-999716,999724,999793,1000005,1000169,1000213,1000229,1000231,1000233,1000240,1000245,1000248,1000265,1000527,1000689,1000696,1000699-1000700,1000705,1000708,1001065,1001080,1001153,1001187,1001490,1001609,1001638,1001652,1001723,1001741,1001744-1001745,1001751,1002080,1002189,1002476,1002480,1002488,1002506,1002511
/harmony/enhanced/trunk/classlib:476395-929252
/harmony/enhanced/trunk/working_classlib:476396-920147
/incubator/harmony/enhanced/trunk/classlib:292550-476394
Propchange: harmony/enhanced/java/branches/java6/classlib/depends/libs/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Sep 29 17:00:09 2010
@@ -1,4 +1,4 @@
/harmony/enhanced/classlib/trunk/depends/libs:544451-926091
-/harmony/enhanced/java/trunk/classlib/depends/libs:929253-997624,997759,997980,997986,998010,998030,998619,998628,998759,998804,998822,999260,999286,999306,999591,999601,999623,999715-999716,999724,999793,1000005,1000169,1000213,1000229,1000231,1000233,1000240,1000245,1000248,1000265,1000527,1000689,1000696,1000699-1000700,1000705,1000708,1001065,1001080,1001153,1001187,1001490,1001609,1001638,1001652,1001723,1001741,1001744-1001745,1001751,1002080,1002189,1002476,1002480,1002488,1002506
+/harmony/enhanced/java/trunk/classlib/depends/libs:929253-997624,997759,997980,997986,998010,998030,998619,998628,998759,998804,998822,999260,999286,999306,999591,999601,999623,999715-999716,999724,999793,1000005,1000169,1000213,1000229,1000231,1000233,1000240,1000245,1000248,1000265,1000527,1000689,1000696,1000699-1000700,1000705,1000708,1001065,1001080,1001153,1001187,1001490,1001609,1001638,1001652,1001723,1001741,1001744-1001745,1001751,1002080,1002189,1002476,1002480,1002488,1002506,1002511
/harmony/enhanced/trunk/classlib/depends/libs:476395-929252
/incubator/harmony/enhanced/trunk/classlib/depends/libs:292550-476394
Modified: harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/DefaultPersistenceDelegate.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/DefaultPersistenceDelegate.java?rev=1002734&r1=1002733&r2=1002734&view=diff
==============================================================================
--- harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/DefaultPersistenceDelegate.java (original)
+++ harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/DefaultPersistenceDelegate.java Wed Sep 29 17:00:09 2010
@@ -115,22 +115,23 @@ public class DefaultPersistenceDelegate
return;
}
PropertyDescriptor[] pds = info.getPropertyDescriptors();
-
+ Method getter, setter;
// Initialize each found non-transient property
for (int i = 0; i < pds.length; i++) {
// Skip a property whose transient attribute is true
if (Boolean.TRUE.equals(pds[i].getValue("transient"))) { //$NON-NLS-1$
continue;
}
+ getter = pds[i].getReadMethod();
+ setter = pds[i].getWriteMethod();
// Skip a property having no setter or getter
- if (null == pds[i].getWriteMethod()
- || null == pds[i].getReadMethod()) {
+ if (getter == null || setter == null) {
continue;
}
// Get the value of the property in the old instance
- Expression getterExp = new Expression(oldInstance, pds[i]
- .getReadMethod().getName(), null);
+ Expression getterExp = new Expression(oldInstance,
+ getter.getName(), null);
try {
// Calculate the old value of the property
Object oldVal = getterExp.getValue();
@@ -138,30 +139,14 @@ public class DefaultPersistenceDelegate
enc.writeExpression(getterExp);
// Get the target value that exists in the new environment
Object targetVal = enc.get(oldVal);
- // Get the current property value in the new environment
- Object newVal = new Expression(newInstance, pds[i]
- .getReadMethod().getName(), null).getValue();
- /*
- * Make the target value and current property value equivalent
- * in the new environment
- */
- if (null == targetVal) {
- if (null != newVal) {
- // Set to null
- Statement setterStm = new Statement(oldInstance, pds[i]
- .getWriteMethod().getName(),
- new Object[] { null });
- enc.writeStatement(setterStm);
- }
- } else {
- PersistenceDelegate pd = enc
- .getPersistenceDelegate(targetVal.getClass());
- if (!pd.mutatesTo(targetVal, newVal)) {
- Statement setterStm = new Statement(oldInstance, pds[i]
- .getWriteMethod().getName(),
- new Object[] { oldVal });
- enc.writeStatement(setterStm);
- }
+ Object newVal = new Expression(newInstance, getter.getName(),
+ null).getValue();
+ boolean invokeSetter = targetVal == null ? (newVal != null && oldVal == null)
+ : !enc.getPersistenceDelegate(targetVal.getClass())
+ .mutatesTo(targetVal, newVal);
+ if (invokeSetter) {
+ enc.writeStatement(new Statement(oldInstance, setter
+ .getName(), new Object[] { oldVal }));
}
} catch (Exception ex) {
enc.getExceptionListener().exceptionThrown(ex);
Modified: harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/Encoder.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/Encoder.java?rev=1002734&r1=1002733&r2=1002734&view=diff
==============================================================================
--- harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/Encoder.java (original)
+++ harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/Encoder.java Wed Sep 29 17:00:09 2010
@@ -40,6 +40,7 @@ import java.lang.reflect.Proxy;
import java.util.Collection;
import java.util.Date;
import java.util.Hashtable;
+import java.util.IdentityHashMap;
import java.util.Map;
import javax.swing.Box;
@@ -49,16 +50,16 @@ import javax.swing.JTabbedPane;
import javax.swing.ToolTipManager;
/**
- * The <code>Encoder</code>, together with <code>PersistenceDelegate</code>
- * s, can encode an object into a series of java statements. By executing these
+ * The <code>Encoder</code>, together with <code>PersistenceDelegate</code> s,
+ * can encode an object into a series of java statements. By executing these
* statements, a new object can be created and it will has the same state as the
* original object which has been passed to the encoder. Here "has the same
* state" means the two objects are indistinguishable from their public API.
* <p>
- * The <code>Encoder</code> and <code>PersistenceDelegate</code> s do this
- * by creating copies of the input object and all objects it references. The
- * copy process continues recursively util every object in the object graph has
- * its new copy and the new version has the same state as the old version. All
+ * The <code>Encoder</code> and <code>PersistenceDelegate</code> s do this by
+ * creating copies of the input object and all objects it references. The copy
+ * process continues recursively util every object in the object graph has its
+ * new copy and the new version has the same state as the old version. All
* statements used to create those new objects and executed on them during the
* process form the result of encoding.
* </p>
@@ -110,7 +111,7 @@ public class Encoder {
private ExceptionListener listener = defaultExListener;
- private ReferenceMap oldNewMap = new ReferenceMap();
+ private IdentityHashMap<Object, Object> oldNewMap = new IdentityHashMap<Object, Object>();
private static volatile boolean isInitilizedAWT;
@@ -143,7 +144,7 @@ public class Encoder {
* one.
*/
public Object get(Object old) {
- if (old == null || old instanceof String) {
+ if (old == null || old.getClass() == String.class) {
return old;
}
return oldNewMap.get(old);
@@ -167,15 +168,14 @@ public class Encoder {
* <p>
* The <code>PersistenceDelegate</code> is determined as following:
* <ol>
- * <li>If a <code>PersistenceDelegate</code> has been registered by
- * calling <code>setPersistenceDelegate</code> for the given type, it is
- * returned.</li>
+ * <li>If a <code>PersistenceDelegate</code> has been registered by calling
+ * <code>setPersistenceDelegate</code> for the given type, it is returned.</li>
* <li>If the given type is an array class, a special
* <code>PersistenceDelegate</code> for array types is returned.</li>
* <li>If the given type is a proxy class, a special
* <code>PersistenceDelegate</code> for proxy classes is returned.</li>
- * <li><code>Introspector</code> is used to check the bean descriptor
- * value "persistenceDelegate". If one is set, it is returned.</li>
+ * <li><code>Introspector</code> is used to check the bean descriptor value
+ * "persistenceDelegate". If one is set, it is returned.</li>
* <li>If none of the above applies, the
* <code>DefaultPersistenceDelegate</code> is returned.</li>
* </ol>
@@ -329,27 +329,40 @@ public class Encoder {
delegates.put(type, delegate);
}
- private Object forceNew(Object old) {
- if (old == null) {
+ Object expressionValue(Expression exp) {
+ try {
+ return exp == null ? null : exp.getValue();
+ } catch (IndexOutOfBoundsException e) {
return null;
+ } catch (Exception e) {
+ listener.exceptionThrown(new Exception(
+ "failed to excute expression: " + exp, e)); //$NON-NLS-1$
}
- Object nu = get(old);
- if (nu != null) {
- return nu;
- }
- writeObject(old);
- return get(old);
+ return null;
}
- private Object[] forceNewArray(Object[] oldArray) {
- if (oldArray == null) {
- return null;
+ private Statement createNewStatement(Statement oldStat) {
+ Object newTarget = createNewObject(oldStat.getTarget());
+ Object[] oldArgs = oldStat.getArguments();
+ Object[] newArgs = new Object[oldArgs.length];
+ for (int index = 0; index < oldArgs.length; index++) {
+ newArgs[index] = createNewObject(oldArgs[index]);
}
- Object newArray[] = new Object[oldArray.length];
- for (int i = 0; i < oldArray.length; i++) {
- newArray[i] = forceNew(oldArray[i]);
+
+ if (oldStat.getClass() == Expression.class) {
+ return new Expression(newTarget, oldStat.getMethodName(), newArgs);
+ } else {
+ return new Statement(newTarget, oldStat.getMethodName(), newArgs);
}
- return newArray;
+ }
+
+ private Object createNewObject(Object old) {
+ Object nu = get(old);
+ if (nu == null) {
+ writeObject(old);
+ nu = get(old);
+ }
+ return nu;
}
/**
@@ -382,30 +395,21 @@ public class Encoder {
throw new NullPointerException();
}
try {
- // if oldValue exists, noop
- Object oldValue = oldExp.getValue();
+ // if oldValue exists, no operation
+ Object oldValue = expressionValue(oldExp);
if (oldValue == null || get(oldValue) != null) {
return;
}
// copy to newExp
- Object newTarget = forceNew(oldExp.getTarget());
- Object newArgs[] = forceNewArray(oldExp.getArguments());
- Expression newExp = new Expression(newTarget, oldExp
- .getMethodName(), newArgs);
-
- // execute newExp
- Object newValue = null;
+ Expression newExp = (Expression) createNewStatement(oldExp);
+ // relate oldValue to newValue
try {
- newValue = newExp.getValue();
- } catch (IndexOutOfBoundsException ex) {
- // Current Container does not have any component, newVal set
- // to null
+ oldNewMap.put(oldValue, newExp.getValue());
+ } catch (IndexOutOfBoundsException e) {
+ // container does not have any component, set newVal null
}
- // relate oldValue to newValue
- put(oldValue, newValue);
-
// force same state
writeObject(oldValue);
} catch (Exception e) {
@@ -450,13 +454,8 @@ public class Encoder {
if (oldStat == null) {
throw new NullPointerException();
}
+ Statement newStat = createNewStatement(oldStat);
try {
- // copy to newStat
- Object newTarget = forceNew(oldStat.getTarget());
- Object newArgs[] = forceNewArray(oldStat.getArguments());
- Statement newStat = new Statement(newTarget, oldStat
- .getMethodName(), newArgs);
-
// execute newStat
newStat.execute();
} catch (Exception e) {
@@ -464,5 +463,4 @@ public class Encoder {
"failed to write statement: " + oldStat, e)); //$NON-NLS-1$
}
}
-
-}
+}
\ No newline at end of file
Modified: harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/PersistenceDelegate.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/PersistenceDelegate.java?rev=1002734&r1=1002733&r2=1002734&view=diff
==============================================================================
--- harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/PersistenceDelegate.java (original)
+++ harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/PersistenceDelegate.java Wed Sep 29 17:00:09 2010
@@ -90,10 +90,7 @@ public abstract class PersistenceDelegat
* false
*/
protected boolean mutatesTo(Object o1, Object o2) {
- if (null == o1 || null == o2 ) {
- return false;
- }
- return o1.getClass() == o2.getClass();
+ return null != o1 && null != o2 && o1.getClass() == o2.getClass();
}
/**
@@ -112,20 +109,16 @@ public abstract class PersistenceDelegat
*/
public void writeObject(Object oldInstance, Encoder out) {
Object newInstance = out.get(oldInstance);
+ Class<?> clazz = oldInstance.getClass();
if (mutatesTo(oldInstance, newInstance)) {
- initialize(oldInstance.getClass(), oldInstance, newInstance, out);
+ initialize(clazz, oldInstance, newInstance, out);
} else {
out.remove(oldInstance);
- Expression exp = instantiate(oldInstance, out);
- out.writeExpression(exp);
+ out.writeExpression(instantiate(oldInstance, out));
newInstance = out.get(oldInstance);
-
if (newInstance != null) {
- initialize(oldInstance.getClass(), oldInstance,
- newInstance, out);
+ initialize(clazz, oldInstance, newInstance, out);
}
}
}
-
-}
-
+}
\ No newline at end of file
Modified: harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/XMLEncoder.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/XMLEncoder.java?rev=1002734&r1=1002733&r2=1002734&view=diff
==============================================================================
--- harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/XMLEncoder.java (original)
+++ harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/XMLEncoder.java Wed Sep 29 17:00:09 2010
@@ -27,6 +27,7 @@ import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.List;
@@ -44,6 +45,8 @@ import org.apache.harmony.beans.internal
*/
public class XMLEncoder extends Encoder {
+ private static final String DEFAULT_ENCODING = "UTF-8"; //$NON-NLS-1$
+
private static int DEADLOCK_THRESHOLD = 7;
/*
@@ -92,11 +95,11 @@ public class XMLEncoder extends Encoder
private Object owner = null;
- private ReferenceMap records = new ReferenceMap();
+ private IdentityHashMap<Object, Record> objRecordMap = new IdentityHashMap<Object, Record>();
- private ReferenceMap objPrePendingCache = new ReferenceMap();
+ private IdentityHashMap<Class<?>, Integer> clazzCounterMap = new IdentityHashMap<Class<?>, Integer>();
- private ReferenceMap clazzCounterMap = new ReferenceMap();
+ private IdentityHashMap<Object, ArrayList<Object>> objPrePendingCache = new IdentityHashMap<Object, ArrayList<Object>>();
private boolean writingObject = false;
@@ -109,11 +112,10 @@ public class XMLEncoder extends Encoder
public XMLEncoder(OutputStream out) {
if (null != out) {
try {
- this.out = new PrintWriter(
- new OutputStreamWriter(out, "UTF-8"), true); //$NON-NLS-1$
+ this.out = new PrintWriter(new OutputStreamWriter(out,
+ DEFAULT_ENCODING), true);
} catch (UnsupportedEncodingException e) {
- // never occur
- e.printStackTrace();
+ // should never occur
}
}
}
@@ -166,7 +168,7 @@ public class XMLEncoder extends Encoder
for (Iterator<Object> iter = flushPending.iterator(); iter
.hasNext();) {
Object o = iter.next();
- Record rec = (Record) records.get(o);
+ Record rec = objRecordMap.get(o);
if (rec != null) {
preprocess(o, rec);
}
@@ -182,7 +184,7 @@ public class XMLEncoder extends Encoder
}
// clear statement records
- records.clear();
+ objRecordMap.clear();
flushPendingStat.clear();
objPrePendingCache.clear();
clazzCounterMap.clear();
@@ -201,54 +203,33 @@ public class XMLEncoder extends Encoder
if (obj == null) {
out.println("<null />");
} else if (obj instanceof String) {
- Record rec = (Record) records.get(obj);
+ Record rec = objRecordMap.get(obj);
if (null != rec) {
- if (flushPendingStat.contains(obj)) {
- flushExpression(obj, rec, indent - 3, true);
- } else {
- flushExpression(obj, rec, indent - 3, false);
- }
+ flushExpression(obj, rec, indent - 3,
+ flushPendingStat.contains(obj));
return;
}
out.print("<string>");
flushString((String) obj);
out.println("</string>");
} else if (obj instanceof Class<?>) {
- out.print("<class>");
- out.print(((Class<?>) obj).getName());
- out.println("</class>");
+ out.println("<class>" + ((Class<?>) obj).getName() + "</class>");
} else if (obj instanceof Boolean) {
- out.print("<boolean>");
- out.print(obj);
- out.println("</boolean>");
+ out.println("<boolean>" + obj + "</boolean>");
} else if (obj instanceof Byte) {
- out.print("<byte>");
- out.print(obj);
- out.println("</byte>");
+ out.println("<byte>" + obj + "</byte>");
} else if (obj instanceof Character) {
- out.print("<char>");
- out.print(obj);
- out.println("</char>");
+ out.println("<char>" + obj + "</char>");
} else if (obj instanceof Double) {
- out.print("<double>");
- out.print(obj);
- out.println("</double>");
+ out.println("<double>" + obj + "</double>");
} else if (obj instanceof Float) {
- out.print("<float>");
- out.print(obj);
- out.println("</float>");
+ out.println("<float>" + obj + "</float>");
} else if (obj instanceof Integer) {
- out.print("<int>");
- out.print(obj);
- out.println("</int>");
+ out.println("<int>" + obj + "</int>");
} else if (obj instanceof Long) {
- out.print("<long>");
- out.print(obj);
- out.println("</long>");
+ out.println("<long>" + obj + "</long>");
} else if (obj instanceof Short) {
- out.print("<short>");
- out.print(obj);
- out.println("</short>");
+ out.println("<short>" + obj + "</short>");
} else {
getExceptionListener().exceptionThrown(
new Exception(Messages.getString("beans.73", obj)));
@@ -287,14 +268,15 @@ public class XMLEncoder extends Encoder
private void flushIndent(int indent) {
for (int i = 0; i < indent; i++) {
- out.print(" "); //$NON-NLS-1$
+ out.print(' ');
}
}
private void flushObject(Object obj, int indent) {
- Record rec = (Record) records.get(obj);
- if (rec == null && !isBasicType(obj))
+ Record rec = objRecordMap.get(obj);
+ if (rec == null && !isBasicType(obj)) {
return;
+ }
if (obj == owner && this.needOwner) {
flushOwner(obj, rec, indent);
@@ -305,11 +287,7 @@ public class XMLEncoder extends Encoder
if (isBasicType(obj)) {
flushBasicObject(obj, indent);
} else {
- if (flushPendingStat.contains(obj)) {
- flushExpression(obj, rec, indent, true);
- } else {
- flushExpression(obj, rec, indent, false);
- }
+ flushExpression(obj, rec, indent, flushPendingStat.contains(obj));
}
}
@@ -451,7 +429,7 @@ public class XMLEncoder extends Encoder
Object args[] = stat.getArguments();
// special case for array
- if (Array.class == target && "newInstance".equals(method)) {
+ if (Array.class == target && BeansUtils.NEWINSTANCE.equals(method)) {
flushStatArray(stat, id, subStats, indent);
return;
}
@@ -643,10 +621,10 @@ public class XMLEncoder extends Encoder
for (int i = 0; i < subStats.size(); i++) {
Statement subStat = (Statement) subStats.get(i);
try {
- if (subStat instanceof Expression) {
+ if (subStat.getClass() == Expression.class) {
Expression subExp = (Expression) subStat;
Object obj = subExp.getValue();
- Record rec = (Record) records.get(obj);
+ Record rec = objRecordMap.get(obj);
flushExpression(obj, rec, indent + INDENT_UNIT, true);
} else {
flushStatement(subStat, null, Collections.EMPTY_LIST,
@@ -678,21 +656,21 @@ public class XMLEncoder extends Encoder
}
private boolean isGetArrayStat(Object target, String method, Object[] args) {
- return ("get".equals(method) && args.length == 1 //$NON-NLS-1$
+ return (BeansUtils.GET.equals(method) && args.length == 1
&& args[0] instanceof Integer && target.getClass().isArray());
}
private boolean isGetPropertyStat(String method, Object[] args) {
- return (method.startsWith("get") && method.length() > 3 && args.length == 0); //$NON-NLS-1$
+ return (method.startsWith(BeansUtils.GET) && method.length() > 3 && args.length == 0);
}
private boolean isSetArrayStat(Object target, String method, Object[] args) {
- return ("set".equals(method) && args.length == 2 //$NON-NLS-1$
+ return (BeansUtils.SET.equals(method) && args.length == 2
&& args[0] instanceof Integer && target.getClass().isArray());
}
private boolean isSetPropertyStat(String method, Object[] args) {
- return (method.startsWith("set") && method.length() > 3 && args.length == 1); //$NON-NLS-1$
+ return (method.startsWith(BeansUtils.SET) && method.length() > 3 && args.length == 1);
}
/*
@@ -719,15 +697,15 @@ public class XMLEncoder extends Encoder
// do it recursively
if (null != rec.exp) {
// deal with 'field' property
- Record targetRec = (Record) records.get(rec.exp.getTarget());
+ Record targetRec = objRecordMap.get(rec.exp.getTarget());
if (targetRec != null && targetRec.exp != null
&& "getField".equals(targetRec.exp.getMethodName())) {
- records.remove(obj);
+ objRecordMap.remove(obj);
}
Object args[] = rec.exp.getArguments();
for (int i = 0; i < args.length; i++) {
- Record argRec = (Record) records.get(args[i]);
+ Record argRec = objRecordMap.get(args[i]);
if (argRec != null) {
preprocess(args[i], argRec);
}
@@ -736,10 +714,10 @@ public class XMLEncoder extends Encoder
for (Iterator<?> iter = rec.stats.iterator(); iter.hasNext();) {
Statement subStat = (Statement) iter.next();
- if (subStat instanceof Expression) {
+ if (subStat.getClass() == Expression.class) {
try {
Expression subExp = (Expression) subStat;
- Record subRec = (Record) records.get(subExp.getValue());
+ Record subRec = objRecordMap.get(subExp.getValue());
if (subRec == null || subRec.exp == null
|| subRec.exp != subExp) {
iter.remove();
@@ -764,7 +742,7 @@ public class XMLEncoder extends Encoder
Object subStatArgs[] = subStat.getArguments();
for (int i = 0; i < subStatArgs.length; i++) {
- Record argRec = (Record) records.get(subStatArgs[i]);
+ Record argRec = objRecordMap.get(subStatArgs[i]);
if (argRec != null) {
preprocess(subStatArgs[i], argRec);
}
@@ -774,24 +752,18 @@ public class XMLEncoder extends Encoder
private void recordExpression(Object value, Expression exp) {
// record how a new object is created or obtained
- Record rec = (Record) records.get(value);
+ Record rec = objRecordMap.get(value);
if (rec == null) {
rec = new Record();
- records.put(value, rec);
+ objRecordMap.put(value, rec);
}
if (rec.exp == null) {
- // it is generated by its sub stats
- for (Iterator<?> iter = rec.stats.iterator(); iter.hasNext();) {
- Statement stat = (Statement) iter.next();
- try {
- if (stat instanceof Expression) {
- flushPrePending.add(value);
- }
- } catch (Exception e) {
- e.printStackTrace();
+ // it is generated by its sub statements
+ for (Statement statement : rec.stats) {
+ if (statement.getClass() == Expression.class) {
+ flushPrePending.add(value);
}
-
}
}
@@ -807,18 +779,19 @@ public class XMLEncoder extends Encoder
}
private void recordStatement(Statement stat) {
- if (null == stat)
+ if (null == stat) {
return;
+ }
// deal with 'owner' property
if (stat.getTarget() == owner && owner != null) {
needOwner = true;
}
// record how a statement affects the target object
- Record rec = (Record) records.get(stat.getTarget());
+ Record rec = objRecordMap.get(stat.getTarget());
if (rec == null) {
rec = new Record();
- records.put(stat.getTarget(), rec);
+ objRecordMap.put(stat.getTarget(), rec);
}
rec.stats.add(stat);
}
@@ -837,7 +810,7 @@ public class XMLEncoder extends Encoder
Object obj = value;
while (obj != null) {
- Record rec = (Record) records.get(obj);
+ Record rec = objRecordMap.get(obj);
if (rec != null && rec.exp != null) {
obj = rec.exp.getTarget();
@@ -881,26 +854,16 @@ public class XMLEncoder extends Encoder
boolean oldWritingObject = writingObject;
writingObject = true;
// get expression value
- Object oldValue = null;
-
- try {
- oldValue = oldExp.getValue();
- } catch (Exception e) {
- getExceptionListener().exceptionThrown(
- new Exception("failed to execute expression: " //$NON-NLS-1$
- + oldExp, e));
- return;
- }
-
+ Object oldValue = expressionValue(oldExp);
// check existence
- if (get(oldValue) != null
- && (!(oldValue instanceof String) || oldWritingObject)) {
+ if (oldValue == null || get(oldValue) != null
+ && (oldWritingObject || oldValue.getClass() != String.class)) {
return;
}
// record how the object is obtained
if (!isBasicType(oldValue)
- || (oldValue instanceof String && !oldWritingObject)) {
+ || (!oldWritingObject && oldValue.getClass() == String.class)) {
recordExpression(oldValue, oldExp);
}
@@ -908,7 +871,6 @@ public class XMLEncoder extends Encoder
if (checkDeadLoop(oldValue)) {
return;
}
-
super.writeExpression(oldExp);
writingObject = oldWritingObject;
}
@@ -917,12 +879,10 @@ public class XMLEncoder extends Encoder
* Records the object so that it can be written out later, then calls super
* implementation.
*/
- @SuppressWarnings("unchecked")
@Override
public void writeObject(Object o) {
synchronized (this) {
- ArrayList<Object> prePending = (ArrayList<Object>) objPrePendingCache
- .get(o);
+ ArrayList<Object> prePending = objPrePendingCache.get(o);
if (prePending == null) {
boolean oldWritingObject = writingObject;
writingObject = true;
@@ -976,9 +936,9 @@ public class XMLEncoder extends Encoder
System.err.println("Continuing...");
return;
}
+
// record how the object is changed
recordStatement(oldStat);
-
super.writeStatement(oldStat);
}
}
\ No newline at end of file
Propchange: harmony/enhanced/java/branches/java6/drlvm/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Sep 29 17:00:09 2010
@@ -1,5 +1,5 @@
/harmony/enhanced/java/branches/mrh/drlvm:935751-941490
-/harmony/enhanced/java/trunk/drlvm:929253-997624,997759,997980,997986,998010,998030,998619,998628,998759,998804,998822,999260,999286,999306,999591,999601,999623,999715-999716,999724,999793,1000005,1000169,1000213,1000229,1000231,1000233,1000240,1000245,1000248,1000265,1000527,1000689,1000696,1000699-1000700,1000705,1000708,1001065,1001080,1001153,1001187,1001490,1001609,1001638,1001652,1001723,1001741,1001744-1001745,1001751,1002080,1002189,1002476,1002480,1002488,1002506
+/harmony/enhanced/java/trunk/drlvm:929253-997624,997759,997980,997986,998010,998030,998619,998628,998759,998804,998822,999260,999286,999306,999591,999601,999623,999715-999716,999724,999793,1000005,1000169,1000213,1000229,1000231,1000233,1000240,1000245,1000248,1000265,1000527,1000689,1000696,1000699-1000700,1000705,1000708,1001065,1001080,1001153,1001187,1001490,1001609,1001638,1001652,1001723,1001741,1001744-1001745,1001751,1002080,1002189,1002476,1002480,1002488,1002506,1002511
/harmony/enhanced/trunk/drlvm:476395-929252
/harmony/enhanced/trunk/working_vm:476396-920147
/incubator/harmony/enhanced/trunk/drlvm:292550-476394
Propchange: harmony/enhanced/java/branches/java6/jdktools/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Sep 29 17:00:09 2010
@@ -1,4 +1,4 @@
-/harmony/enhanced/java/trunk/jdktools:929253-997624,997759,997980,997986,998010,998030,998619,998628,998759,998804,998822,999260,999286,999306,999591,999601,999623,999715-999716,999724,999793,1000005,1000169,1000213,1000229,1000231,1000233,1000240,1000245,1000248,1000265,1000527,1000689,1000696,1000699-1000700,1000705,1000708,1001065,1001080,1001153,1001187,1001490,1001609,1001638,1001652,1001723,1001741,1001744-1001745,1001751,1002080,1002189,1002476,1002480,1002488,1002506
+/harmony/enhanced/java/trunk/jdktools:929253-997624,997759,997980,997986,998010,998030,998619,998628,998759,998804,998822,999260,999286,999306,999591,999601,999623,999715-999716,999724,999793,1000005,1000169,1000213,1000229,1000231,1000233,1000240,1000245,1000248,1000265,1000527,1000689,1000696,1000699-1000700,1000705,1000708,1001065,1001080,1001153,1001187,1001490,1001609,1001638,1001652,1001723,1001741,1001744-1001745,1001751,1002080,1002189,1002476,1002480,1002488,1002506,1002511
/harmony/enhanced/jdktools/trunk:630107-925933
/harmony/enhanced/trunk/jdktools:476395-929252
/harmony/enhanced/trunk/working_jdktools:476396-920147
Re: svn commit: r1002734 - in /harmony/enhanced/java/branches/java6:
./ classlib/ classlib/depends/libs/ classlib/modules/beans/src/main/java/java/beans/
drlvm/ jdktools/
Posted by Kevin Zhou <zh...@gmail.com>.
On 2010-9-30 1:00, hindessm@apache.org wrote:
> Author: hindessm
> Date: Wed Sep 29 17:00:09 2010
> New Revision: 1002734
>
> URL: http://svn.apache.org/viewvc?rev=1002734&view=rev
> Log:
> Merge change from trunk@1002511:
>
> r1002511 | zhoukevin | 2010-09-29 09:10:27 +0100 (Wed, 29 Sep 2010) | 1 line
>
> Apply the patch for HARMONY-6664: Poor performance of
> java.beans.XMLEncoder.writeObject() method. This reduce the time of
> writing a list of 25000 integers from 30 seconds to 3 seconds, improve
> the performance of XMLEncoder.writeObject() to some extent.
>
> Removed:
> harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/ReferenceMap.java
> Modified:
> harmony/enhanced/java/branches/java6/ (props changed)
> harmony/enhanced/java/branches/java6/classlib/ (props changed)
> harmony/enhanced/java/branches/java6/classlib/depends/libs/ (props changed)
> harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/DefaultPersistenceDelegate.java
> harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/Encoder.java
> harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/PersistenceDelegate.java
> harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/XMLEncoder.java
> harmony/enhanced/java/branches/java6/drlvm/ (props changed)
> harmony/enhanced/java/branches/java6/jdktools/ (props changed)
>
> Propchange: harmony/enhanced/java/branches/java6/
> ------------------------------------------------------------------------------
> --- svn:mergeinfo (original)
> +++ svn:mergeinfo Wed Sep 29 17:00:09 2010
> @@ -1,4 +1,4 @@
> /harmony/enhanced/java/branches/mrh:935751-941490
> -/harmony/enhanced/java/trunk:929253-997624,997759,997980,997986,998010,998030,998619,998628,998759,998804,998822,999260,999286,999306,999591,999601,999623,999715-999716,999724,999793,1000005,1000169,1000213,1000229,1000231,1000233,1000240,1000245,1000248,1000265,1000527,1000689,1000696,1000699-1000700,1000705,1000708,1001065,1001080,1001153,1001187,1001490,1001609,1001638,1001652,1001723,1001741,1001744-1001745,1001751,1002080,1002189,1002476,1002480,1002488,1002506
> +/harmony/enhanced/java/trunk:929253-997624,997759,997980,997986,998010,998030,998619,998628,998759,998804,998822,999260,999286,999306,999591,999601,999623,999715-999716,999724,999793,1000005,1000169,1000213,1000229,1000231,1000233,1000240,1000245,1000248,1000265,1000527,1000689,1000696,1000699-1000700,1000705,1000708,1001065,1001080,1001153,1001187,1001490,1001609,1001638,1001652,1001723,1001741,1001744-1001745,1001751,1002080,1002189,1002476,1002480,1002488,1002506,1002511
> /harmony/enhanced/trunk:476395-929252
> /incubator/harmony/enhanced/trunk:292550-476394
>
> Propchange: harmony/enhanced/java/branches/java6/classlib/
> ------------------------------------------------------------------------------
> --- svn:mergeinfo (original)
> +++ svn:mergeinfo Wed Sep 29 17:00:09 2010
> @@ -1,7 +1,7 @@
> /harmony/enhanced/classlib/trunk:713674-735919,765923-926091,926318-926838
> /harmony/enhanced/classlib/trunk/working_classlib:884014-884286
> /harmony/enhanced/java/branches/mrh/classlib:935751-941490
> -/harmony/enhanced/java/trunk/classlib:929253-997624,997759,997980,997986,998010,998030,998619,998628,998759,998804,998822,999260,999286,999306,999591,999601,999623,999715-999716,999724,999793,1000005,1000169,1000213,1000229,1000231,1000233,1000240,1000245,1000248,1000265,1000527,1000689,1000696,1000699-1000700,1000705,1000708,1001065,1001080,1001153,1001187,1001490,1001609,1001638,1001652,1001723,1001741,1001744-1001745,1001751,1002080,1002189,1002476,1002480,1002488,1002506
> +/harmony/enhanced/java/trunk/classlib:929253-997624,997759,997980,997986,998010,998030,998619,998628,998759,998804,998822,999260,999286,999306,999591,999601,999623,999715-999716,999724,999793,1000005,1000169,1000213,1000229,1000231,1000233,1000240,1000245,1000248,1000265,1000527,1000689,1000696,1000699-1000700,1000705,1000708,1001065,1001080,1001153,1001187,1001490,1001609,1001638,1001652,1001723,1001741,1001744-1001745,1001751,1002080,1002189,1002476,1002480,1002488,1002506,1002511
> /harmony/enhanced/trunk/classlib:476395-929252
> /harmony/enhanced/trunk/working_classlib:476396-920147
> /incubator/harmony/enhanced/trunk/classlib:292550-476394
>
> Propchange: harmony/enhanced/java/branches/java6/classlib/depends/libs/
> ------------------------------------------------------------------------------
> --- svn:mergeinfo (original)
> +++ svn:mergeinfo Wed Sep 29 17:00:09 2010
> @@ -1,4 +1,4 @@
> /harmony/enhanced/classlib/trunk/depends/libs:544451-926091
> -/harmony/enhanced/java/trunk/classlib/depends/libs:929253-997624,997759,997980,997986,998010,998030,998619,998628,998759,998804,998822,999260,999286,999306,999591,999601,999623,999715-999716,999724,999793,1000005,1000169,1000213,1000229,1000231,1000233,1000240,1000245,1000248,1000265,1000527,1000689,1000696,1000699-1000700,1000705,1000708,1001065,1001080,1001153,1001187,1001490,1001609,1001638,1001652,1001723,1001741,1001744-1001745,1001751,1002080,1002189,1002476,1002480,1002488,1002506
> +/harmony/enhanced/java/trunk/classlib/depends/libs:929253-997624,997759,997980,997986,998010,998030,998619,998628,998759,998804,998822,999260,999286,999306,999591,999601,999623,999715-999716,999724,999793,1000005,1000169,1000213,1000229,1000231,1000233,1000240,1000245,1000248,1000265,1000527,1000689,1000696,1000699-1000700,1000705,1000708,1001065,1001080,1001153,1001187,1001490,1001609,1001638,1001652,1001723,1001741,1001744-1001745,1001751,1002080,1002189,1002476,1002480,1002488,1002506,1002511
> /harmony/enhanced/trunk/classlib/depends/libs:476395-929252
> /incubator/harmony/enhanced/trunk/classlib/depends/libs:292550-476394
>
> Modified: harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/DefaultPersistenceDelegate.java
> URL: http://svn.apache.org/viewvc/harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/DefaultPersistenceDelegate.java?rev=1002734&r1=1002733&r2=1002734&view=diff
> ==============================================================================
> --- harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/DefaultPersistenceDelegate.java (original)
> +++ harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/DefaultPersistenceDelegate.java Wed Sep 29 17:00:09 2010
> @@ -115,22 +115,23 @@ public class DefaultPersistenceDelegate
> return;
> }
> PropertyDescriptor[] pds = info.getPropertyDescriptors();
> -
> + Method getter, setter;
> // Initialize each found non-transient property
> for (int i = 0; i< pds.length; i++) {
> // Skip a property whose transient attribute is true
> if (Boolean.TRUE.equals(pds[i].getValue("transient"))) { //$NON-NLS-1$
> continue;
> }
> + getter = pds[i].getReadMethod();
> + setter = pds[i].getWriteMethod();
> // Skip a property having no setter or getter
> - if (null == pds[i].getWriteMethod()
> - || null == pds[i].getReadMethod()) {
> + if (getter == null || setter == null) {
> continue;
> }
>
> // Get the value of the property in the old instance
> - Expression getterExp = new Expression(oldInstance, pds[i]
> - .getReadMethod().getName(), null);
> + Expression getterExp = new Expression(oldInstance,
> + getter.getName(), null);
> try {
> // Calculate the old value of the property
> Object oldVal = getterExp.getValue();
> @@ -138,30 +139,14 @@ public class DefaultPersistenceDelegate
> enc.writeExpression(getterExp);
> // Get the target value that exists in the new environment
> Object targetVal = enc.get(oldVal);
> - // Get the current property value in the new environment
> - Object newVal = new Expression(newInstance, pds[i]
> - .getReadMethod().getName(), null).getValue();
> - /*
> - * Make the target value and current property value equivalent
> - * in the new environment
> - */
> - if (null == targetVal) {
> - if (null != newVal) {
> - // Set to null
> - Statement setterStm = new Statement(oldInstance, pds[i]
> - .getWriteMethod().getName(),
> - new Object[] { null });
> - enc.writeStatement(setterStm);
> - }
> - } else {
> - PersistenceDelegate pd = enc
> - .getPersistenceDelegate(targetVal.getClass());
> - if (!pd.mutatesTo(targetVal, newVal)) {
> - Statement setterStm = new Statement(oldInstance, pds[i]
> - .getWriteMethod().getName(),
> - new Object[] { oldVal });
> - enc.writeStatement(setterStm);
> - }
> + Object newVal = new Expression(newInstance, getter.getName(),
> + null).getValue();
> + boolean invokeSetter = targetVal == null ? (newVal != null&& oldVal == null)
> + : !enc.getPersistenceDelegate(targetVal.getClass())
> + .mutatesTo(targetVal, newVal);
> + if (invokeSetter) {
> + enc.writeStatement(new Statement(oldInstance, setter
> + .getName(), new Object[] { oldVal }));
> }
> } catch (Exception ex) {
> enc.getExceptionListener().exceptionThrown(ex);
>
> Modified: harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/Encoder.java
> URL: http://svn.apache.org/viewvc/harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/Encoder.java?rev=1002734&r1=1002733&r2=1002734&view=diff
> ==============================================================================
> --- harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/Encoder.java (original)
> +++ harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/Encoder.java Wed Sep 29 17:00:09 2010
> @@ -40,6 +40,7 @@ import java.lang.reflect.Proxy;
> import java.util.Collection;
> import java.util.Date;
> import java.util.Hashtable;
> +import java.util.IdentityHashMap;
> import java.util.Map;
>
> import javax.swing.Box;
> @@ -49,16 +50,16 @@ import javax.swing.JTabbedPane;
> import javax.swing.ToolTipManager;
>
> /**
> - * The<code>Encoder</code>, together with<code>PersistenceDelegate</code>
> - * s, can encode an object into a series of java statements. By executing these
> + * The<code>Encoder</code>, together with<code>PersistenceDelegate</code> s,
> + * can encode an object into a series of java statements. By executing these
> * statements, a new object can be created and it will has the same state as the
> * original object which has been passed to the encoder. Here "has the same
> * state" means the two objects are indistinguishable from their public API.
> *<p>
> - * The<code>Encoder</code> and<code>PersistenceDelegate</code> s do this
> - * by creating copies of the input object and all objects it references. The
> - * copy process continues recursively util every object in the object graph has
> - * its new copy and the new version has the same state as the old version. All
> + * The<code>Encoder</code> and<code>PersistenceDelegate</code> s do this by
> + * creating copies of the input object and all objects it references. The copy
> + * process continues recursively util every object in the object graph has its
> + * new copy and the new version has the same state as the old version. All
> * statements used to create those new objects and executed on them during the
> * process form the result of encoding.
> *</p>
> @@ -110,7 +111,7 @@ public class Encoder {
>
> private ExceptionListener listener = defaultExListener;
>
> - private ReferenceMap oldNewMap = new ReferenceMap();
> + private IdentityHashMap<Object, Object> oldNewMap = new IdentityHashMap<Object, Object>();
>
> private static volatile boolean isInitilizedAWT;
>
> @@ -143,7 +144,7 @@ public class Encoder {
> * one.
> */
> public Object get(Object old) {
> - if (old == null || old instanceof String) {
> + if (old == null || old.getClass() == String.class) {
> return old;
> }
> return oldNewMap.get(old);
> @@ -167,15 +168,14 @@ public class Encoder {
> *<p>
> * The<code>PersistenceDelegate</code> is determined as following:
> *<ol>
> - *<li>If a<code>PersistenceDelegate</code> has been registered by
> - * calling<code>setPersistenceDelegate</code> for the given type, it is
> - * returned.</li>
> + *<li>If a<code>PersistenceDelegate</code> has been registered by calling
> + *<code>setPersistenceDelegate</code> for the given type, it is returned.</li>
> *<li>If the given type is an array class, a special
> *<code>PersistenceDelegate</code> for array types is returned.</li>
> *<li>If the given type is a proxy class, a special
> *<code>PersistenceDelegate</code> for proxy classes is returned.</li>
> - *<li><code>Introspector</code> is used to check the bean descriptor
> - * value "persistenceDelegate". If one is set, it is returned.</li>
> + *<li><code>Introspector</code> is used to check the bean descriptor value
> + * "persistenceDelegate". If one is set, it is returned.</li>
> *<li>If none of the above applies, the
> *<code>DefaultPersistenceDelegate</code> is returned.</li>
> *</ol>
> @@ -329,27 +329,40 @@ public class Encoder {
> delegates.put(type, delegate);
> }
>
> - private Object forceNew(Object old) {
> - if (old == null) {
> + Object expressionValue(Expression exp) {
> + try {
> + return exp == null ? null : exp.getValue();
> + } catch (IndexOutOfBoundsException e) {
> return null;
> + } catch (Exception e) {
> + listener.exceptionThrown(new Exception(
> + "failed to excute expression: " + exp, e)); //$NON-NLS-1$
> }
> - Object nu = get(old);
> - if (nu != null) {
> - return nu;
> - }
> - writeObject(old);
> - return get(old);
> + return null;
> }
>
> - private Object[] forceNewArray(Object[] oldArray) {
> - if (oldArray == null) {
> - return null;
> + private Statement createNewStatement(Statement oldStat) {
> + Object newTarget = createNewObject(oldStat.getTarget());
> + Object[] oldArgs = oldStat.getArguments();
> + Object[] newArgs = new Object[oldArgs.length];
> + for (int index = 0; index< oldArgs.length; index++) {
> + newArgs[index] = createNewObject(oldArgs[index]);
> }
> - Object newArray[] = new Object[oldArray.length];
> - for (int i = 0; i< oldArray.length; i++) {
> - newArray[i] = forceNew(oldArray[i]);
> +
> + if (oldStat.getClass() == Expression.class) {
> + return new Expression(newTarget, oldStat.getMethodName(), newArgs);
> + } else {
> + return new Statement(newTarget, oldStat.getMethodName(), newArgs);
> }
> - return newArray;
> + }
> +
> + private Object createNewObject(Object old) {
> + Object nu = get(old);
> + if (nu == null) {
> + writeObject(old);
> + nu = get(old);
> + }
> + return nu;
> }
>
> /**
> @@ -382,30 +395,21 @@ public class Encoder {
> throw new NullPointerException();
> }
> try {
> - // if oldValue exists, noop
> - Object oldValue = oldExp.getValue();
> + // if oldValue exists, no operation
> + Object oldValue = expressionValue(oldExp);
> if (oldValue == null || get(oldValue) != null) {
> return;
> }
>
> // copy to newExp
> - Object newTarget = forceNew(oldExp.getTarget());
> - Object newArgs[] = forceNewArray(oldExp.getArguments());
> - Expression newExp = new Expression(newTarget, oldExp
> - .getMethodName(), newArgs);
> -
> - // execute newExp
> - Object newValue = null;
> + Expression newExp = (Expression) createNewStatement(oldExp);
> + // relate oldValue to newValue
> try {
> - newValue = newExp.getValue();
> - } catch (IndexOutOfBoundsException ex) {
> - // Current Container does not have any component, newVal set
> - // to null
> + oldNewMap.put(oldValue, newExp.getValue());
> + } catch (IndexOutOfBoundsException e) {
> + // container does not have any component, set newVal null
> }
>
> - // relate oldValue to newValue
> - put(oldValue, newValue);
> -
> // force same state
> writeObject(oldValue);
> } catch (Exception e) {
> @@ -450,13 +454,8 @@ public class Encoder {
> if (oldStat == null) {
> throw new NullPointerException();
> }
> + Statement newStat = createNewStatement(oldStat);
> try {
> - // copy to newStat
> - Object newTarget = forceNew(oldStat.getTarget());
> - Object newArgs[] = forceNewArray(oldStat.getArguments());
> - Statement newStat = new Statement(newTarget, oldStat
> - .getMethodName(), newArgs);
> -
> // execute newStat
> newStat.execute();
> } catch (Exception e) {
> @@ -464,5 +463,4 @@ public class Encoder {
> "failed to write statement: " + oldStat, e)); //$NON-NLS-1$
> }
> }
> -
> -}
> +}
> \ No newline at end of file
>
> Modified: harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/PersistenceDelegate.java
> URL: http://svn.apache.org/viewvc/harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/PersistenceDelegate.java?rev=1002734&r1=1002733&r2=1002734&view=diff
> ==============================================================================
> --- harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/PersistenceDelegate.java (original)
> +++ harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/PersistenceDelegate.java Wed Sep 29 17:00:09 2010
> @@ -90,10 +90,7 @@ public abstract class PersistenceDelegat
> * false
> */
> protected boolean mutatesTo(Object o1, Object o2) {
> - if (null == o1 || null == o2 ) {
> - return false;
> - }
> - return o1.getClass() == o2.getClass();
> + return null != o1&& null != o2&& o1.getClass() == o2.getClass();
> }
>
> /**
> @@ -112,20 +109,16 @@ public abstract class PersistenceDelegat
> */
> public void writeObject(Object oldInstance, Encoder out) {
> Object newInstance = out.get(oldInstance);
> + Class<?> clazz = oldInstance.getClass();
> if (mutatesTo(oldInstance, newInstance)) {
> - initialize(oldInstance.getClass(), oldInstance, newInstance, out);
> + initialize(clazz, oldInstance, newInstance, out);
> } else {
> out.remove(oldInstance);
> - Expression exp = instantiate(oldInstance, out);
> - out.writeExpression(exp);
> + out.writeExpression(instantiate(oldInstance, out));
> newInstance = out.get(oldInstance);
> -
> if (newInstance != null) {
> - initialize(oldInstance.getClass(), oldInstance,
> - newInstance, out);
> + initialize(clazz, oldInstance, newInstance, out);
> }
> }
> }
> -
> -}
> -
> +}
> \ No newline at end of file
>
> Modified: harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/XMLEncoder.java
> URL: http://svn.apache.org/viewvc/harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/XMLEncoder.java?rev=1002734&r1=1002733&r2=1002734&view=diff
> ==============================================================================
> --- harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/XMLEncoder.java (original)
> +++ harmony/enhanced/java/branches/java6/classlib/modules/beans/src/main/java/java/beans/XMLEncoder.java Wed Sep 29 17:00:09 2010
> @@ -27,6 +27,7 @@ import java.lang.reflect.Modifier;
> import java.lang.reflect.Proxy;
> import java.util.ArrayList;
> import java.util.Collections;
> +import java.util.IdentityHashMap;
> import java.util.Iterator;
> import java.util.List;
>
> @@ -44,6 +45,8 @@ import org.apache.harmony.beans.internal
> */
> public class XMLEncoder extends Encoder {
>
> + private static final String DEFAULT_ENCODING = "UTF-8"; //$NON-NLS-1$
> +
> private static int DEADLOCK_THRESHOLD = 7;
>
> /*
> @@ -92,11 +95,11 @@ public class XMLEncoder extends Encoder
>
> private Object owner = null;
>
> - private ReferenceMap records = new ReferenceMap();
> + private IdentityHashMap<Object, Record> objRecordMap = new IdentityHashMap<Object, Record>();
>
> - private ReferenceMap objPrePendingCache = new ReferenceMap();
> + private IdentityHashMap<Class<?>, Integer> clazzCounterMap = new IdentityHashMap<Class<?>, Integer>();
>
> - private ReferenceMap clazzCounterMap = new ReferenceMap();
> + private IdentityHashMap<Object, ArrayList<Object>> objPrePendingCache = new IdentityHashMap<Object, ArrayList<Object>>();
>
> private boolean writingObject = false;
>
> @@ -109,11 +112,10 @@ public class XMLEncoder extends Encoder
> public XMLEncoder(OutputStream out) {
> if (null != out) {
> try {
> - this.out = new PrintWriter(
> - new OutputStreamWriter(out, "UTF-8"), true); //$NON-NLS-1$
> + this.out = new PrintWriter(new OutputStreamWriter(out,
> + DEFAULT_ENCODING), true);
> } catch (UnsupportedEncodingException e) {
> - // never occur
> - e.printStackTrace();
> + // should never occur
> }
> }
> }
> @@ -166,7 +168,7 @@ public class XMLEncoder extends Encoder
> for (Iterator<Object> iter = flushPending.iterator(); iter
> .hasNext();) {
> Object o = iter.next();
> - Record rec = (Record) records.get(o);
> + Record rec = objRecordMap.get(o);
> if (rec != null) {
> preprocess(o, rec);
> }
> @@ -182,7 +184,7 @@ public class XMLEncoder extends Encoder
> }
>
> // clear statement records
> - records.clear();
> + objRecordMap.clear();
> flushPendingStat.clear();
> objPrePendingCache.clear();
> clazzCounterMap.clear();
> @@ -201,54 +203,33 @@ public class XMLEncoder extends Encoder
> if (obj == null) {
> out.println("<null />");
> } else if (obj instanceof String) {
> - Record rec = (Record) records.get(obj);
> + Record rec = objRecordMap.get(obj);
> if (null != rec) {
> - if (flushPendingStat.contains(obj)) {
> - flushExpression(obj, rec, indent - 3, true);
> - } else {
> - flushExpression(obj, rec, indent - 3, false);
> - }
> + flushExpression(obj, rec, indent - 3,
> + flushPendingStat.contains(obj));
> return;
> }
> out.print("<string>");
> flushString((String) obj);
> out.println("</string>");
> } else if (obj instanceof Class<?>) {
> - out.print("<class>");
> - out.print(((Class<?>) obj).getName());
> - out.println("</class>");
> + out.println("<class>" + ((Class<?>) obj).getName() + "</class>");
> } else if (obj instanceof Boolean) {
> - out.print("<boolean>");
> - out.print(obj);
> - out.println("</boolean>");
> + out.println("<boolean>" + obj +"</boolean>");
> } else if (obj instanceof Byte) {
> - out.print("<byte>");
> - out.print(obj);
> - out.println("</byte>");
> + out.println("<byte>" + obj +"</byte>");
> } else if (obj instanceof Character) {
> - out.print("<char>");
> - out.print(obj);
> - out.println("</char>");
> + out.println("<char>" + obj +"</char>");
> } else if (obj instanceof Double) {
> - out.print("<double>");
> - out.print(obj);
> - out.println("</double>");
> + out.println("<double>" + obj +"</double>");
> } else if (obj instanceof Float) {
> - out.print("<float>");
> - out.print(obj);
> - out.println("</float>");
> + out.println("<float>" + obj +"</float>");
> } else if (obj instanceof Integer) {
> - out.print("<int>");
> - out.print(obj);
> - out.println("</int>");
> + out.println("<int>" + obj +"</int>");
> } else if (obj instanceof Long) {
> - out.print("<long>");
> - out.print(obj);
> - out.println("</long>");
> + out.println("<long>" + obj +"</long>");
> } else if (obj instanceof Short) {
> - out.print("<short>");
> - out.print(obj);
> - out.println("</short>");
> + out.println("<short>" + obj +"</short>");
> } else {
> getExceptionListener().exceptionThrown(
> new Exception(Messages.getString("beans.73", obj)));
> @@ -287,14 +268,15 @@ public class XMLEncoder extends Encoder
>
> private void flushIndent(int indent) {
> for (int i = 0; i< indent; i++) {
> - out.print(" "); //$NON-NLS-1$
> + out.print(' ');
> }
> }
>
> private void flushObject(Object obj, int indent) {
> - Record rec = (Record) records.get(obj);
> - if (rec == null&& !isBasicType(obj))
> + Record rec = objRecordMap.get(obj);
> + if (rec == null&& !isBasicType(obj)) {
> return;
> + }
>
> if (obj == owner&& this.needOwner) {
> flushOwner(obj, rec, indent);
> @@ -305,11 +287,7 @@ public class XMLEncoder extends Encoder
> if (isBasicType(obj)) {
> flushBasicObject(obj, indent);
> } else {
> - if (flushPendingStat.contains(obj)) {
> - flushExpression(obj, rec, indent, true);
> - } else {
> - flushExpression(obj, rec, indent, false);
> - }
> + flushExpression(obj, rec, indent, flushPendingStat.contains(obj));
> }
> }
>
> @@ -451,7 +429,7 @@ public class XMLEncoder extends Encoder
> Object args[] = stat.getArguments();
>
> // special case for array
> - if (Array.class == target&& "newInstance".equals(method)) {
> + if (Array.class == target&& BeansUtils.NEWINSTANCE.equals(method)) {
> flushStatArray(stat, id, subStats, indent);
> return;
> }
> @@ -643,10 +621,10 @@ public class XMLEncoder extends Encoder
> for (int i = 0; i< subStats.size(); i++) {
> Statement subStat = (Statement) subStats.get(i);
> try {
> - if (subStat instanceof Expression) {
> + if (subStat.getClass() == Expression.class) {
> Expression subExp = (Expression) subStat;
> Object obj = subExp.getValue();
> - Record rec = (Record) records.get(obj);
> + Record rec = objRecordMap.get(obj);
> flushExpression(obj, rec, indent + INDENT_UNIT, true);
> } else {
> flushStatement(subStat, null, Collections.EMPTY_LIST,
> @@ -678,21 +656,21 @@ public class XMLEncoder extends Encoder
> }
>
> private boolean isGetArrayStat(Object target, String method, Object[] args) {
> - return ("get".equals(method)&& args.length == 1 //$NON-NLS-1$
> + return (BeansUtils.GET.equals(method)&& args.length == 1
> && args[0] instanceof Integer&& target.getClass().isArray());
> }
>
> private boolean isGetPropertyStat(String method, Object[] args) {
> - return (method.startsWith("get")&& method.length()> 3&& args.length == 0); //$NON-NLS-1$
> + return (method.startsWith(BeansUtils.GET)&& method.length()> 3&& args.length == 0);
> }
>
> private boolean isSetArrayStat(Object target, String method, Object[] args) {
> - return ("set".equals(method)&& args.length == 2 //$NON-NLS-1$
> + return (BeansUtils.SET.equals(method)&& args.length == 2
> && args[0] instanceof Integer&& target.getClass().isArray());
> }
>
> private boolean isSetPropertyStat(String method, Object[] args) {
> - return (method.startsWith("set")&& method.length()> 3&& args.length == 1); //$NON-NLS-1$
> + return (method.startsWith(BeansUtils.SET)&& method.length()> 3&& args.length == 1);
> }
>
> /*
> @@ -719,15 +697,15 @@ public class XMLEncoder extends Encoder
> // do it recursively
> if (null != rec.exp) {
> // deal with 'field' property
> - Record targetRec = (Record) records.get(rec.exp.getTarget());
> + Record targetRec = objRecordMap.get(rec.exp.getTarget());
> if (targetRec != null&& targetRec.exp != null
> && "getField".equals(targetRec.exp.getMethodName())) {
> - records.remove(obj);
> + objRecordMap.remove(obj);
> }
>
> Object args[] = rec.exp.getArguments();
> for (int i = 0; i< args.length; i++) {
> - Record argRec = (Record) records.get(args[i]);
> + Record argRec = objRecordMap.get(args[i]);
> if (argRec != null) {
> preprocess(args[i], argRec);
> }
> @@ -736,10 +714,10 @@ public class XMLEncoder extends Encoder
>
> for (Iterator<?> iter = rec.stats.iterator(); iter.hasNext();) {
> Statement subStat = (Statement) iter.next();
> - if (subStat instanceof Expression) {
> + if (subStat.getClass() == Expression.class) {
> try {
> Expression subExp = (Expression) subStat;
> - Record subRec = (Record) records.get(subExp.getValue());
> + Record subRec = objRecordMap.get(subExp.getValue());
> if (subRec == null || subRec.exp == null
> || subRec.exp != subExp) {
> iter.remove();
> @@ -764,7 +742,7 @@ public class XMLEncoder extends Encoder
>
> Object subStatArgs[] = subStat.getArguments();
> for (int i = 0; i< subStatArgs.length; i++) {
> - Record argRec = (Record) records.get(subStatArgs[i]);
> + Record argRec = objRecordMap.get(subStatArgs[i]);
> if (argRec != null) {
> preprocess(subStatArgs[i], argRec);
> }
> @@ -774,24 +752,18 @@ public class XMLEncoder extends Encoder
>
> private void recordExpression(Object value, Expression exp) {
> // record how a new object is created or obtained
> - Record rec = (Record) records.get(value);
> + Record rec = objRecordMap.get(value);
> if (rec == null) {
> rec = new Record();
> - records.put(value, rec);
> + objRecordMap.put(value, rec);
> }
>
> if (rec.exp == null) {
> - // it is generated by its sub stats
> - for (Iterator<?> iter = rec.stats.iterator(); iter.hasNext();) {
> - Statement stat = (Statement) iter.next();
> - try {
> - if (stat instanceof Expression) {
> - flushPrePending.add(value);
> - }
> - } catch (Exception e) {
> - e.printStackTrace();
> + // it is generated by its sub statements
> + for (Statement statement : rec.stats) {
> + if (statement.getClass() == Expression.class) {
> + flushPrePending.add(value);
> }
> -
> }
> }
>
> @@ -807,18 +779,19 @@ public class XMLEncoder extends Encoder
> }
>
> private void recordStatement(Statement stat) {
> - if (null == stat)
> + if (null == stat) {
> return;
> + }
> // deal with 'owner' property
> if (stat.getTarget() == owner&& owner != null) {
> needOwner = true;
> }
>
> // record how a statement affects the target object
> - Record rec = (Record) records.get(stat.getTarget());
> + Record rec = objRecordMap.get(stat.getTarget());
> if (rec == null) {
> rec = new Record();
> - records.put(stat.getTarget(), rec);
> + objRecordMap.put(stat.getTarget(), rec);
> }
> rec.stats.add(stat);
> }
> @@ -837,7 +810,7 @@ public class XMLEncoder extends Encoder
> Object obj = value;
>
> while (obj != null) {
> - Record rec = (Record) records.get(obj);
> + Record rec = objRecordMap.get(obj);
>
> if (rec != null&& rec.exp != null) {
> obj = rec.exp.getTarget();
> @@ -881,26 +854,16 @@ public class XMLEncoder extends Encoder
> boolean oldWritingObject = writingObject;
> writingObject = true;
> // get expression value
> - Object oldValue = null;
> -
> - try {
> - oldValue = oldExp.getValue();
> - } catch (Exception e) {
> - getExceptionListener().exceptionThrown(
> - new Exception("failed to execute expression: " //$NON-NLS-1$
> - + oldExp, e));
> - return;
> - }
> -
> + Object oldValue = expressionValue(oldExp);
> // check existence
> - if (get(oldValue) != null
> -&& (!(oldValue instanceof String) || oldWritingObject)) {
> + if (oldValue == null || get(oldValue) != null
> +&& (oldWritingObject || oldValue.getClass() != String.class)) {
> return;
> }
>
> // record how the object is obtained
> if (!isBasicType(oldValue)
> - || (oldValue instanceof String&& !oldWritingObject)) {
> + || (!oldWritingObject&& oldValue.getClass() == String.class)) {
> recordExpression(oldValue, oldExp);
> }
>
> @@ -908,7 +871,6 @@ public class XMLEncoder extends Encoder
> if (checkDeadLoop(oldValue)) {
> return;
> }
> -
> super.writeExpression(oldExp);
> writingObject = oldWritingObject;
> }
> @@ -917,12 +879,10 @@ public class XMLEncoder extends Encoder
> * Records the object so that it can be written out later, then calls super
> * implementation.
> */
> - @SuppressWarnings("unchecked")
> @Override
> public void writeObject(Object o) {
> synchronized (this) {
> - ArrayList<Object> prePending = (ArrayList<Object>) objPrePendingCache
> - .get(o);
> + ArrayList<Object> prePending = objPrePendingCache.get(o);
> if (prePending == null) {
> boolean oldWritingObject = writingObject;
> writingObject = true;
> @@ -976,9 +936,9 @@ public class XMLEncoder extends Encoder
> System.err.println("Continuing...");
> return;
> }
> +
> // record how the object is changed
> recordStatement(oldStat);
> -
> super.writeStatement(oldStat);
> }
> }
> \ No newline at end of file
>
> Propchange: harmony/enhanced/java/branches/java6/drlvm/
> ------------------------------------------------------------------------------
> --- svn:mergeinfo (original)
> +++ svn:mergeinfo Wed Sep 29 17:00:09 2010
> @@ -1,5 +1,5 @@
> /harmony/enhanced/java/branches/mrh/drlvm:935751-941490
> -/harmony/enhanced/java/trunk/drlvm:929253-997624,997759,997980,997986,998010,998030,998619,998628,998759,998804,998822,999260,999286,999306,999591,999601,999623,999715-999716,999724,999793,1000005,1000169,1000213,1000229,1000231,1000233,1000240,1000245,1000248,1000265,1000527,1000689,1000696,1000699-1000700,1000705,1000708,1001065,1001080,1001153,1001187,1001490,1001609,1001638,1001652,1001723,1001741,1001744-1001745,1001751,1002080,1002189,1002476,1002480,1002488,1002506
> +/harmony/enhanced/java/trunk/drlvm:929253-997624,997759,997980,997986,998010,998030,998619,998628,998759,998804,998822,999260,999286,999306,999591,999601,999623,999715-999716,999724,999793,1000005,1000169,1000213,1000229,1000231,1000233,1000240,1000245,1000248,1000265,1000527,1000689,1000696,1000699-1000700,1000705,1000708,1001065,1001080,1001153,1001187,1001490,1001609,1001638,1001652,1001723,1001741,1001744-1001745,1001751,1002080,1002189,1002476,1002480,1002488,1002506,1002511
> /harmony/enhanced/trunk/drlvm:476395-929252
> /harmony/enhanced/trunk/working_vm:476396-920147
> /incubator/harmony/enhanced/trunk/drlvm:292550-476394
>
> Propchange: harmony/enhanced/java/branches/java6/jdktools/
> ------------------------------------------------------------------------------
> --- svn:mergeinfo (original)
> +++ svn:mergeinfo Wed Sep 29 17:00:09 2010
> @@ -1,4 +1,4 @@
> -/harmony/enhanced/java/trunk/jdktools:929253-997624,997759,997980,997986,998010,998030,998619,998628,998759,998804,998822,999260,999286,999306,999591,999601,999623,999715-999716,999724,999793,1000005,1000169,1000213,1000229,1000231,1000233,1000240,1000245,1000248,1000265,1000527,1000689,1000696,1000699-1000700,1000705,1000708,1001065,1001080,1001153,1001187,1001490,1001609,1001638,1001652,1001723,1001741,1001744-1001745,1001751,1002080,1002189,1002476,1002480,1002488,1002506
> +/harmony/enhanced/java/trunk/jdktools:929253-997624,997759,997980,997986,998010,998030,998619,998628,998759,998804,998822,999260,999286,999306,999591,999601,999623,999715-999716,999724,999793,1000005,1000169,1000213,1000229,1000231,1000233,1000240,1000245,1000248,1000265,1000527,1000689,1000696,1000699-1000700,1000705,1000708,1001065,1001080,1001153,1001187,1001490,1001609,1001638,1001652,1001723,1001741,1001744-1001745,1001751,1002080,1002189,1002476,1002480,1002488,1002506,1002511
> /harmony/enhanced/jdktools/trunk:630107-925933
> /harmony/enhanced/trunk/jdktools:476395-929252
> /harmony/enhanced/trunk/working_jdktools:476396-920147
>
>
Thanks, Mark. This merge is good. Moreover, I add one more refinement to
java.beans.Encoder class at r1002929, no functional changes.