blob: 3390e11d4b87ab66d885d33f38c1ed01feb3e073 [file] [log] [blame]
/*
* 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;
}
}