Merge changes up to trunk@1022963.
git-svn-id: https://svn.apache.org/repos/asf/harmony/enhanced/java/branches/mrh@1023369 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/classlib/modules/beans/main/java/java/beans/UtilCollectionsPersistenceDelegate.java b/classlib/modules/beans/main/java/java/beans/UtilCollectionsPersistenceDelegate.java
new file mode 100644
index 0000000..3390e11
--- /dev/null
+++ b/classlib/modules/beans/main/java/java/beans/UtilCollectionsPersistenceDelegate.java
@@ -0,0 +1,208 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.beans;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import org.apache.harmony.beans.BeansUtils;
+
+public class UtilCollectionsPersistenceDelegate extends PersistenceDelegate {
+
+ static String CLASS_PREFIX = "java.util.Collections$"; //$NON-NLS-1$
+
+ private static final String COLLECTIONS_TYPE = "type"; //$NON-NLS-1$
+
+ private static final String MAP_KEY_TYPE = "keyType"; //$NON-NLS-1$
+
+ private static final String MAP_VALUE_TYPE = "valueType"; //$NON-NLS-1$
+
+ protected boolean mutatesTo(Object o1, Object o2) {
+ if (BeansUtils.declaredEquals(o1.getClass())) {
+ return o1.equals(o2);
+ }
+ if (o1 instanceof Collection<?>) {
+ Collection<?> c1 = (Collection<?>) o1;
+ Collection<?> c2 = (Collection<?>) o2;
+ return c1.size() == c2.size() && c1.containsAll(c2);
+ }
+ if (o1 instanceof Map<?, ?>) {
+ Map<?, ?> m1 = (Map<?, ?>) o1;
+ Map<?, ?> m2 = (Map<?, ?>) o2;
+ return m1.size() == m2.size()
+ && m1.entrySet().containsAll(m2.entrySet());
+ }
+ return super.mutatesTo(o1, o2);
+ }
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ @Override
+ protected Expression instantiate(Object oldInstance, Encoder enc) {
+ String className = oldInstance.getClass().getName();
+ if (className.endsWith("UnmodifiableCollection")) { //$NON-NLS-1$
+ // Collections.unmodifiableCollection(Collection);
+ return new Expression(oldInstance, Collections.class,
+ "unmodifiableCollection", new Object[] { new ArrayList( //$NON-NLS-1$
+ (Collection) oldInstance) });
+ } else if (className.endsWith("UnmodifiableList")) { //$NON-NLS-1$
+ // Collections.unmodifiableList(List);
+ return new Expression(oldInstance, Collections.class,
+ "unmodifiableList", new Object[] { new LinkedList(
+ (Collection) oldInstance) });
+ } else if (className.endsWith("UnmodifiableRandomAccessList")) { //$NON-NLS-1$
+ // Collections.unmodifiableList(List);
+ return new Expression(oldInstance, Collections.class,
+ "unmodifiableList", new Object[] { new ArrayList( //$NON-NLS-1$
+ (Collection) oldInstance) });
+ } else if (className.endsWith("UnmodifiableSet")) { //$NON-NLS-1$
+ // Collections.unmodifiableSet(Set);
+ return new Expression(oldInstance, Collections.class,
+ "unmodifiableSet", new Object[] { new HashSet( //$NON-NLS-1$
+ (Set) oldInstance) });
+ } else if (className.endsWith("UnmodifiableSortedSet")) { //$NON-NLS-1$
+ // Collections.unmodifiableSortedSet(set)
+ return new Expression(oldInstance, Collections.class,
+ "unmodifiableSortedSet", new Object[] { new TreeSet( //$NON-NLS-1$
+ (SortedSet) oldInstance) });
+ } else if (className.endsWith("UnmodifiableMap")) { //$NON-NLS-1$
+ return new Expression(oldInstance, Collections.class,
+ "unmodifiableMap", new Object[] { new HashMap( //$NON-NLS-1$
+ (Map) oldInstance) });
+ } else if (className.endsWith("UnmodifiableSortedMap")) { //$NON-NLS-1$
+ // Collections.unmodifiableSortedMap(SortedMap);
+ return new Expression(oldInstance, Collections.class,
+ "unmodifiableSortedMap", new Object[] { new TreeMap( //$NON-NLS-1$
+ (Map) oldInstance) });
+ } else if (className.endsWith("SynchronizedCollection")) { //$NON-NLS-1$
+ // Collections.synchronizedCollection(Collection);
+ return new Expression(oldInstance, Collections.class,
+ "synchronizedCollection", new Object[] { new ArrayList( //$NON-NLS-1$
+ (Collection) oldInstance) });
+ } else if (className.endsWith("SynchronizedList")) { //$NON-NLS-1$
+ // Collections.synchronizedList(List);
+ return new Expression(oldInstance, Collections.class,
+ "synchronizedList", new Object[] { new LinkedList( //$NON-NLS-1$
+ (List) oldInstance) });
+ } else if (className.endsWith("SynchronizedRandomAccessList")) { //$NON-NLS-1$
+ // Collections.synchronizedList(List);
+ return new Expression(oldInstance, Collections.class,
+ "synchronizedList", new Object[] { new ArrayList( //$NON-NLS-1$
+ (List) oldInstance) });
+ } else if (className.endsWith("SynchronizedSet")) { //$NON-NLS-1$
+ // Collections.synchronizedSet(Set);
+ return new Expression(oldInstance, Collections.class,
+ "synchronizedSet", new Object[] { new HashSet( //$NON-NLS-1$
+ (Set) oldInstance) });
+ } else if (className.endsWith("SynchronizedSortedSet")) { //$NON-NLS-1$
+ // Collections.synchronizedSortedSet(SortedSet);
+ return new Expression(oldInstance, Collections.class,
+ "synchronizedSortedSet", new Object[] { new TreeSet( //$NON-NLS-1$
+ (SortedSet) oldInstance) });
+ } else if (className.endsWith("SynchronizedMap")) { //$NON-NLS-1$
+ // Collections.synchronizedMap(Map);
+ return new Expression(oldInstance, Collections.class,
+ "synchronizedMap", new Object[] { new HashMap( //$NON-NLS-1$
+ (Map) oldInstance) });
+ } else if (className.endsWith("SynchronizedSortedMap")) { //$NON-NLS-1$
+ // Collections.synchronizedSortedMap(SortedMap)
+ return new Expression(oldInstance, Collections.class,
+ "synchronizedSortedMap", new Object[] { new TreeMap( //$NON-NLS-1$
+ (SortedMap) oldInstance) });
+ } else if (className.endsWith("CheckedCollection")) { //$NON-NLS-1$
+ // Collections.checkedCollection(Collection, Class);
+ return new Expression(oldInstance, Collections.class,
+ "checkedCollection", new Object[] { //$NON-NLS-1$
+ new ArrayList((Collection) oldInstance),
+ valueOfField(oldInstance, COLLECTIONS_TYPE) });
+ } else if (className.endsWith("CheckedList")) { //$NON-NLS-1$
+ // Collections.checkedList(List, Class);
+ return new Expression(oldInstance, Collections.class,
+ "checkedList", new Object[] {
+ new LinkedList((Collection) oldInstance),
+ valueOfField(oldInstance, COLLECTIONS_TYPE) });
+ } else if (className.endsWith("CheckedRandomAccessList")) { //$NON-NLS-1$
+ // Collections.checkedList(List, Class);
+ return new Expression(oldInstance, Collections.class,
+ "checkedList", new Object[] { //$NON-NLS-1$
+ new ArrayList((Collection) oldInstance),
+ valueOfField(oldInstance, COLLECTIONS_TYPE) });
+ } else if (className.endsWith("CheckedSet")) { //$NON-NLS-1$
+ // Collections.checkedSet(Set, Class);
+ return new Expression(oldInstance, Collections.class, "checkedSet", //$NON-NLS-1$
+ new Object[] { new HashSet((Set) oldInstance),
+ valueOfField(oldInstance, COLLECTIONS_TYPE) });
+ } else if (className.endsWith("CheckedSortedSet")) { //$NON-NLS-1$
+ // Collections.checkedSortedSet(SortedSet, Class);
+ return new Expression(oldInstance, Collections.class,
+ "checkedSortedSet", new Object[] { //$NON-NLS-1$
+ new TreeSet((Set) oldInstance),
+ valueOfField(oldInstance, COLLECTIONS_TYPE) });
+ } else if (className.endsWith("CheckedMap")) { //$NON-NLS-1$
+ // Collections.checkedMap(Map, keyType, valueType);
+ return new Expression(oldInstance, Collections.class, "checkedMap", //$NON-NLS-1$
+ new Object[] { new HashMap((Map) oldInstance),
+ valueOfField(oldInstance, MAP_KEY_TYPE),
+ valueOfField(oldInstance, MAP_VALUE_TYPE) });
+ } else if (className.endsWith("CheckedSortedMap")) { //$NON-NLS-1$
+ // Collections.checkedSortedMap(SortedMap, keyType, valueType);
+ return new Expression(oldInstance, Collections.class,
+ "checkedSortedMap", new Object[] { //$NON-NLS-1$
+ new TreeMap((Map) oldInstance),
+ valueOfField(oldInstance, MAP_KEY_TYPE),
+ valueOfField(oldInstance, MAP_VALUE_TYPE) });
+ }
+ return null;
+ }
+
+ private static Object valueOfField(Object obj, String fieldName) {
+ Class<?> clazz = obj.getClass();
+ Field field = null;
+ while (clazz != null) {
+ for (Field declaredField : clazz.getDeclaredFields()) {
+ if (fieldName.equals(declaredField.getName())) {
+ field = declaredField;
+ break;
+ }
+ }
+ clazz = clazz.getSuperclass();
+ }
+ if (field != null) {
+ if (!field.isAccessible()) {
+ field.setAccessible(true);
+ }
+ try {
+ return field.get(obj);
+ } catch (Exception e) {
+ // Ignored
+ }
+ }
+ return null;
+ }
+}
diff --git a/classlib/modules/beans/src/main/java/java/beans/DefaultPersistenceDelegate.java b/classlib/modules/beans/src/main/java/java/beans/DefaultPersistenceDelegate.java
index bd43dac..556664f 100644
--- a/classlib/modules/beans/src/main/java/java/beans/DefaultPersistenceDelegate.java
+++ b/classlib/modules/beans/src/main/java/java/beans/DefaultPersistenceDelegate.java
@@ -141,10 +141,8 @@
Object targetVal = enc.get(oldVal);
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) {
+ if (targetVal == null ? (newVal != null && oldVal == null)
+ : targetVal != newVal && !targetVal.equals(newVal)) {
enc.writeStatement(new Statement(oldInstance, setter
.getName(), new Object[] { oldVal }));
}
diff --git a/classlib/modules/beans/src/main/java/java/beans/Encoder.java b/classlib/modules/beans/src/main/java/java/beans/Encoder.java
index e00bfb1..98d5d1a 100644
--- a/classlib/modules/beans/src/main/java/java/beans/Encoder.java
+++ b/classlib/modules/beans/src/main/java/java/beans/Encoder.java
@@ -71,6 +71,8 @@
private static final DefaultPersistenceDelegate defaultPD = new DefaultPersistenceDelegate();
+ private static final UtilCollectionsPersistenceDelegate utilCollectionsPD = new UtilCollectionsPersistenceDelegate();
+
private static final ArrayPersistenceDelegate arrayPD = new ArrayPersistenceDelegate();
private static final ProxyPersistenceDelegate proxyPD = new ProxyPersistenceDelegate();
@@ -136,6 +138,19 @@
delegates.put(ScrollPane.class, new AwtScrollPanePersistenceDelegate());
delegates.put(Date.class, new UtilDatePersistenceDelegate());
+
+ PersistenceDelegate pd = new UtilListPersistenceDelegate();
+ delegates.put(java.util.List.class, pd);
+ delegates.put(java.util.AbstractList.class, pd);
+
+ pd = new UtilCollectionPersistenceDelegate();
+ delegates.put(java.util.Collection.class, pd);
+ delegates.put(java.util.AbstractCollection.class, pd);
+
+ pd = new UtilMapPersistenceDelegate();
+ delegates.put(java.util.Map.class, pd);
+ delegates.put(java.util.AbstractMap.class, pd);
+ delegates.put(java.util.Hashtable.class, pd);
}
private ExceptionListener listener = defaultExListener;
@@ -221,16 +236,9 @@
return registeredPD;
}
- if (java.util.List.class.isAssignableFrom(type)) {
- return new UtilListPersistenceDelegate();
- }
-
- if (Collection.class.isAssignableFrom(type)) {
- return new UtilCollectionPersistenceDelegate();
- }
-
- if (Map.class.isAssignableFrom(type)) {
- return new UtilMapPersistenceDelegate();
+ if (type.getName().startsWith(
+ UtilCollectionsPersistenceDelegate.CLASS_PREFIX)) {
+ return utilCollectionsPD;
}
if (type.isArray()) {
diff --git a/classlib/modules/beans/src/main/java/java/beans/UtilCollectionsPersistenceDelegate.java b/classlib/modules/beans/src/main/java/java/beans/UtilCollectionsPersistenceDelegate.java
new file mode 100644
index 0000000..a8fef58
--- /dev/null
+++ b/classlib/modules/beans/src/main/java/java/beans/UtilCollectionsPersistenceDelegate.java
@@ -0,0 +1,208 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.beans;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import org.apache.harmony.beans.BeansUtils;
+
+class UtilCollectionsPersistenceDelegate extends PersistenceDelegate {
+
+ static String CLASS_PREFIX = "java.util.Collections$"; //$NON-NLS-1$
+
+ private static final String COLLECTIONS_TYPE = "type"; //$NON-NLS-1$
+
+ private static final String MAP_KEY_TYPE = "keyType"; //$NON-NLS-1$
+
+ private static final String MAP_VALUE_TYPE = "valueType"; //$NON-NLS-1$
+
+ protected boolean mutatesTo(Object o1, Object o2) {
+ if (BeansUtils.declaredEquals(o1.getClass())) {
+ return o1.equals(o2);
+ }
+ if (o1 instanceof Collection<?>) {
+ Collection<?> c1 = (Collection<?>) o1;
+ Collection<?> c2 = (Collection<?>) o2;
+ return c1.size() == c2.size() && c1.containsAll(c2);
+ }
+ if (o1 instanceof Map<?, ?>) {
+ Map<?, ?> m1 = (Map<?, ?>) o1;
+ Map<?, ?> m2 = (Map<?, ?>) o2;
+ return m1.size() == m2.size()
+ && m1.entrySet().containsAll(m2.entrySet());
+ }
+ return super.mutatesTo(o1, o2);
+ }
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ @Override
+ protected Expression instantiate(Object oldInstance, Encoder enc) {
+ String className = oldInstance.getClass().getName();
+ if (className.endsWith("UnmodifiableCollection")) { //$NON-NLS-1$
+ // Collections.unmodifiableCollection(Collection);
+ return new Expression(oldInstance, Collections.class,
+ "unmodifiableCollection", new Object[] { new ArrayList( //$NON-NLS-1$
+ (Collection) oldInstance) });
+ } else if (className.endsWith("UnmodifiableList")) { //$NON-NLS-1$
+ // Collections.unmodifiableList(List);
+ return new Expression(oldInstance, Collections.class,
+ "unmodifiableList", new Object[] { new LinkedList(
+ (Collection) oldInstance) });
+ } else if (className.endsWith("UnmodifiableRandomAccessList")) { //$NON-NLS-1$
+ // Collections.unmodifiableList(List);
+ return new Expression(oldInstance, Collections.class,
+ "unmodifiableList", new Object[] { new ArrayList( //$NON-NLS-1$
+ (Collection) oldInstance) });
+ } else if (className.endsWith("UnmodifiableSet")) { //$NON-NLS-1$
+ // Collections.unmodifiableSet(Set);
+ return new Expression(oldInstance, Collections.class,
+ "unmodifiableSet", new Object[] { new HashSet( //$NON-NLS-1$
+ (Set) oldInstance) });
+ } else if (className.endsWith("UnmodifiableSortedSet")) { //$NON-NLS-1$
+ // Collections.unmodifiableSortedSet(set)
+ return new Expression(oldInstance, Collections.class,
+ "unmodifiableSortedSet", new Object[] { new TreeSet( //$NON-NLS-1$
+ (SortedSet) oldInstance) });
+ } else if (className.endsWith("UnmodifiableMap")) { //$NON-NLS-1$
+ return new Expression(oldInstance, Collections.class,
+ "unmodifiableMap", new Object[] { new HashMap( //$NON-NLS-1$
+ (Map) oldInstance) });
+ } else if (className.endsWith("UnmodifiableSortedMap")) { //$NON-NLS-1$
+ // Collections.unmodifiableSortedMap(SortedMap);
+ return new Expression(oldInstance, Collections.class,
+ "unmodifiableSortedMap", new Object[] { new TreeMap( //$NON-NLS-1$
+ (Map) oldInstance) });
+ } else if (className.endsWith("SynchronizedCollection")) { //$NON-NLS-1$
+ // Collections.synchronizedCollection(Collection);
+ return new Expression(oldInstance, Collections.class,
+ "synchronizedCollection", new Object[] { new ArrayList( //$NON-NLS-1$
+ (Collection) oldInstance) });
+ } else if (className.endsWith("SynchronizedList")) { //$NON-NLS-1$
+ // Collections.synchronizedList(List);
+ return new Expression(oldInstance, Collections.class,
+ "synchronizedList", new Object[] { new LinkedList( //$NON-NLS-1$
+ (List) oldInstance) });
+ } else if (className.endsWith("SynchronizedRandomAccessList")) { //$NON-NLS-1$
+ // Collections.synchronizedList(List);
+ return new Expression(oldInstance, Collections.class,
+ "synchronizedList", new Object[] { new ArrayList( //$NON-NLS-1$
+ (List) oldInstance) });
+ } else if (className.endsWith("SynchronizedSet")) { //$NON-NLS-1$
+ // Collections.synchronizedSet(Set);
+ return new Expression(oldInstance, Collections.class,
+ "synchronizedSet", new Object[] { new HashSet( //$NON-NLS-1$
+ (Set) oldInstance) });
+ } else if (className.endsWith("SynchronizedSortedSet")) { //$NON-NLS-1$
+ // Collections.synchronizedSortedSet(SortedSet);
+ return new Expression(oldInstance, Collections.class,
+ "synchronizedSortedSet", new Object[] { new TreeSet( //$NON-NLS-1$
+ (SortedSet) oldInstance) });
+ } else if (className.endsWith("SynchronizedMap")) { //$NON-NLS-1$
+ // Collections.synchronizedMap(Map);
+ return new Expression(oldInstance, Collections.class,
+ "synchronizedMap", new Object[] { new HashMap( //$NON-NLS-1$
+ (Map) oldInstance) });
+ } else if (className.endsWith("SynchronizedSortedMap")) { //$NON-NLS-1$
+ // Collections.synchronizedSortedMap(SortedMap)
+ return new Expression(oldInstance, Collections.class,
+ "synchronizedSortedMap", new Object[] { new TreeMap( //$NON-NLS-1$
+ (SortedMap) oldInstance) });
+ } else if (className.endsWith("CheckedCollection")) { //$NON-NLS-1$
+ // Collections.checkedCollection(Collection, Class);
+ return new Expression(oldInstance, Collections.class,
+ "checkedCollection", new Object[] { //$NON-NLS-1$
+ new ArrayList((Collection) oldInstance),
+ valueOfField(oldInstance, COLLECTIONS_TYPE) });
+ } else if (className.endsWith("CheckedList")) { //$NON-NLS-1$
+ // Collections.checkedList(List, Class);
+ return new Expression(oldInstance, Collections.class,
+ "checkedList", new Object[] {
+ new LinkedList((Collection) oldInstance),
+ valueOfField(oldInstance, COLLECTIONS_TYPE) });
+ } else if (className.endsWith("CheckedRandomAccessList")) { //$NON-NLS-1$
+ // Collections.checkedList(List, Class);
+ return new Expression(oldInstance, Collections.class,
+ "checkedList", new Object[] { //$NON-NLS-1$
+ new ArrayList((Collection) oldInstance),
+ valueOfField(oldInstance, COLLECTIONS_TYPE) });
+ } else if (className.endsWith("CheckedSet")) { //$NON-NLS-1$
+ // Collections.checkedSet(Set, Class);
+ return new Expression(oldInstance, Collections.class, "checkedSet", //$NON-NLS-1$
+ new Object[] { new HashSet((Set) oldInstance),
+ valueOfField(oldInstance, COLLECTIONS_TYPE) });
+ } else if (className.endsWith("CheckedSortedSet")) { //$NON-NLS-1$
+ // Collections.checkedSortedSet(SortedSet, Class);
+ return new Expression(oldInstance, Collections.class,
+ "checkedSortedSet", new Object[] { //$NON-NLS-1$
+ new TreeSet((Set) oldInstance),
+ valueOfField(oldInstance, COLLECTIONS_TYPE) });
+ } else if (className.endsWith("CheckedMap")) { //$NON-NLS-1$
+ // Collections.checkedMap(Map, keyType, valueType);
+ return new Expression(oldInstance, Collections.class, "checkedMap", //$NON-NLS-1$
+ new Object[] { new HashMap((Map) oldInstance),
+ valueOfField(oldInstance, MAP_KEY_TYPE),
+ valueOfField(oldInstance, MAP_VALUE_TYPE) });
+ } else if (className.endsWith("CheckedSortedMap")) { //$NON-NLS-1$
+ // Collections.checkedSortedMap(SortedMap, keyType, valueType);
+ return new Expression(oldInstance, Collections.class,
+ "checkedSortedMap", new Object[] { //$NON-NLS-1$
+ new TreeMap((Map) oldInstance),
+ valueOfField(oldInstance, MAP_KEY_TYPE),
+ valueOfField(oldInstance, MAP_VALUE_TYPE) });
+ }
+ return null;
+ }
+
+ private static Object valueOfField(Object obj, String fieldName) {
+ Class<?> clazz = obj.getClass();
+ Field field = null;
+ while (clazz != null) {
+ for (Field declaredField : clazz.getDeclaredFields()) {
+ if (fieldName.equals(declaredField.getName())) {
+ field = declaredField;
+ break;
+ }
+ }
+ clazz = clazz.getSuperclass();
+ }
+ if (field != null) {
+ if (!field.isAccessible()) {
+ field.setAccessible(true);
+ }
+ try {
+ return field.get(obj);
+ } catch (Exception e) {
+ // Ignored
+ }
+ }
+ return null;
+ }
+}
diff --git a/classlib/modules/beans/src/main/java/java/beans/XMLDecoder.java b/classlib/modules/beans/src/main/java/java/beans/XMLDecoder.java
index 4ccae80..2b2c6bc 100644
--- a/classlib/modules/beans/src/main/java/java/beans/XMLDecoder.java
+++ b/classlib/modules/beans/src/main/java/java/beans/XMLDecoder.java
@@ -111,6 +111,7 @@
elem.isExpression = true;
elem.id = attributes.getValue("id");
elem.idref = attributes.getValue("idref");
+ elem.attributes = attributes;
if (elem.idref == null) {
obtainTarget(elem, attributes);
obtainMethod(elem, attributes);
@@ -201,6 +202,7 @@
Elem elem = new Elem();
elem.isExpression = true;
elem.id = attributes.getValue("id"); //$NON-NLS-1$
+ elem.attributes = attributes;
try {
// find component class
Class<?> compClass = classForName(attributes.getValue("class")); //$NON-NLS-1$
@@ -230,6 +232,7 @@
private void startVoidElem(Attributes attributes) {
Elem elem = new Elem();
elem.id = attributes.getValue("id");
+ elem.attributes = attributes;
obtainTarget(elem, attributes);
obtainMethod(elem, attributes);
readObjs.push(elem);
@@ -242,6 +245,7 @@
elem.isExpression = true;
elem.id = attributes.getValue("id");
elem.idref = attributes.getValue("idref");
+ elem.attributes = attributes;
elem.target = tagName;
readObjs.push(elem);
}
@@ -258,6 +262,21 @@
}
// find the elem to close
Elem toClose = latestUnclosedElem();
+ if ("string".equals(toClose.target)) {
+ StringBuilder sb = new StringBuilder();
+ for (int index = readObjs.size() - 1; index >= 0; index--) {
+ Elem elem = (Elem) readObjs.get(index);
+ if (toClose == elem) {
+ break;
+ }
+ if ("char".equals(elem.target)) {
+ sb.insert(0, elem.methodName);
+ }
+ }
+ toClose.methodName = toClose.methodName != null ? toClose.methodName
+ + sb.toString()
+ : sb.toString();
+ }
// make sure it is executed
execute(toClose);
// set to closed
@@ -465,6 +484,15 @@
} else if ("byte".equals(tag)) {
return Byte.valueOf(value);
} else if ("char".equals(tag)) {
+ if (value == null && elem.attributes != null) {
+ String codeAttr = elem.attributes.getValue("code");
+ if (codeAttr != null) {
+ Character character = new Character((char) Integer
+ .valueOf(codeAttr.substring(1), 16).intValue());
+ elem.methodName = character.toString();
+ return character;
+ }
+ }
return Character.valueOf(value.charAt(0));
} else if ("double".equals(tag)) {
return Double.valueOf(value);
@@ -522,6 +550,8 @@
boolean fromOwner;
+ Attributes attributes;
+
Object result;
}
diff --git a/classlib/modules/beans/src/main/java/java/beans/XMLEncoder.java b/classlib/modules/beans/src/main/java/java/beans/XMLEncoder.java
index c17d2bd..9b16ad5 100644
--- a/classlib/modules/beans/src/main/java/java/beans/XMLEncoder.java
+++ b/classlib/modules/beans/src/main/java/java/beans/XMLEncoder.java
@@ -126,7 +126,7 @@
*/
public void close() {
flush();
- out.println("</java>"); //$NON-NLS-1$
+ out.println("</java> "); //$NON-NLS-1$
out.close();
}
@@ -136,15 +136,6 @@
return buf;
}
- private String idSerialNoOfObject(Object obj) {
- Class<?> clazz = obj.getClass();
- Integer serialNo = (Integer) clazzCounterMap.get(clazz);
- serialNo = serialNo == null ? 0 : serialNo;
- String id = BeansUtils.idOfClass(obj.getClass()) + serialNo;
- clazzCounterMap.put(clazz, ++serialNo);
- return id;
- }
-
/**
* Writes out all objects since last flush to the output stream.
* <p>
@@ -157,10 +148,10 @@
synchronized (this) {
// write xml header
if (!hasXmlHeader) {
- out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+ out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?> ");
out.println("<java version=\""
+ System.getProperty("java.version")
- + "\" class=\"java.beans.XMLDecoder\">");
+ + "\" class=\"java.beans.XMLDecoder\"> ");
hasXmlHeader = true;
}
@@ -201,7 +192,7 @@
}
flushIndent(indent);
if (obj == null) {
- out.println("<null />");
+ out.println("<null /> ");
} else if (obj instanceof String) {
Record rec = objRecordMap.get(obj);
if (null != rec) {
@@ -211,31 +202,42 @@
}
out.print("<string>");
flushString((String) obj);
- out.println("</string>");
+ out.println("</string> ");
} else if (obj instanceof Class<?>) {
- out.println("<class>" + ((Class<?>) obj).getName() + "</class>");
+ out.println("<class>" + ((Class<?>) obj).getName() + "</class> ");
} else if (obj instanceof Boolean) {
- out.println("<boolean>" + obj + "</boolean>");
+ out.println("<boolean>" + obj + "</boolean> ");
} else if (obj instanceof Byte) {
- out.println("<byte>" + obj + "</byte>");
+ out.println("<byte>" + obj + "</byte> ");
} else if (obj instanceof Character) {
- out.println("<char>" + obj + "</char>");
+ char objChar = ((Character) obj).charValue();
+ if (invalidCharacter(objChar)) {
+ out.println("<char code=\"#" + Integer.toString(objChar, 16)
+ + "\"/>");
+ } else {
+ out.println("<char>" + objChar + "</char> ");
+ }
} else if (obj instanceof Double) {
- out.println("<double>" + obj + "</double>");
+ out.println("<double>" + obj + "</double> ");
} else if (obj instanceof Float) {
- out.println("<float>" + obj + "</float>");
+ out.println("<float>" + obj + "</float> ");
} else if (obj instanceof Integer) {
- out.println("<int>" + obj + "</int>");
+ out.println("<int>" + obj + "</int> ");
} else if (obj instanceof Long) {
- out.println("<long>" + obj + "</long>");
+ out.println("<long>" + obj + "</long> ");
} else if (obj instanceof Short) {
- out.println("<short>" + obj + "</short>");
+ out.println("<short>" + obj + "</short> ");
} else {
getExceptionListener().exceptionThrown(
new Exception(Messages.getString("beans.73", obj)));
}
}
+ private boolean invalidCharacter(char c) {
+ return ((0x0000 <= c && c < 0x0009) || (0x000a < c && c < 0x000d)
+ || (0x000d < c && c < 0x0020) || (0xd7ff < c && c < 0xe000) || c == 0xfffe);
+ }
+
@SuppressWarnings("nls")
private void flushExpression(Object obj, Record rec, int indent,
boolean asStatement) {
@@ -253,7 +255,7 @@
flushIndent(indent);
out.print("<object idref=\"");
out.print(rec.id);
- out.println("\" />");
+ out.println("\"/> ");
return;
}
@@ -313,10 +315,10 @@
// open tag, end
if (rec.exp.getArguments().length == 0 && rec.stats.isEmpty()) {
- out.println("/>");
+ out.println("/> ");
return;
}
- out.println(">");
+ out.println("> ");
// arguments
for (int i = 0; i < rec.exp.getArguments().length; i++) {
@@ -330,7 +332,7 @@
flushIndent(indent);
out.print("</");
out.print(tagName);
- out.println(">");
+ out.println("> ");
}
@SuppressWarnings("nls")
@@ -356,17 +358,17 @@
// open tag, end
if (subStats.isEmpty()) {
- out.println("/>");
+ out.println("/> ");
return;
}
- out.println(">");
+ out.println("> ");
// sub statements
flushSubStatements(subStats, indent);
// close tag
flushIndent(indent);
- out.println("</array>");
+ out.println("</array> ");
}
@SuppressWarnings("nls")
@@ -401,10 +403,10 @@
// open tag, end
if (stat.getArguments().length == 0 && subStats.isEmpty()) {
- out.println("/>");
+ out.println("/> ");
return;
}
- out.println(">");
+ out.println("> ");
// arguments
for (int i = 0; i < stat.getArguments().length; i++) {
@@ -418,7 +420,7 @@
flushIndent(indent);
out.print("</");
out.print(tagName);
- out.println(">");
+ out.println("> ");
}
@SuppressWarnings("nls")
@@ -484,15 +486,15 @@
out.print(" field=\"");
out.print(stat.getArguments()[0]);
out.print("\"");
- out.println("/>");
+ out.println("/> ");
} else {
out.print(" method=\"");
out.print(stat.getMethodName());
out.print("\"");
- out.println(">");
+ out.println("> ");
flushObject(stat.getArguments()[0], indent + INDENT_UNIT);
flushIndent(indent);
- out.println("</object>");
+ out.println("</object> ");
}
}
@@ -501,7 +503,7 @@
List<?> subStats, int indent) {
// open tag, begin
flushIndent(indent);
- String tagName = stat instanceof Expression ? "object" : "void";
+ String tagName = "void";
out.print("<");
out.print(tagName);
@@ -526,10 +528,10 @@
// open tag, end
if (stat.getArguments().length == 0 && subStats.isEmpty()) {
- out.println("/>");
+ out.println("/> ");
return;
}
- out.println(">");
+ out.println("> ");
// arguments
for (int i = 0; i < stat.getArguments().length; i++) {
@@ -543,7 +545,7 @@
flushIndent(indent);
out.print("</");
out.print(tagName);
- out.println(">");
+ out.println("> ");
}
@SuppressWarnings("nls")
@@ -576,10 +578,10 @@
// open tag, end
if (stat.getArguments().length == 1 && subStats.isEmpty()) {
- out.println("/>");
+ out.println("/> ");
return;
}
- out.println(">");
+ out.println("> ");
// arguments
for (int i = 1; i < stat.getArguments().length; i++) {
@@ -593,7 +595,7 @@
flushIndent(indent);
out.print("</");
out.print(tagName);
- out.println(">");
+ out.println("> ");
}
@SuppressWarnings("nls")
@@ -612,7 +614,12 @@
} else if (c == '"') {
out.print(""");
} else {
- out.print(c);
+ if (invalidCharacter(c)) {
+ out.print("<char code=\"#" + Integer.toString(c, 16)
+ + "\"/>");
+ } else {
+ out.print(c);
+ }
}
}
}
@@ -673,6 +680,15 @@
return (method.startsWith(BeansUtils.SET) && method.length() > 3 && args.length == 1);
}
+ private String idSerialNoOfObject(Object obj) {
+ Class<?> clazz = obj.getClass();
+ Integer serialNo = (Integer) clazzCounterMap.get(clazz);
+ serialNo = serialNo == null ? 0 : serialNo;
+ String id = BeansUtils.idOfClass(obj.getClass()) + serialNo;
+ clazzCounterMap.put(clazz, ++serialNo);
+ return id;
+ }
+
/*
* The preprocess removes unused statements and counts references of every
* object
@@ -783,17 +799,48 @@
return;
}
// deal with 'owner' property
- if (stat.getTarget() == owner && owner != null) {
+ Object target = stat.getTarget();
+ if (target == owner && owner != null) {
needOwner = true;
}
// record how a statement affects the target object
- Record rec = objRecordMap.get(stat.getTarget());
+ Record rec = objRecordMap.get(target);
if (rec == null) {
rec = new Record();
- objRecordMap.put(stat.getTarget(), rec);
+ objRecordMap.put(target, rec);
}
- rec.stats.add(stat);
+
+ boolean hasRecord = false;
+ String methodName = stat.getMethodName();
+ Object[] args = stat.getArguments();
+ if (isSetPropertyStat(methodName, args)
+ || isSetArrayStat(target, methodName, args)) {
+ for (Statement subStat : rec.stats) {
+ if (target == subStat.getTarget()
+ && methodName.equals(subStat.getMethodName())) {
+ Object[] subArgs = subStat.getArguments();
+ if (args.length == subArgs.length) {
+ boolean equals = true;
+ for (int index = 0; index < args.length; index++) {
+ if (getPersistenceDelegate(args[index].getClass())
+ .mutatesTo(args[index], subArgs[index])) {
+ continue;
+ }
+ equals = false;
+ break;
+ }
+ if (equals) {
+ hasRecord = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+ if (!hasRecord) {
+ rec.stats.add(stat);
+ }
}
/**
diff --git a/classlib/modules/beans/src/test/java/org/apache/harmony/beans/tests/java/beans/XMLEncoderTest.java b/classlib/modules/beans/src/test/java/org/apache/harmony/beans/tests/java/beans/XMLEncoderTest.java
index f772c49..98932fe 100644
--- a/classlib/modules/beans/src/test/java/org/apache/harmony/beans/tests/java/beans/XMLEncoderTest.java
+++ b/classlib/modules/beans/src/test/java/org/apache/harmony/beans/tests/java/beans/XMLEncoderTest.java
@@ -25,6 +25,7 @@
import java.beans.Expression;
import java.beans.PersistenceDelegate;
import java.beans.Statement;
+import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
@@ -35,10 +36,23 @@
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
import java.util.Map;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.SortedSet;
import java.util.TreeMap;
+import java.util.TreeSet;
import junit.framework.TestCase;
@@ -1022,4 +1036,883 @@
this.name = name;
}
}
+
+ public static class MockCharProperty {
+ private char property;
+
+ public char getProperty() {
+ return property;
+ }
+
+ public void setProperty(char property) {
+ this.property = property;
+ }
+
+ public boolean equals(Object obj) {
+ if (obj instanceof MockCharProperty) {
+ return ((MockCharProperty) obj).property == (this.property);
+ }
+ return false;
+ }
+ }
+
+ public void testMockCharProperty() {
+ MockCharProperty expectedObj = new MockCharProperty();
+ MockCharProperty actualObj;
+ ByteArrayOutputStream baos;
+ ByteArrayInputStream bais;
+ XMLEncoder xmlEncoder;
+ XMLDecoder xmlDecoder;
+ char ch;
+ for (int index = 1; index < 65536; index++) {
+ ch = (char) index;
+ if (invalidCharacter(ch)) {
+ expectedObj.setProperty(ch);
+ baos = new ByteArrayOutputStream();
+ xmlEncoder = new XMLEncoder(baos);
+ xmlEncoder.writeObject(expectedObj);
+ xmlEncoder.close();
+ assertTrue(baos.toString().contains("<char code=\"#"));
+
+ bais = new ByteArrayInputStream(baos.toByteArray());
+ xmlDecoder = new XMLDecoder(bais);
+ actualObj = (MockCharProperty) xmlDecoder.readObject();
+ xmlDecoder.close();
+ assertEquals(expectedObj, actualObj);
+ }
+ }
+ }
+
+ public static class MockStringProperty {
+ private String property;
+
+ public String getProperty() {
+ return property;
+ }
+
+ public void setProperty(String property) {
+ this.property = property;
+ }
+
+ public boolean equals(Object obj) {
+ if (obj instanceof MockStringProperty) {
+ return ((MockStringProperty) obj).property
+ .equals(this.property);
+ }
+ return false;
+ }
+ }
+
+ public void testMockStringProperty() {
+ MockStringProperty expectedObj = new MockStringProperty();
+ MockStringProperty actualObj;
+ ByteArrayOutputStream baos;
+ ByteArrayInputStream bais;
+ XMLEncoder xmlEncoder;
+ XMLDecoder xmlDecoder;
+ char ch;
+ for (int index = 0; index < 65536; index++) {
+ ch = (char) index;
+ if (invalidCharacter(ch)) {
+ expectedObj.setProperty(stringWithChar(ch));
+ baos = new ByteArrayOutputStream();
+ xmlEncoder = new XMLEncoder(baos);
+ xmlEncoder.writeObject(expectedObj);
+ xmlEncoder.close();
+ assertTrue(baos.toString().contains("<char code=\"#"));
+
+ bais = new ByteArrayInputStream(baos.toByteArray());
+ xmlDecoder = new XMLDecoder(bais);
+ actualObj = (MockStringProperty) xmlDecoder.readObject();
+ xmlDecoder.close();
+ assertEquals(expectedObj, actualObj);
+ }
+ }
+ }
+
+ private String stringWithChar(char character) {
+ return "a string with a " + character + " character";
+ }
+
+ private boolean invalidCharacter(char c) {
+ return ((0x0000 <= c && c < 0x0009) || (0x000a < c && c < 0x000d)
+ || (0x000d < c && c < 0x0020) || (0xd7ff < c && c < 0xe000) || c == 0xfffe);
+ }
+
+ public static class MockUnmodifiableCollection {
+
+ private Collection<String> property = new ArrayList<String>();
+
+ public Collection<String> getProperty() {
+ return Collections.unmodifiableCollection(property);
+ }
+
+ public void setProperty(Collection<String> set) {
+ property.clear();
+ property.addAll(set);
+ }
+ }
+
+ public void testWriteObject_MockUnmodifiableCollection() throws Exception {
+ MockUnmodifiableCollection mockCollections = new MockUnmodifiableCollection();
+ Class<?> propertyClass = mockCollections.getProperty().getClass();
+ assertEquals("java.util.Collections$UnmodifiableCollection",
+ propertyClass.getName());
+ assertSamePD(propertyClass);
+ mockCollections.setProperty(Arrays
+ .asList(new String[] { "A", "B", "C" }));
+ assertCodedXML(mockCollections, "/xml/MockUnmodifiableCollection.xml");
+ }
+
+ public static class MockUnmodifiableList {
+
+ private List<String> property = new LinkedList<String>();
+
+ public Collection<String> getProperty() {
+ return Collections.unmodifiableList(property);
+ }
+
+ public void setProperty(Collection<String> set) {
+ property.clear();
+ property.addAll(set);
+ }
+ }
+
+ public void testWriteObject_MockUnmodifiableList() throws Exception {
+ MockUnmodifiableList mockCollections = new MockUnmodifiableList();
+ Class<?> propertyClass = mockCollections.getProperty().getClass();
+ assertEquals("java.util.Collections$UnmodifiableList",
+ propertyClass.getName());
+ assertSamePD(propertyClass);
+ mockCollections.setProperty(Arrays
+ .asList(new String[] { "A", "B", "C" }));
+ assertCodedXML(mockCollections, "/xml/MockUnmodifiableList.xml");
+ }
+
+ public static class MockUnmodifiableRandomAccessList {
+
+ private List<String> property = new ArrayList<String>();
+
+ public Collection<String> getProperty() {
+ return Collections.unmodifiableList(property);
+ }
+
+ public void setProperty(Collection<String> set) {
+ property.clear();
+ property.addAll(set);
+ }
+ }
+
+ public void testWriteObject_MockUnmodifiableRandomAccessList()
+ throws Exception {
+ MockUnmodifiableRandomAccessList mockCollections = new MockUnmodifiableRandomAccessList();
+ Class<?> propertyClass = mockCollections.getProperty().getClass();
+ assertEquals("java.util.Collections$UnmodifiableRandomAccessList",
+ propertyClass.getName());
+ assertSamePD(propertyClass);
+ mockCollections.setProperty(Arrays
+ .asList(new String[] { "A", "B", "C" }));
+ assertCodedXML(mockCollections,
+ "/xml/MockUnmodifiableRandomAccessList.xml");
+ }
+
+ public static class MockUnmodifiableSet {
+
+ private Set<String> property = new HashSet<String>();
+
+ public Collection<String> getProperty() {
+ return Collections.unmodifiableSet(property);
+ }
+
+ public void setProperty(Collection<String> set) {
+ property.clear();
+ property.addAll(set);
+ }
+ }
+
+ public void testWriteObject_MockUnmodifiableSet() throws Exception {
+ MockUnmodifiableSet mockCollections = new MockUnmodifiableSet();
+ Class<?> propertyClass = mockCollections.getProperty().getClass();
+ assertEquals("java.util.Collections$UnmodifiableSet",
+ propertyClass.getName());
+ assertSamePD(propertyClass);
+ Set<String> prop = new HashSet<String>();
+ prop.add("A");
+ prop.add("B");
+ prop.add("C");
+ mockCollections.setProperty(prop);
+ assertCodedXML(mockCollections, "/xml/MockUnmodifiableSet.xml");
+ }
+
+ public static class MockUnmodifiableSortedSet {
+
+ private SortedSet<String> property = new TreeSet<String>();
+
+ public Collection<String> getProperty() {
+ return Collections.unmodifiableSortedSet(property);
+ }
+
+ public void setProperty(Collection<String> set) {
+ property.clear();
+ property.addAll(set);
+ }
+ }
+
+ public void testWriteObject_MockUnmodifiableSortedSet() throws Exception {
+ MockUnmodifiableSortedSet mockCollections = new MockUnmodifiableSortedSet();
+ Class<?> propertyClass = mockCollections.getProperty().getClass();
+ assertEquals("java.util.Collections$UnmodifiableSortedSet",
+ propertyClass.getName());
+ assertSamePD(propertyClass);
+ Set<String> prop = new HashSet<String>();
+ prop.add("A");
+ prop.add("B");
+ prop.add("C");
+ mockCollections.setProperty(prop);
+ assertCodedXML(mockCollections, "/xml/MockUnmodifiableSortedSet.xml");
+ }
+
+ public static class MockUnmodifiableMap {
+
+ private Map<String, String> property = new HashMap<String, String>();
+
+ public Map<String, String> getProperty() {
+ return Collections.unmodifiableMap(property);
+ }
+
+ public void setProperty(Map<String, String> prop) {
+ property.clear();
+ property.putAll(prop);
+ }
+ }
+
+ public void testWriteObject_MockUnmodifiableMap() throws Exception {
+ MockUnmodifiableMap mockCollections = new MockUnmodifiableMap();
+ Class<?> propertyClass = mockCollections.getProperty().getClass();
+ assertEquals("java.util.Collections$UnmodifiableMap",
+ propertyClass.getName());
+ assertSamePD(propertyClass);
+ Map<String, String> prop = new HashMap<String, String>();
+ prop.put("A", "a");
+ prop.put("B", "b");
+ prop.put("C", "c");
+ mockCollections.setProperty(prop);
+ assertCodedXML(mockCollections, "/xml/MockUnmodifiableMap.xml");
+ }
+
+ public static class MockUnmodifiableSortedMap {
+
+ private SortedMap<String, String> property = new TreeMap<String, String>();
+
+ public Map<String, String> getProperty() {
+ return Collections.unmodifiableSortedMap(property);
+ }
+
+ public void setProperty(Map<String, String> prop) {
+ property.clear();
+ property.putAll(prop);
+ }
+ }
+
+ public void testWriteObject_MockUnmodifiableSortedMap() throws Exception {
+ MockUnmodifiableSortedMap mockCollections = new MockUnmodifiableSortedMap();
+ Class<?> propertyClass = mockCollections.getProperty().getClass();
+ assertEquals("java.util.Collections$UnmodifiableSortedMap",
+ propertyClass.getName());
+ assertSamePD(propertyClass);
+ Map<String, String> prop = new HashMap<String, String>();
+ prop.put("A", "a");
+ prop.put("B", "b");
+ prop.put("C", "c");
+ mockCollections.setProperty(prop);
+ assertCodedXML(mockCollections, "/xml/MockUnmodifiableSortedMap.xml");
+ }
+
+ public static class MockSynchronizedCollection {
+
+ private Collection<String> property = new ArrayList<String>();
+
+ public Collection<String> getProperty() {
+ return Collections.synchronizedCollection(property);
+ }
+
+ public void setProperty(Collection<String> prop) {
+ property.clear();
+ property.addAll(prop);
+ }
+ }
+
+ public void testWriteObject_MockSynchronizedCollection() throws Exception {
+ MockSynchronizedCollection mockCollections = new MockSynchronizedCollection();
+ Class<?> propertyClass = mockCollections.getProperty().getClass();
+ assertEquals("java.util.Collections$SynchronizedCollection",
+ propertyClass.getName());
+ assertSamePD(propertyClass);
+ mockCollections.setProperty(Arrays
+ .asList(new String[] { "A", "B", "C" }));
+ assertCodedXML(mockCollections, "/xml/MockSynchronizedCollection.xml");
+ }
+
+ public static class MockSynchronizedList {
+
+ private List<String> property = new LinkedList<String>();
+
+ public Collection<String> getProperty() {
+ return Collections.synchronizedList(property);
+ }
+
+ public void setProperty(Collection<String> prop) {
+ property.clear();
+ property.addAll(prop);
+ }
+ }
+
+ public void testWriteObject_MockSynchronizedList() throws Exception {
+ MockSynchronizedList mockCollections = new MockSynchronizedList();
+ Class<?> propertyClass = mockCollections.getProperty().getClass();
+ assertEquals("java.util.Collections$SynchronizedList",
+ propertyClass.getName());
+ assertSamePD(propertyClass);
+ mockCollections.setProperty(Arrays
+ .asList(new String[] { "A", "B", "C" }));
+ assertCodedXML(mockCollections, "/xml/MockSynchronizedList.xml");
+ }
+
+ public static class MockSynchronizedRandomAccessList {
+
+ private List<String> property = new ArrayList<String>();
+
+ public Collection<String> getProperty() {
+ return Collections.synchronizedList(property);
+ }
+
+ public void setProperty(Collection<String> prop) {
+ property.clear();
+ property.addAll(prop);
+ }
+ }
+
+ public void testWriteObject_MockSynchronizedRandomAccessList()
+ throws Exception {
+ MockSynchronizedRandomAccessList mockCollections = new MockSynchronizedRandomAccessList();
+ Class<?> propertyClass = mockCollections.getProperty().getClass();
+ assertEquals("java.util.Collections$SynchronizedRandomAccessList",
+ propertyClass.getName());
+ assertSamePD(propertyClass);
+ mockCollections.setProperty(Arrays
+ .asList(new String[] { "A", "B", "C" }));
+ assertCodedXML(mockCollections,
+ "/xml/MockSynchronizedRandomAccessList.xml");
+ }
+
+ public static class MockSynchronizedSet {
+
+ private Set<String> property = new HashSet<String>();
+
+ public Collection<String> getProperty() {
+ return Collections.synchronizedSet(property);
+ }
+
+ public void setProperty(Collection<String> prop) {
+ property.clear();
+ property.addAll(prop);
+ }
+ }
+
+ public void testWriteObject_MockSynchronizedSet() throws Exception {
+ MockSynchronizedSet mockCollections = new MockSynchronizedSet();
+ Class<?> propertyClass = mockCollections.getProperty().getClass();
+ assertEquals("java.util.Collections$SynchronizedSet",
+ propertyClass.getName());
+ assertSamePD(propertyClass);
+ mockCollections.setProperty(Arrays
+ .asList(new String[] { "A", "B", "C" }));
+ assertCodedXML(mockCollections, "/xml/MockSynchronizedSet.xml");
+ }
+
+ public static class MockSynchronizedSortedSet {
+
+ private SortedSet<String> property = new TreeSet<String>();
+
+ public Collection<String> getProperty() {
+ return Collections.synchronizedSortedSet(property);
+ }
+
+ public void setProperty(Collection<String> prop) {
+ property.clear();
+ property.addAll(prop);
+ }
+ }
+
+ public void testWriteObject_MockSynchronizedSortedSet() throws Exception {
+ MockSynchronizedSortedSet mockCollections = new MockSynchronizedSortedSet();
+ Class<?> propertyClass = mockCollections.getProperty().getClass();
+ assertEquals("java.util.Collections$SynchronizedSortedSet",
+ propertyClass.getName());
+ assertSamePD(propertyClass);
+ mockCollections.setProperty(Arrays
+ .asList(new String[] { "A", "B", "C" }));
+ assertCodedXML(mockCollections, "/xml/MockSynchronizedSortedSet.xml");
+ }
+
+ public static class MockSynchronizedMap {
+
+ private Map<String, String> property = new HashMap<String, String>();
+
+ public Map<String, String> getProperty() {
+ return Collections.synchronizedMap(property);
+ }
+
+ public void setProperty(Map<String, String> prop) {
+ property.clear();
+ property.putAll(prop);
+ }
+ }
+
+ public void testWriteObject_MockSynchronizedMap() throws Exception {
+ MockSynchronizedMap mockCollections = new MockSynchronizedMap();
+ Class<?> propertyClass = mockCollections.getProperty().getClass();
+ assertEquals("java.util.Collections$SynchronizedMap",
+ propertyClass.getName());
+ assertSamePD(propertyClass);
+ Map<String, String> prop = new HashMap<String, String>();
+ prop.put("A", "a");
+ prop.put("B", "b");
+ prop.put("C", "c");
+ mockCollections.setProperty(prop);
+ assertCodedXML(mockCollections, "/xml/MockSynchronizedMap.xml");
+ }
+
+ public static class MockSynchronizedSortedMap {
+
+ private SortedMap<String, String> property = new TreeMap<String, String>();
+
+ public Map<String, String> getProperty() {
+ return Collections.synchronizedSortedMap(property);
+ }
+
+ public void setProperty(Map<String, String> prop) {
+ property.clear();
+ property.putAll(prop);
+ }
+ }
+
+ public void testWriteObject_MockSynchronizedSortedMap() throws Exception {
+ MockSynchronizedSortedMap mockCollections = new MockSynchronizedSortedMap();
+ Class<?> propertyClass = mockCollections.getProperty().getClass();
+ assertEquals("java.util.Collections$SynchronizedSortedMap",
+ propertyClass.getName());
+ assertSamePD(propertyClass);
+ Map<String, String> prop = new HashMap<String, String>();
+ prop.put("A", "a");
+ prop.put("B", "b");
+ prop.put("C", "c");
+ mockCollections.setProperty(prop);
+ assertCodedXML(mockCollections, "/xml/MockSynchronizedSortedMap.xml");
+ }
+
+ public static class MockCheckedCollection {
+
+ private Collection<String> property = new ArrayList<String>();
+
+ public Collection<String> getProperty() {
+ return Collections.checkedCollection(property, String.class);
+ }
+
+ public void setProperty(Collection<String> prop) {
+ property.clear();
+ property.addAll(prop);
+ }
+ }
+
+ public void testWriteObject_MockCheckedCollection() throws Exception {
+ MockCheckedCollection mockCollections = new MockCheckedCollection();
+ Class<?> propertyClass = mockCollections.getProperty().getClass();
+ assertEquals("java.util.Collections$CheckedCollection",
+ propertyClass.getName());
+ assertSamePD(propertyClass);
+ mockCollections.setProperty(Arrays
+ .asList(new String[] { "A", "B", "C" }));
+ assertCodedXML(mockCollections, "/xml/MockCheckedCollection.xml");
+ }
+
+ public static class MockCheckedList {
+
+ private List<String> property = new LinkedList<String>();
+
+ public Collection<String> getProperty() {
+ return Collections.checkedList(property, String.class);
+ }
+
+ public void setProperty(Collection<String> prop) {
+ property.clear();
+ property.addAll(prop);
+ }
+ }
+
+ public void testWriteObject_MockCheckedList() throws Exception {
+ MockCheckedList mockCollections = new MockCheckedList();
+ Class<?> propertyClass = mockCollections.getProperty().getClass();
+ assertEquals("java.util.Collections$CheckedList",
+ propertyClass.getName());
+ assertSamePD(propertyClass);
+ mockCollections.setProperty(Arrays
+ .asList(new String[] { "A", "B", "C" }));
+ assertCodedXML(mockCollections, "/xml/MockCheckedList.xml");
+ }
+
+ public static class MockCheckedRandomAccessList {
+
+ private List<String> property = new ArrayList<String>();
+
+ public Collection<String> getProperty() {
+ return Collections.checkedList(property, String.class);
+ }
+
+ public void setProperty(Collection<String> prop) {
+ property.clear();
+ property.addAll(prop);
+ }
+ }
+
+ public void testWriteObject_MockCheckedRandomAccessList() throws Exception {
+ MockCheckedRandomAccessList mockCollections = new MockCheckedRandomAccessList();
+ Class<?> propertyClass = mockCollections.getProperty().getClass();
+ assertEquals("java.util.Collections$CheckedRandomAccessList",
+ propertyClass.getName());
+ assertSamePD(propertyClass);
+ mockCollections.setProperty(Arrays
+ .asList(new String[] { "A", "B", "C" }));
+ assertCodedXML(mockCollections, "/xml/MockCheckedRandomAccessList.xml");
+ }
+
+ public static class MockCheckedSet {
+
+ private Set<String> property = new HashSet<String>();
+
+ public Collection<String> getProperty() {
+ return Collections.checkedSet(property, String.class);
+ }
+
+ public void setProperty(Collection<String> prop) {
+ property.clear();
+ property.addAll(prop);
+ }
+ }
+
+ public void testWriteObject_MockCheckedSet() throws Exception {
+ MockCheckedSet mockCollections = new MockCheckedSet();
+ Class<?> propertyClass = mockCollections.getProperty().getClass();
+ assertEquals("java.util.Collections$CheckedSet",
+ propertyClass.getName());
+ assertSamePD(propertyClass);
+ mockCollections.setProperty(Arrays
+ .asList(new String[] { "A", "B", "C" }));
+ assertCodedXML(mockCollections, "/xml/MockCheckedSet.xml");
+ }
+
+ public static class MockCheckedSortedSet {
+
+ private SortedSet<String> property = new TreeSet<String>();
+
+ public Collection<String> getProperty() {
+ return Collections.checkedSortedSet(property, String.class);
+ }
+
+ public void setProperty(Collection<String> prop) {
+ property.clear();
+ property.addAll(prop);
+ }
+ }
+
+ public void testWriteObject_MockCheckedSortedSet() throws Exception {
+ MockCheckedSortedSet mockCollections = new MockCheckedSortedSet();
+ Class<?> propertyClass = mockCollections.getProperty().getClass();
+ assertEquals("java.util.Collections$CheckedSortedSet",
+ propertyClass.getName());
+ assertSamePD(propertyClass);
+ mockCollections.setProperty(Arrays
+ .asList(new String[] { "A", "B", "C" }));
+ assertCodedXML(mockCollections, "/xml/MockCheckedSortedSet.xml");
+ }
+
+ public static class MockCheckedMap {
+
+ private Map<String, String> property = new HashMap<String, String>();
+
+ public Map<String, String> getProperty() {
+ return Collections.checkedMap(property, String.class, String.class);
+ }
+
+ public void setProperty(Map<String, String> prop) {
+ property.clear();
+ property.putAll(prop);
+ }
+ }
+
+ public void testWriteObject_MockCheckedMap() throws Exception {
+ MockCheckedMap mockCollections = new MockCheckedMap();
+ Class<?> propertyClass = mockCollections.getProperty().getClass();
+ assertEquals("java.util.Collections$CheckedMap",
+ propertyClass.getName());
+ assertSamePD(propertyClass);
+ Map<String, String> prop = new HashMap<String, String>();
+ prop.put("A", "a");
+ prop.put("B", "b");
+ prop.put("C", "c");
+ mockCollections.setProperty(prop);
+ assertCodedXML(mockCollections, "/xml/MockCheckedMap.xml");
+ }
+
+ public static class MockCheckedSortedMap {
+
+ private SortedMap<String, String> property = new TreeMap<String, String>();
+
+ public Map<String, String> getProperty() {
+ return Collections.checkedSortedMap(property, String.class,
+ String.class);
+ }
+
+ public void setProperty(Map<String, String> prop) {
+ property.clear();
+ property.putAll(prop);
+ }
+ }
+
+ public void testWriteObject_MockCheckedSortedMap() throws Exception {
+ MockCheckedSortedMap mockCollections = new MockCheckedSortedMap();
+ Class<?> propertyClass = mockCollections.getProperty().getClass();
+ assertEquals("java.util.Collections$CheckedSortedMap",
+ propertyClass.getName());
+ assertSamePD(propertyClass);
+ Map<String, String> prop = new HashMap<String, String>();
+ prop.put("A", "a");
+ prop.put("B", "b");
+ prop.put("C", "c");
+ mockCollections.setProperty(prop);
+ assertCodedXML(mockCollections, "/xml/MockCheckedSortedMap.xml");
+ }
+
+ public static class MockGetPropertyClass {
+
+ private Set<String> property = new HashSet<String>();
+
+ public Set<String> getProperty() {
+ return new HashSet<String>(property);
+ }
+
+ public void setProperty(Set<String> set) {
+ property.clear();
+ property.addAll(set);
+ }
+ }
+
+ public void testWriteObject_MockGetPropertyClass() throws Exception {
+ MockGetPropertyClass mockCollections = new MockGetPropertyClass();
+ assertSamePD(mockCollections.getProperty().getClass());
+ Set<String> prop = new HashSet<String>();
+ prop.add("A");
+ prop.add("B");
+ prop.add("C");
+ mockCollections.setProperty(prop);
+ assertCodedXML(mockCollections, "/xml/MockGetPropertyClass.xml");
+ }
+
+ public static class MockListImplements implements List<String> {
+
+ private List<String> property = new ArrayList<String>();
+
+ public List<String> getProperty() {
+ return property;
+ }
+
+ public void setProperty(List<String> prop) {
+ property = prop;
+ }
+
+ public boolean add(String o) {
+ return property.add(o);
+ }
+
+ public void add(int index, String o) {
+ property.add(index, o);
+ }
+
+ public boolean addAll(Collection<? extends String> c) {
+ return property.addAll(c);
+ }
+
+ public boolean addAll(int index, Collection<? extends String> c) {
+ return property.addAll(index, c);
+ }
+
+ public void clear() {
+ property.clear();
+ }
+
+ public boolean contains(Object o) {
+ return property.contains(o);
+ }
+
+ public boolean containsAll(Collection<?> c) {
+ return property.containsAll(c);
+ }
+
+ public String get(int index) {
+ return property.get(index);
+ }
+
+ public int indexOf(Object o) {
+ return property.indexOf(o);
+ }
+
+ public boolean isEmpty() {
+ return property.isEmpty();
+ }
+
+ public Iterator<String> iterator() {
+ return property.iterator();
+ }
+
+ public int lastIndexOf(Object o) {
+ return property.lastIndexOf(o);
+ }
+
+ public ListIterator<String> listIterator() {
+ return property.listIterator();
+ }
+
+ public ListIterator<String> listIterator(int index) {
+ return property.listIterator(index);
+ }
+
+ public boolean remove(Object o) {
+ return property.remove(o);
+ }
+
+ public String remove(int index) {
+ return property.remove(index);
+ }
+
+ public boolean removeAll(Collection<?> c) {
+ return property.removeAll(c);
+ }
+
+ public boolean retainAll(Collection<?> c) {
+ return property.retainAll(c);
+ }
+
+ public String set(int index, String o) {
+ return property.set(index, o);
+ }
+
+ public int size() {
+ return property.size();
+ }
+
+ public List<String> subList(int fromIndex, int toIndex) {
+ return property.subList(fromIndex, toIndex);
+ }
+
+ public Object[] toArray() {
+ return property.toArray();
+ }
+
+ public <T> T[] toArray(T[] a) {
+ return property.toArray(a);
+ }
+ }
+
+ public void testWriteObject_MockListImplements() throws Exception {
+ List<String> mockListImplements = new MockListImplements();
+ mockListImplements.add("A");
+ assertCodedXML(mockListImplements, "/xml/MockListImplements.xml");
+ }
+
+ public static class MockSetImplements implements Set<String> {
+
+ private Set<String> property;
+
+ public MockSetImplements() {
+ property = new HashSet<String>();
+ }
+
+ public Set<String> getProperty() {
+ return property;
+ }
+
+ public void setProperty(Set<String> prop) {
+ property = prop;
+ }
+
+ public boolean add(String o) {
+ return property.add(o);
+ }
+
+ public void clear() {
+ property.clear();
+ }
+
+ public boolean contains(final Object o) {
+ return property.contains(o);
+ }
+
+ public boolean containsAll(final Collection<?> c) {
+ return property.containsAll(c);
+ }
+
+ public boolean isEmpty() {
+ return property.isEmpty();
+ }
+
+ public Iterator<String> iterator() {
+ return property.iterator();
+ }
+
+ public boolean remove(final Object o) {
+ return property.remove(o);
+ }
+
+ public boolean removeAll(final Collection<?> c) {
+ return property.removeAll(c);
+ }
+
+ public boolean retainAll(final Collection<?> c) {
+ return property.retainAll(c);
+ }
+
+ public int size() {
+ return property.size();
+ }
+
+ public Object[] toArray() {
+ return property.toArray();
+ }
+
+ public <T> T[] toArray(final T[] a) {
+ return property.toArray(a);
+ }
+
+ public int hashCode() {
+ return property.hashCode();
+ }
+
+ public boolean addAll(Collection<? extends String> c) {
+ return property.addAll(c);
+ }
+ }
+
+ public void testWriteObject_MockSetImplements() throws Exception {
+ Set<String> mockSetImplements = new MockSetImplements();
+ mockSetImplements.add("A");
+ assertCodedXML(mockSetImplements, "/xml/MockSetImplements.xml");
+ }
+
+ private Encoder encoder = new Encoder();
+
+ private void assertSamePD(Class<?> clazz) {
+ assertSame(encoder.getPersistenceDelegate(clazz),
+ encoder.getPersistenceDelegate(clazz));
+ }
+
}
\ No newline at end of file
diff --git a/classlib/modules/beans/src/test/resources/xml/MockCheckedCollection.xml b/classlib/modules/beans/src/test/resources/xml/MockCheckedCollection.xml
new file mode 100644
index 0000000..3abf592
--- /dev/null
+++ b/classlib/modules/beans/src/test/resources/xml/MockCheckedCollection.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<java version="${version}" class="java.beans.XMLDecoder">
+ <object class="${classname}">
+ <void property="property">
+ <object class="java.util.Collections" method="checkedCollection">
+ <object class="java.util.ArrayList">
+ <void method="add">
+ <string>A</string>
+ </void>
+ <void method="add">
+ <string>B</string>
+ </void>
+ <void method="add">
+ <string>C</string>
+ </void>
+ </object>
+ <class>java.lang.String</class>
+ </object>
+ </void>
+ </object>
+</java>
+
diff --git a/classlib/modules/beans/src/test/resources/xml/MockCheckedList.xml b/classlib/modules/beans/src/test/resources/xml/MockCheckedList.xml
new file mode 100644
index 0000000..98f3486
--- /dev/null
+++ b/classlib/modules/beans/src/test/resources/xml/MockCheckedList.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<java version="${version}" class="java.beans.XMLDecoder">
+ <object class="${classname}">
+ <void property="property">
+ <object class="java.util.Collections" method="checkedList">
+ <object class="java.util.LinkedList">
+ <void method="add">
+ <string>A</string>
+ </void>
+ <void method="add">
+ <string>B</string>
+ </void>
+ <void method="add">
+ <string>C</string>
+ </void>
+ </object>
+ <class>java.lang.String</class>
+ </object>
+ </void>
+ </object>
+</java>
+
diff --git a/classlib/modules/beans/src/test/resources/xml/MockCheckedMap.xml b/classlib/modules/beans/src/test/resources/xml/MockCheckedMap.xml
new file mode 100644
index 0000000..31e4623
--- /dev/null
+++ b/classlib/modules/beans/src/test/resources/xml/MockCheckedMap.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<java version="${version}" class="java.beans.XMLDecoder">
+ <object class="${classname}">
+ <void property="property">
+ <object class="java.util.Collections" method="checkedMap">
+ <object class="java.util.HashMap">
+ <void method="put">
+ <string>A</string>
+ <string>a</string>
+ </void>
+ <void method="put">
+ <string>B</string>
+ <string>b</string>
+ </void>
+ <void method="put">
+ <string>C</string>
+ <string>c</string>
+ </void>
+ </object>
+ <class>java.lang.String</class>
+ <class>java.lang.String</class>
+ </object>
+ </void>
+ </object>
+</java>
\ No newline at end of file
diff --git a/classlib/modules/beans/src/test/resources/xml/MockCheckedRandomAccessList.xml b/classlib/modules/beans/src/test/resources/xml/MockCheckedRandomAccessList.xml
new file mode 100644
index 0000000..5daae2a
--- /dev/null
+++ b/classlib/modules/beans/src/test/resources/xml/MockCheckedRandomAccessList.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<java version="${version}" class="java.beans.XMLDecoder">
+ <object class="${classname}">
+ <void property="property">
+ <object class="java.util.Collections" method="checkedList">
+ <object class="java.util.ArrayList">
+ <void method="add">
+ <string>A</string>
+ </void>
+ <void method="add">
+ <string>B</string>
+ </void>
+ <void method="add">
+ <string>C</string>
+ </void>
+ </object>
+ <class>java.lang.String</class>
+ </object>
+ </void>
+ </object>
+</java>
+
diff --git a/classlib/modules/beans/src/test/resources/xml/MockCheckedSet.xml b/classlib/modules/beans/src/test/resources/xml/MockCheckedSet.xml
new file mode 100644
index 0000000..af0743c
--- /dev/null
+++ b/classlib/modules/beans/src/test/resources/xml/MockCheckedSet.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<java version="${version}" class="java.beans.XMLDecoder">
+ <object class="${classname}">
+ <void property="property">
+ <object class="java.util.Collections" method="checkedSet">
+ <object class="java.util.HashSet">
+ <void method="add">
+ <string>A</string>
+ </void>
+ <void method="add">
+ <string>B</string>
+ </void>
+ <void method="add">
+ <string>C</string>
+ </void>
+ </object>
+ <class>java.lang.String</class>
+ </object>
+ </void>
+ </object>
+</java>
+
diff --git a/classlib/modules/beans/src/test/resources/xml/MockCheckedSortedMap.xml b/classlib/modules/beans/src/test/resources/xml/MockCheckedSortedMap.xml
new file mode 100644
index 0000000..5179966
--- /dev/null
+++ b/classlib/modules/beans/src/test/resources/xml/MockCheckedSortedMap.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<java version="${version}" class="java.beans.XMLDecoder">
+ <object class="${classname}">
+ <void property="property">
+ <object class="java.util.Collections" method="checkedSortedMap">
+ <object class="java.util.TreeMap">
+ <void method="put">
+ <string>A</string>
+ <string>a</string>
+ </void>
+ <void method="put">
+ <string>B</string>
+ <string>b</string>
+ </void>
+ <void method="put">
+ <string>C</string>
+ <string>c</string>
+ </void>
+ </object>
+ <class>java.lang.String</class>
+ <class>java.lang.String</class>
+ </object>
+ </void>
+ </object>
+</java>
\ No newline at end of file
diff --git a/classlib/modules/beans/src/test/resources/xml/MockCheckedSortedSet.xml b/classlib/modules/beans/src/test/resources/xml/MockCheckedSortedSet.xml
new file mode 100644
index 0000000..43bf2f7
--- /dev/null
+++ b/classlib/modules/beans/src/test/resources/xml/MockCheckedSortedSet.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<java version="${version}" class="java.beans.XMLDecoder">
+ <object class="${classname}">
+ <void property="property">
+ <object class="java.util.Collections" method="checkedSortedSet">
+ <object class="java.util.TreeSet">
+ <void method="add">
+ <string>A</string>
+ </void>
+ <void method="add">
+ <string>B</string>
+ </void>
+ <void method="add">
+ <string>C</string>
+ </void>
+ </object>
+ <class>java.lang.String</class>
+ </object>
+ </void>
+ </object>
+</java>
+
diff --git a/classlib/modules/beans/src/test/resources/xml/MockGetPropertyClass.xml b/classlib/modules/beans/src/test/resources/xml/MockGetPropertyClass.xml
new file mode 100644
index 0000000..7b8e8cc
--- /dev/null
+++ b/classlib/modules/beans/src/test/resources/xml/MockGetPropertyClass.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<java version="${version}" class="java.beans.XMLDecoder">
+ <object class="${classname}">
+ <void id="HashSet0" property="property">
+ <void method="add">
+ <string>A</string>
+ </void>
+ <void method="add">
+ <string>B</string>
+ </void>
+ <void method="add">
+ <string>C</string>
+ </void>
+ </void>
+ <void property="property">
+ <object idref="HashSet0"/>
+ </void>
+ </object>
+</java>
\ No newline at end of file
diff --git a/classlib/modules/beans/src/test/resources/xml/MockListImplements.xml b/classlib/modules/beans/src/test/resources/xml/MockListImplements.xml
new file mode 100644
index 0000000..76190bc
--- /dev/null
+++ b/classlib/modules/beans/src/test/resources/xml/MockListImplements.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<java version="${version}" class="java.beans.XMLDecoder">
+ <object class="${classname}">
+ <void property="property">
+ <void method="add">
+ <string>A</string>
+ </void>
+ </void>
+ </object>
+</java>
+
diff --git a/classlib/modules/beans/src/test/resources/xml/MockSetImplements.xml b/classlib/modules/beans/src/test/resources/xml/MockSetImplements.xml
new file mode 100644
index 0000000..1b9c56a
--- /dev/null
+++ b/classlib/modules/beans/src/test/resources/xml/MockSetImplements.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<java version="${version}" class="java.beans.XMLDecoder">
+ <object class="${classname}">
+ <void property="property">
+ <void method="add">
+ <string>A</string>
+ </void>
+ </void>
+ </object>
+</java>
+
diff --git a/classlib/modules/beans/src/test/resources/xml/MockSynchronizedCollection.xml b/classlib/modules/beans/src/test/resources/xml/MockSynchronizedCollection.xml
new file mode 100644
index 0000000..2cdc336
--- /dev/null
+++ b/classlib/modules/beans/src/test/resources/xml/MockSynchronizedCollection.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<java version="${version}" class="java.beans.XMLDecoder">
+ <object class="${classname}">
+ <void property="property">
+ <object class="java.util.Collections" method="synchronizedCollection">
+ <object class="java.util.ArrayList">
+ <void method="add">
+ <string>A</string>
+ </void>
+ <void method="add">
+ <string>B</string>
+ </void>
+ <void method="add">
+ <string>C</string>
+ </void>
+ </object>
+ </object>
+ </void>
+ </object>
+</java>
+
diff --git a/classlib/modules/beans/src/test/resources/xml/MockSynchronizedList.xml b/classlib/modules/beans/src/test/resources/xml/MockSynchronizedList.xml
new file mode 100644
index 0000000..33bdcea
--- /dev/null
+++ b/classlib/modules/beans/src/test/resources/xml/MockSynchronizedList.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<java version="${version}" class="java.beans.XMLDecoder">
+ <object class="${classname}">
+ <void property="property">
+ <object class="java.util.Collections" method="synchronizedList">
+ <object class="java.util.LinkedList">
+ <void method="add">
+ <string>A</string>
+ </void>
+ <void method="add">
+ <string>B</string>
+ </void>
+ <void method="add">
+ <string>C</string>
+ </void>
+ </object>
+ </object>
+ </void>
+ </object>
+</java>
+
diff --git a/classlib/modules/beans/src/test/resources/xml/MockSynchronizedMap.xml b/classlib/modules/beans/src/test/resources/xml/MockSynchronizedMap.xml
new file mode 100644
index 0000000..0efc0b4
--- /dev/null
+++ b/classlib/modules/beans/src/test/resources/xml/MockSynchronizedMap.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<java version="${version}" class="java.beans.XMLDecoder">
+ <object class="${classname}">
+ <void property="property">
+ <object class="java.util.Collections" method="synchronizedMap">
+ <object class="java.util.HashMap">
+ <void method="put">
+ <string>A</string>
+ <string>a</string>
+ </void>
+ <void method="put">
+ <string>B</string>
+ <string>b</string>
+ </void>
+ <void method="put">
+ <string>C</string>
+ <string>c</string>
+ </void>
+ </object>
+ </object>
+ </void>
+ </object>
+</java>
+
diff --git a/classlib/modules/beans/src/test/resources/xml/MockSynchronizedRandomAccessList.xml b/classlib/modules/beans/src/test/resources/xml/MockSynchronizedRandomAccessList.xml
new file mode 100644
index 0000000..9cb22a4
--- /dev/null
+++ b/classlib/modules/beans/src/test/resources/xml/MockSynchronizedRandomAccessList.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<java version="${version}" class="java.beans.XMLDecoder">
+ <object class="${classname}">
+ <void property="property">
+ <object class="java.util.Collections" method="synchronizedList">
+ <object class="java.util.ArrayList">
+ <void method="add">
+ <string>A</string>
+ </void>
+ <void method="add">
+ <string>B</string>
+ </void>
+ <void method="add">
+ <string>C</string>
+ </void>
+ </object>
+ </object>
+ </void>
+ </object>
+</java>
+
diff --git a/classlib/modules/beans/src/test/resources/xml/MockSynchronizedSet.xml b/classlib/modules/beans/src/test/resources/xml/MockSynchronizedSet.xml
new file mode 100644
index 0000000..6426f6c
--- /dev/null
+++ b/classlib/modules/beans/src/test/resources/xml/MockSynchronizedSet.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<java version="${version}" class="java.beans.XMLDecoder">
+ <object class="${classname}">
+ <void property="property">
+ <object class="java.util.Collections" method="synchronizedSet">
+ <object class="java.util.HashSet">
+ <void method="add">
+ <string>A</string>
+ </void>
+ <void method="add">
+ <string>B</string>
+ </void>
+ <void method="add">
+ <string>C</string>
+ </void>
+ </object>
+ </object>
+ </void>
+ </object>
+</java>
+
diff --git a/classlib/modules/beans/src/test/resources/xml/MockSynchronizedSortedMap.xml b/classlib/modules/beans/src/test/resources/xml/MockSynchronizedSortedMap.xml
new file mode 100644
index 0000000..b34e9d2
--- /dev/null
+++ b/classlib/modules/beans/src/test/resources/xml/MockSynchronizedSortedMap.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<java version="${version}" class="java.beans.XMLDecoder">
+ <object class="${classname}">
+ <void property="property">
+ <object class="java.util.Collections" method="synchronizedSortedMap">
+ <object class="java.util.TreeMap">
+ <void method="put">
+ <string>A</string>
+ <string>a</string>
+ </void>
+ <void method="put">
+ <string>B</string>
+ <string>b</string>
+ </void>
+ <void method="put">
+ <string>C</string>
+ <string>c</string>
+ </void>
+ </object>
+ </object>
+ </void>
+ </object>
+</java>
+
diff --git a/classlib/modules/beans/src/test/resources/xml/MockSynchronizedSortedSet.xml b/classlib/modules/beans/src/test/resources/xml/MockSynchronizedSortedSet.xml
new file mode 100644
index 0000000..4b50148
--- /dev/null
+++ b/classlib/modules/beans/src/test/resources/xml/MockSynchronizedSortedSet.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<java version="${version}" class="java.beans.XMLDecoder">
+ <object class="${classname}">
+ <void property="property">
+ <object class="java.util.Collections" method="synchronizedSortedSet">
+ <object class="java.util.TreeSet">
+ <void method="add">
+ <string>A</string>
+ </void>
+ <void method="add">
+ <string>B</string>
+ </void>
+ <void method="add">
+ <string>C</string>
+ </void>
+ </object>
+ </object>
+ </void>
+ </object>
+</java>
+
diff --git a/classlib/modules/beans/src/test/resources/xml/MockUnmodifiableCollection.xml b/classlib/modules/beans/src/test/resources/xml/MockUnmodifiableCollection.xml
new file mode 100644
index 0000000..43227a5
--- /dev/null
+++ b/classlib/modules/beans/src/test/resources/xml/MockUnmodifiableCollection.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<java version="${version}" class="java.beans.XMLDecoder">
+ <object class="${classname}">
+ <void property="property">
+ <object class="java.util.Collections" method="unmodifiableCollection">
+ <object class="java.util.ArrayList">
+ <void method="add">
+ <string>A</string>
+ </void>
+ <void method="add">
+ <string>B</string>
+ </void>
+ <void method="add">
+ <string>C</string>
+ </void>
+ </object>
+ </object>
+ </void>
+ </object>
+</java>
+
diff --git a/classlib/modules/beans/src/test/resources/xml/MockUnmodifiableList.xml b/classlib/modules/beans/src/test/resources/xml/MockUnmodifiableList.xml
new file mode 100644
index 0000000..9f3d212
--- /dev/null
+++ b/classlib/modules/beans/src/test/resources/xml/MockUnmodifiableList.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<java version="${version}" class="java.beans.XMLDecoder">
+ <object class="${classname}">
+ <void property="property">
+ <object class="java.util.Collections" method="unmodifiableList">
+ <object class="java.util.LinkedList">
+ <void method="add">
+ <string>A</string>
+ </void>
+ <void method="add">
+ <string>B</string>
+ </void>
+ <void method="add">
+ <string>C</string>
+ </void>
+ </object>
+ </object>
+ </void>
+ </object>
+</java>
+
diff --git a/classlib/modules/beans/src/test/resources/xml/MockUnmodifiableMap.xml b/classlib/modules/beans/src/test/resources/xml/MockUnmodifiableMap.xml
new file mode 100644
index 0000000..d5bd832
--- /dev/null
+++ b/classlib/modules/beans/src/test/resources/xml/MockUnmodifiableMap.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<java version="${version}" class="java.beans.XMLDecoder">
+ <object class="${classname}">
+ <void property="property">
+ <object class="java.util.Collections" method="unmodifiableMap">
+ <object class="java.util.HashMap">
+ <void method="put">
+ <string>A</string>
+ <string>a</string>
+ </void>
+ <void method="put">
+ <string>B</string>
+ <string>b</string>
+ </void>
+ <void method="put">
+ <string>C</string>
+ <string>c</string>
+ </void>
+ </object>
+ </object>
+ </void>
+ </object>
+</java>
+
diff --git a/classlib/modules/beans/src/test/resources/xml/MockUnmodifiableRandomAccessList.xml b/classlib/modules/beans/src/test/resources/xml/MockUnmodifiableRandomAccessList.xml
new file mode 100644
index 0000000..41cb2f9
--- /dev/null
+++ b/classlib/modules/beans/src/test/resources/xml/MockUnmodifiableRandomAccessList.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<java version="${version}" class="java.beans.XMLDecoder">
+ <object class="${classname}">
+ <void property="property">
+ <object class="java.util.Collections" method="unmodifiableList">
+ <object class="java.util.ArrayList">
+ <void method="add">
+ <string>A</string>
+ </void>
+ <void method="add">
+ <string>B</string>
+ </void>
+ <void method="add">
+ <string>C</string>
+ </void>
+ </object>
+ </object>
+ </void>
+ </object>
+</java>
+
diff --git a/classlib/modules/beans/src/test/resources/xml/MockUnmodifiableSet.xml b/classlib/modules/beans/src/test/resources/xml/MockUnmodifiableSet.xml
new file mode 100644
index 0000000..91ba582
--- /dev/null
+++ b/classlib/modules/beans/src/test/resources/xml/MockUnmodifiableSet.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<java version="${version}" class="java.beans.XMLDecoder">
+ <object class="${classname}">
+ <void property="property">
+ <object class="java.util.Collections" method="unmodifiableSet">
+ <object class="java.util.HashSet">
+ <void method="add">
+ <string>A</string>
+ </void>
+ <void method="add">
+ <string>B</string>
+ </void>
+ <void method="add">
+ <string>C</string>
+ </void>
+ </object>
+ </object>
+ </void>
+ </object>
+</java>
+
diff --git a/classlib/modules/beans/src/test/resources/xml/MockUnmodifiableSortedMap.xml b/classlib/modules/beans/src/test/resources/xml/MockUnmodifiableSortedMap.xml
new file mode 100644
index 0000000..143fcb2
--- /dev/null
+++ b/classlib/modules/beans/src/test/resources/xml/MockUnmodifiableSortedMap.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<java version="${version}" class="java.beans.XMLDecoder">
+ <object class="${classname}">
+ <void property="property">
+ <object class="java.util.Collections" method="unmodifiableSortedMap">
+ <object class="java.util.TreeMap">
+ <void method="put">
+ <string>A</string>
+ <string>a</string>
+ </void>
+ <void method="put">
+ <string>B</string>
+ <string>b</string>
+ </void>
+ <void method="put">
+ <string>C</string>
+ <string>c</string>
+ </void>
+ </object>
+ </object>
+ </void>
+ </object>
+</java>
+
diff --git a/classlib/modules/beans/src/test/resources/xml/MockUnmodifiableSortedSet.xml b/classlib/modules/beans/src/test/resources/xml/MockUnmodifiableSortedSet.xml
new file mode 100644
index 0000000..c63bce2
--- /dev/null
+++ b/classlib/modules/beans/src/test/resources/xml/MockUnmodifiableSortedSet.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<java version="${version}" class="java.beans.XMLDecoder">
+ <object class="${classname}">
+ <void property="property">
+ <object class="java.util.Collections" method="unmodifiableSortedSet">
+ <object class="java.util.TreeSet">
+ <void method="add">
+ <string>A</string>
+ </void>
+ <void method="add">
+ <string>B</string>
+ </void>
+ <void method="add">
+ <string>C</string>
+ </void>
+ </object>
+ </object>
+ </void>
+ </object>
+</java>
+