259 lines
14 KiB
Java
259 lines
14 KiB
Java
package com.thoughtworks.xstream.converters.extended;
|
|
|
|
import com.thoughtworks.xstream.converters.ConversionException;
|
|
import com.thoughtworks.xstream.converters.Converter;
|
|
import com.thoughtworks.xstream.converters.ConverterLookup;
|
|
import com.thoughtworks.xstream.converters.ConverterMatcher;
|
|
import com.thoughtworks.xstream.converters.MarshallingContext;
|
|
import com.thoughtworks.xstream.converters.SingleValueConverter;
|
|
import com.thoughtworks.xstream.converters.UnmarshallingContext;
|
|
import com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter;
|
|
import com.thoughtworks.xstream.converters.reflection.ReflectionProvider;
|
|
import com.thoughtworks.xstream.core.JVM;
|
|
import com.thoughtworks.xstream.core.util.FastField;
|
|
import com.thoughtworks.xstream.core.util.HierarchicalStreams;
|
|
import com.thoughtworks.xstream.core.util.Primitives;
|
|
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
|
|
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
|
|
import com.thoughtworks.xstream.mapper.Mapper;
|
|
import java.lang.reflect.Field;
|
|
import java.lang.reflect.Modifier;
|
|
import java.util.HashMap;
|
|
import java.util.HashSet;
|
|
import java.util.Iterator;
|
|
|
|
/* loaded from: classes.dex */
|
|
public class ToAttributedValueConverter implements Converter {
|
|
private static final String STRUCTURE_MARKER = "";
|
|
private final Mapper enumMapper;
|
|
private final ConverterLookup lookup;
|
|
private final Mapper mapper;
|
|
private final ReflectionProvider reflectionProvider;
|
|
private final Class type;
|
|
private final Field valueField;
|
|
|
|
public ToAttributedValueConverter(Class cls, Mapper mapper, ReflectionProvider reflectionProvider, ConverterLookup converterLookup) {
|
|
this(cls, mapper, reflectionProvider, converterLookup, null, null);
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
public boolean fieldIsEqual(FastField fastField) {
|
|
return this.valueField.getName().equals(fastField.getName()) && this.valueField.getDeclaringClass().getName().equals(fastField.getDeclaringClass());
|
|
}
|
|
|
|
@Override // com.thoughtworks.xstream.converters.ConverterMatcher
|
|
public boolean canConvert(Class cls) {
|
|
return this.type == cls;
|
|
}
|
|
|
|
@Override // com.thoughtworks.xstream.converters.Converter
|
|
public void marshal(Object obj, final HierarchicalStreamWriter hierarchicalStreamWriter, MarshallingContext marshallingContext) {
|
|
String aliasForSystemAttribute;
|
|
final Class<?> cls = obj.getClass();
|
|
final HashMap hashMap = new HashMap();
|
|
final String[] strArr = new String[1];
|
|
final Object[] objArr = new Object[1];
|
|
final Class[] clsArr = new Class[1];
|
|
final Class[] clsArr2 = new Class[1];
|
|
this.reflectionProvider.visitSerializableFields(obj, new ReflectionProvider.Visitor() { // from class: com.thoughtworks.xstream.converters.extended.ToAttributedValueConverter.1
|
|
@Override // com.thoughtworks.xstream.converters.reflection.ReflectionProvider.Visitor
|
|
public void visit(String str, Class cls2, Class cls3, Object obj2) {
|
|
if (ToAttributedValueConverter.this.mapper.shouldSerializeMember(cls3, str)) {
|
|
FastField fastField = new FastField(cls3, str);
|
|
String serializedMember = ToAttributedValueConverter.this.mapper.serializedMember(cls3, str);
|
|
if (!hashMap.containsKey(serializedMember)) {
|
|
hashMap.put(serializedMember, ToAttributedValueConverter.this.reflectionProvider.getField(cls, str));
|
|
} else if (!ToAttributedValueConverter.this.fieldIsEqual(fastField)) {
|
|
ConversionException conversionException = new ConversionException("Cannot write attribute twice for object");
|
|
conversionException.add("alias", serializedMember);
|
|
conversionException.add("type", cls.getName());
|
|
throw conversionException;
|
|
}
|
|
ConverterMatcher converterFromItemType = UseAttributeForEnumMapper.isEnum(cls2) ? ToAttributedValueConverter.this.enumMapper.getConverterFromItemType(null, cls2, null) : ToAttributedValueConverter.this.mapper.getLocalConverter(cls3, str);
|
|
if (converterFromItemType == null) {
|
|
converterFromItemType = ToAttributedValueConverter.this.lookup.lookupConverterForType(cls2);
|
|
}
|
|
if (obj2 != null) {
|
|
boolean z = ToAttributedValueConverter.this.valueField != null && ToAttributedValueConverter.this.fieldIsEqual(fastField);
|
|
if (z) {
|
|
clsArr2[0] = cls3;
|
|
clsArr[0] = cls2;
|
|
objArr[0] = obj2;
|
|
strArr[0] = "";
|
|
}
|
|
if (!(converterFromItemType instanceof SingleValueConverter)) {
|
|
if (z) {
|
|
return;
|
|
}
|
|
ConversionException conversionException2 = new ConversionException("Cannot write element as attribute");
|
|
conversionException2.add("alias", serializedMember);
|
|
conversionException2.add("type", cls.getName());
|
|
throw conversionException2;
|
|
}
|
|
String singleValueConverter = ((SingleValueConverter) converterFromItemType).toString(obj2);
|
|
if (z) {
|
|
strArr[0] = singleValueConverter;
|
|
} else if (singleValueConverter != null) {
|
|
hierarchicalStreamWriter.addAttribute(serializedMember, singleValueConverter);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
if (strArr[0] != null) {
|
|
Class<?> cls2 = objArr[0].getClass();
|
|
Class defaultImplementationOf = this.mapper.defaultImplementationOf(clsArr[0]);
|
|
if (!cls2.equals(defaultImplementationOf)) {
|
|
String serializedClass = this.mapper.serializedClass(cls2);
|
|
if (!serializedClass.equals(this.mapper.serializedClass(defaultImplementationOf)) && (aliasForSystemAttribute = this.mapper.aliasForSystemAttribute("class")) != null) {
|
|
hierarchicalStreamWriter.addAttribute(aliasForSystemAttribute, serializedClass);
|
|
}
|
|
}
|
|
if (strArr[0] == "") {
|
|
marshallingContext.convertAnother(objArr[0]);
|
|
} else {
|
|
hierarchicalStreamWriter.setValue(strArr[0]);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override // com.thoughtworks.xstream.converters.Converter
|
|
public Object unmarshal(HierarchicalStreamReader hierarchicalStreamReader, UnmarshallingContext unmarshallingContext) {
|
|
Class<?> cls;
|
|
Iterator it;
|
|
HashSet hashSet;
|
|
ConverterMatcher localConverter;
|
|
Object newInstance = this.reflectionProvider.newInstance(unmarshallingContext.getRequiredType());
|
|
Class<?> cls2 = newInstance.getClass();
|
|
HashSet hashSet2 = new HashSet();
|
|
Iterator attributeNames = hierarchicalStreamReader.getAttributeNames();
|
|
HashSet hashSet3 = new HashSet();
|
|
hashSet3.add(this.mapper.aliasForSystemAttribute("class"));
|
|
while (attributeNames.hasNext()) {
|
|
String str = (String) attributeNames.next();
|
|
if (!hashSet3.contains(str)) {
|
|
String realMember = this.mapper.realMember(cls2, str);
|
|
Field fieldOrNull = this.reflectionProvider.getFieldOrNull(cls2, realMember);
|
|
if (fieldOrNull == null) {
|
|
cls = cls2;
|
|
it = attributeNames;
|
|
hashSet = hashSet3;
|
|
} else if (Modifier.isTransient(fieldOrNull.getModifiers())) {
|
|
continue;
|
|
} else {
|
|
it = attributeNames;
|
|
Class<?> type = fieldOrNull.getType();
|
|
Class<?> declaringClass = fieldOrNull.getDeclaringClass();
|
|
if (UseAttributeForEnumMapper.isEnum(type)) {
|
|
hashSet = hashSet3;
|
|
cls = cls2;
|
|
localConverter = this.enumMapper.getConverterFromItemType(null, type, null);
|
|
} else {
|
|
cls = cls2;
|
|
hashSet = hashSet3;
|
|
localConverter = this.mapper.getLocalConverter(declaringClass, realMember);
|
|
}
|
|
if (localConverter == null) {
|
|
localConverter = this.lookup.lookupConverterForType(type);
|
|
}
|
|
if (!(localConverter instanceof SingleValueConverter)) {
|
|
ConversionException conversionException = new ConversionException("Cannot read field as a single value for object");
|
|
conversionException.add("field", realMember);
|
|
conversionException.add("type", cls.getName());
|
|
throw conversionException;
|
|
}
|
|
if (localConverter != null) {
|
|
Object fromString = ((SingleValueConverter) localConverter).fromString(hierarchicalStreamReader.getAttribute(str));
|
|
if (type.isPrimitive()) {
|
|
type = Primitives.box(type);
|
|
}
|
|
if (fromString != null && !type.isAssignableFrom(fromString.getClass())) {
|
|
ConversionException conversionException2 = new ConversionException("Cannot assign object to type");
|
|
conversionException2.add("object type", fromString.getClass().getName());
|
|
conversionException2.add("target type", type.getName());
|
|
throw conversionException2;
|
|
}
|
|
this.reflectionProvider.writeField(newInstance, realMember, fromString, declaringClass);
|
|
if (!hashSet2.add(new FastField(declaringClass, realMember))) {
|
|
StringBuffer stringBuffer = new StringBuffer();
|
|
stringBuffer.append(realMember);
|
|
stringBuffer.append(" [");
|
|
stringBuffer.append(declaringClass.getName());
|
|
stringBuffer.append("]");
|
|
throw new AbstractReflectionConverter.DuplicateFieldException(stringBuffer.toString());
|
|
}
|
|
}
|
|
}
|
|
attributeNames = it;
|
|
hashSet3 = hashSet;
|
|
cls2 = cls;
|
|
}
|
|
}
|
|
Field field = this.valueField;
|
|
if (field != null) {
|
|
Class<?> declaringClass2 = field.getDeclaringClass();
|
|
String name = this.valueField.getName();
|
|
Field field2 = name == null ? null : this.reflectionProvider.getField(declaringClass2, name);
|
|
if (name == null || field2 == null) {
|
|
ConversionException conversionException3 = new ConversionException("Cannot assign value to field of type");
|
|
conversionException3.add("element", hierarchicalStreamReader.getNodeName());
|
|
conversionException3.add("field", name);
|
|
conversionException3.add("target type", unmarshallingContext.getRequiredType().getName());
|
|
throw conversionException3;
|
|
}
|
|
String readClassAttribute = HierarchicalStreams.readClassAttribute(hierarchicalStreamReader, this.mapper);
|
|
Class realClass = readClassAttribute != null ? this.mapper.realClass(readClassAttribute) : this.mapper.defaultImplementationOf(this.reflectionProvider.getFieldType(newInstance, name, declaringClass2));
|
|
Object convertAnother = unmarshallingContext.convertAnother(newInstance, realClass, this.mapper.getLocalConverter(field2.getDeclaringClass(), field2.getName()));
|
|
Class fieldType = this.reflectionProvider.getFieldType(newInstance, name, declaringClass2);
|
|
if (!fieldType.isPrimitive()) {
|
|
realClass = fieldType;
|
|
}
|
|
if (convertAnother != null && !realClass.isAssignableFrom(convertAnother.getClass())) {
|
|
ConversionException conversionException4 = new ConversionException("Cannot assign object to type");
|
|
conversionException4.add("object type", convertAnother.getClass().getName());
|
|
conversionException4.add("target type", realClass.getName());
|
|
throw conversionException4;
|
|
}
|
|
this.reflectionProvider.writeField(newInstance, name, convertAnother, declaringClass2);
|
|
if (!hashSet2.add(new FastField(declaringClass2, name))) {
|
|
StringBuffer stringBuffer2 = new StringBuffer();
|
|
stringBuffer2.append(name);
|
|
stringBuffer2.append(" [");
|
|
stringBuffer2.append(declaringClass2.getName());
|
|
stringBuffer2.append("]");
|
|
throw new AbstractReflectionConverter.DuplicateFieldException(stringBuffer2.toString());
|
|
}
|
|
}
|
|
return newInstance;
|
|
}
|
|
|
|
public ToAttributedValueConverter(Class cls, Mapper mapper, ReflectionProvider reflectionProvider, ConverterLookup converterLookup, String str) {
|
|
this(cls, mapper, reflectionProvider, converterLookup, str, null);
|
|
}
|
|
|
|
public ToAttributedValueConverter(Class cls, Mapper mapper, ReflectionProvider reflectionProvider, ConverterLookup converterLookup, String str, Class cls2) {
|
|
this.type = cls;
|
|
this.mapper = mapper;
|
|
this.reflectionProvider = reflectionProvider;
|
|
this.lookup = converterLookup;
|
|
if (str == null) {
|
|
this.valueField = null;
|
|
} else {
|
|
try {
|
|
Field declaredField = (cls2 != null ? cls2 : cls).getDeclaredField(str);
|
|
if (!declaredField.isAccessible()) {
|
|
declaredField.setAccessible(true);
|
|
}
|
|
this.valueField = declaredField;
|
|
} catch (NoSuchFieldException e) {
|
|
StringBuffer stringBuffer = new StringBuffer();
|
|
stringBuffer.append(e.getMessage());
|
|
stringBuffer.append(": ");
|
|
stringBuffer.append(str);
|
|
throw new IllegalArgumentException(stringBuffer.toString());
|
|
}
|
|
}
|
|
this.enumMapper = JVM.isVersion(5) ? UseAttributeForEnumMapper.createEnumMapper(mapper) : null;
|
|
}
|
|
}
|