// this is an array as it's a non final value that's accessed from an anonymous inner class.
final Class[] currentType = new Class[1];
String attributeName = mapper.aliasForSystemAttribute(ATTRIBUTE_SERIALIZATION);
if (attributeName != null && !ATTRIBUTE_VALUE_CUSTOM.equals(reader.getAttribute(attributeName))) {
throw new ConversionException("Cannot deserialize object with new readObject()/writeObject() methods");
}
CustomObjectInputStream.StreamCallback callback = new CustomObjectInputStream.StreamCallback() {
public Object readFromStream() {
reader.moveDown();
Class type = HierarchicalStreams.readClassType(reader, mapper);
Object value = context.convertAnother(result, type);
reader.moveUp();
return value;
}
public Map readFieldsFromStream() {
final Map fields = new HashMap();
reader.moveDown();
if (reader.getNodeName().equals(ELEMENT_FIELDS)) {
// Maintain compatibility with XStream 1.1.0
while (reader.hasMoreChildren()) {
reader.moveDown();
if (!reader.getNodeName().equals(ELEMENT_FIELD)) {
throw new ConversionException("Expected <" + ELEMENT_FIELD + "/> element inside <" + ELEMENT_FIELD + "/>");
}
String name = reader.getAttribute(ATTRIBUTE_NAME);
Class type = mapper.realClass(reader.getAttribute(ATTRIBUTE_CLASS));
Object value = context.convertAnother(result, type);
fields.put(name, value);
reader.moveUp();
}
} else if (reader.getNodeName().equals(ELEMENT_DEFAULT)) {
// New format introduced in XStream 1.1.1
ObjectStreamClass objectStreamClass = ObjectStreamClass.lookup(currentType[0]);
while (reader.hasMoreChildren()) {
reader.moveDown();
String name = mapper.realMember(currentType[0], reader.getNodeName());
if (mapper.shouldSerializeMember(currentType[0], name)) {
String classAttribute = HierarchicalStreams.readClassAttribute(reader, mapper);
Class type;
if (classAttribute != null) {
type = mapper.realClass(classAttribute);
} else {
ObjectStreamField field = objectStreamClass.getField(name);
if (field == null) {
throw new ObjectAccessException("Class " + currentType[0]
+ " does not contain a field named '" + name + "'");
}
type = field.getType();
}
Object value = context.convertAnother(result, type);
fields.put(name, value);
}
reader.moveUp();
}
} else {
throw new ConversionException("Expected <" + ELEMENT_FIELDS + "/> or <" +
ELEMENT_DEFAULT + "/> element when calling ObjectInputStream.readFields()");
}
reader.moveUp();
return fields;
}
public void defaultReadObject() {
if (!reader.hasMoreChildren()) {
return;
}
reader.moveDown();
if (!reader.getNodeName().equals(ELEMENT_DEFAULT)) {
throw new ConversionException("Expected <" + ELEMENT_DEFAULT + "/> element in readObject() stream");
}
while (reader.hasMoreChildren()) {
reader.moveDown();
String fieldName = mapper.realMember(currentType[0], reader.getNodeName());