com.thoughtworks.xstream.mapper.ImplicitCollectionMapper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.apache.servicemix.bundles.xstream
Show all versions of org.apache.servicemix.bundles.xstream
This OSGi bundle wraps ${pkgArtifactId} ${pkgVersion} jar file.
/*
* Copyright (C) 2005 Joe Walnes.
* Copyright (C) 2006, 2007, 2009, 2011, 2012, 2013, 2014, 2015, 2016 XStream Committers.
* All rights reserved.
*
* The software in this package is published under the terms of the BSD
* style license a copy of which has been included with this distribution in
* the LICENSE.txt file.
*
* Created on 16. February 2005 by Joe Walnes
*/
package com.thoughtworks.xstream.mapper;
import com.thoughtworks.xstream.InitializationException;
import com.thoughtworks.xstream.converters.reflection.ReflectionProvider;
import com.thoughtworks.xstream.core.util.Primitives;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class ImplicitCollectionMapper extends MapperWrapper {
private ReflectionProvider reflectionProvider;
public ImplicitCollectionMapper(Mapper wrapped, ReflectionProvider reflectionProvider) {
super(wrapped);
this.reflectionProvider = reflectionProvider;
}
// { definedIn (Class) -> (ImplicitCollectionMapperForClass) }
private final Map classNameToMapper = new HashMap();
private ImplicitCollectionMapperForClass getMapper(final Class declaredFor, final String fieldName) {
Class definedIn = declaredFor;
Field field = fieldName != null ? reflectionProvider.getFieldOrNull(definedIn, fieldName) : null;
Class inheritanceStop = field != null ? field.getDeclaringClass() : null;
while (definedIn != null) {
ImplicitCollectionMapperForClass mapper = (ImplicitCollectionMapperForClass)classNameToMapper
.get(definedIn);
if (mapper != null) {
return mapper;
}
if (definedIn == inheritanceStop) {
break;
}
definedIn = definedIn.getSuperclass();
}
return null;
}
private ImplicitCollectionMapperForClass getOrCreateMapper(Class definedIn) {
ImplicitCollectionMapperForClass mapper = (ImplicitCollectionMapperForClass)classNameToMapper
.get(definedIn);
if (mapper == null) {
mapper = new ImplicitCollectionMapperForClass(definedIn);
classNameToMapper.put(definedIn, mapper);
}
return mapper;
}
public String getFieldNameForItemTypeAndName(Class definedIn, Class itemType,
String itemFieldName) {
ImplicitCollectionMapperForClass mapper = getMapper(definedIn, null);
if (mapper != null) {
return mapper.getFieldNameForItemTypeAndName(itemType, itemFieldName);
} else {
return null;
}
}
public Class getItemTypeForItemFieldName(Class definedIn, String itemFieldName) {
ImplicitCollectionMapperForClass mapper = getMapper(definedIn, null);
if (mapper != null) {
return mapper.getItemTypeForItemFieldName(itemFieldName);
} else {
return null;
}
}
public ImplicitCollectionMapping getImplicitCollectionDefForFieldName(Class itemType,
String fieldName) {
ImplicitCollectionMapperForClass mapper = getMapper(itemType, fieldName);
if (mapper != null) {
return mapper.getImplicitCollectionDefForFieldName(fieldName);
} else {
return null;
}
}
public void add(Class definedIn, String fieldName, Class itemType) {
add(definedIn, fieldName, null, itemType);
}
public void add(Class definedIn, String fieldName, String itemFieldName, Class itemType) {
add(definedIn, fieldName, itemFieldName, itemType, null);
}
public void add(Class definedIn, String fieldName, String itemFieldName, Class itemType, String keyFieldName) {
Field field = null;
if (definedIn != null) {
Class declaredIn = definedIn;
while (declaredIn != Object.class) {
try {
field = declaredIn.getDeclaredField(fieldName);
if (!Modifier.isStatic(field.getModifiers())) {
break;
}
field = null;
} catch (final SecurityException e) {
throw new InitializationException("Access denied for field with implicit collection", e);
} catch (final NoSuchFieldException e) {
declaredIn = declaredIn.getSuperclass();
}
}
}
if (field == null) {
throw new InitializationException("No field \""
+ fieldName
+ "\" for implicit collection");
} else if (Map.class.isAssignableFrom(field.getType())) {
if (itemFieldName == null && keyFieldName == null) {
itemType = Map.Entry.class;
}
} else if (!Collection.class.isAssignableFrom(field.getType())) {
Class fieldType = field.getType();
if (!fieldType.isArray()) {
throw new InitializationException("Field \""
+ fieldName
+ "\" declares no collection or array");
} else {
Class componentType = fieldType.getComponentType();
componentType = componentType.isPrimitive() ? Primitives.box(componentType) : componentType;
if (itemType == null) {
itemType = componentType;
} else {
itemType = itemType.isPrimitive() ? Primitives.box(itemType) : itemType;
if (!componentType.isAssignableFrom(itemType)) {
throw new InitializationException("Field \""
+ fieldName
+ "\" declares an array, but the array type is not compatible with " + itemType.getName());
}
}
}
}
ImplicitCollectionMapperForClass mapper = getOrCreateMapper(definedIn);
mapper.add(new ImplicitCollectionMappingImpl(fieldName, itemType, itemFieldName, keyFieldName));
}
private class ImplicitCollectionMapperForClass {
private Class definedIn;
// { (NamedItemType) -> (ImplicitCollectionDefImpl) }
private Map namedItemTypeToDef = new HashMap();
// { itemFieldName (String) -> (ImplicitCollectionDefImpl) }
private Map itemFieldNameToDef = new HashMap();
// { fieldName (String) -> (ImplicitCollectionDefImpl) }
private Map fieldNameToDef = new HashMap();
ImplicitCollectionMapperForClass(Class definedIn) {
this.definedIn = definedIn;
}
public String getFieldNameForItemTypeAndName(Class itemType, String itemFieldName) {
ImplicitCollectionMappingImpl unnamed = null;
for (Iterator iterator = namedItemTypeToDef.keySet().iterator(); iterator.hasNext();) {
NamedItemType itemTypeForFieldName = (NamedItemType)iterator.next();
ImplicitCollectionMappingImpl def = (ImplicitCollectionMappingImpl)namedItemTypeToDef
.get(itemTypeForFieldName);
if (itemType == Mapper.Null.class) {
unnamed = def;
break;
} else if (itemTypeForFieldName.itemType.isAssignableFrom(itemType)) {
if (def.getItemFieldName() != null) {
if (def.getItemFieldName().equals(itemFieldName)) {
return def.getFieldName();
}
} else {
if (unnamed == null
|| unnamed.getItemType() == null
|| (def.getItemType() != null
&& unnamed.getItemType().isAssignableFrom(def.getItemType()))) {
unnamed = def;
}
}
}
}
if (unnamed != null) {
return unnamed.getFieldName();
} else {
ImplicitCollectionMapperForClass mapper = ImplicitCollectionMapper.this.getMapper(definedIn.getSuperclass(), null);
return mapper != null ? mapper.getFieldNameForItemTypeAndName(itemType, itemFieldName) : null;
}
}
public Class getItemTypeForItemFieldName(String itemFieldName) {
ImplicitCollectionMappingImpl def = getImplicitCollectionDefByItemFieldName(itemFieldName);
if (def != null) {
return def.getItemType();
} else {
ImplicitCollectionMapperForClass mapper = ImplicitCollectionMapper.this.getMapper(definedIn.getSuperclass(), null);
return mapper != null ? mapper.getItemTypeForItemFieldName(itemFieldName) : null;
}
}
private ImplicitCollectionMappingImpl getImplicitCollectionDefByItemFieldName(
String itemFieldName) {
if (itemFieldName == null) {
return null;
} else {
ImplicitCollectionMappingImpl mapping = (ImplicitCollectionMappingImpl)itemFieldNameToDef.get(itemFieldName);
if (mapping != null) {
return mapping;
} else {
ImplicitCollectionMapperForClass mapper = ImplicitCollectionMapper.this.getMapper(definedIn.getSuperclass(), null);
return mapper != null ? mapper.getImplicitCollectionDefByItemFieldName(itemFieldName) : null;
}
}
}
public ImplicitCollectionMapping getImplicitCollectionDefForFieldName(String fieldName) {
ImplicitCollectionMapping mapping = (ImplicitCollectionMapping)fieldNameToDef.get(fieldName);
if (mapping != null) {
return mapping;
} else {
ImplicitCollectionMapperForClass mapper = ImplicitCollectionMapper.this.getMapper(definedIn.getSuperclass(), null);
return mapper != null ? mapper.getImplicitCollectionDefForFieldName(fieldName) : null;
}
}
public void add(ImplicitCollectionMappingImpl def) {
fieldNameToDef.put(def.getFieldName(), def);
namedItemTypeToDef.put(def.createNamedItemType(), def);
if (def.getItemFieldName() != null) {
itemFieldNameToDef.put(def.getItemFieldName(), def);
}
}
}
private static class ImplicitCollectionMappingImpl implements ImplicitCollectionMapping {
private final String fieldName;
private final String itemFieldName;
private final Class itemType;
private final String keyFieldName;
ImplicitCollectionMappingImpl(String fieldName, Class itemType, String itemFieldName, String keyFieldName) {
this.fieldName = fieldName;
this.itemFieldName = itemFieldName;
this.itemType = itemType;
this.keyFieldName = keyFieldName;
}
public NamedItemType createNamedItemType() {
return new NamedItemType(itemType, itemFieldName);
}
public String getFieldName() {
return fieldName;
}
public String getItemFieldName() {
return itemFieldName;
}
public Class getItemType() {
return itemType;
}
public String getKeyFieldName() {
return keyFieldName;
}
}
private static class NamedItemType {
Class itemType;
String itemFieldName;
NamedItemType(Class itemType, String itemFieldName) {
this.itemType = itemType == null ? Object.class : itemType;
this.itemFieldName = itemFieldName;
}
public boolean equals(Object obj) {
if (obj instanceof NamedItemType) {
NamedItemType b = (NamedItemType)obj;
return itemType.equals(b.itemType) && isEquals(itemFieldName, b.itemFieldName);
} else {
return false;
}
}
private static boolean isEquals(Object a, Object b) {
if (a == null) {
return b == null;
} else {
return a.equals(b);
}
}
public int hashCode() {
int hash = itemType.hashCode() << 7;
if (itemFieldName != null) {
hash += itemFieldName.hashCode();
}
return hash;
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy