Details
-
Type: Bug
-
Status: Closed
-
Resolution: Won't Fix
-
Affects Version/s: None
-
Fix Version/s: None
-
Component/s: None
-
Labels:None
Description
TreeUnmarshaller does not currently implement the currentObject() method. It always returns "root" (which is always null...) It should keep a stack of objects, so that when users call
Object newChild = context.convertAnother(thisParent, valueType);
in the "parent" unmarshaller, the child unmarshaller can do the following:
Object myParent = context.currentObject();
Have fixed this, however. This required creating a new class (ObjectStack - it is identical to ClassStack, but substituting type Object for type Class), and then adding the stack operations to TreeUnmarshaller.
The new class is included here:
=====================================================================
package com.thoughtworks.xstream.core.util;
public final class ObjectStack {
private Object[] stack;
private int pointer;
public ObjectStack(int initialCapacity)
{ stack = new Object[initialCapacity]; } public void push(Object value) {
if (pointer + 1 >= stack.length)
stack[pointer++] = value;
}
public void popSilently()
{ pointer--; }public Object pop()
{ return stack[--pointer]; }public Object peek()
{ return pointer == 0 ? null : stack[pointer - 1]; }public int size()
{ return pointer; }public Object get(int i)
{ return stack[i]; }private void resizeStack(int newCapacity)
{ Object[] newStack = new Object[newCapacity]; System.arraycopy(stack, 0, newStack, 0, Math.min(stack.length, newCapacity)); stack = newStack; }}
=====================================================================
The MODIFIED version of TreeUnmarshaller is included here (sorry, no diff)
=====================================================================
package com.thoughtworks.xstream.core;
import com.thoughtworks.xstream.alias.ClassMapper;
import com.thoughtworks.xstream.converters.*;
import com.thoughtworks.xstream.core.util.ClassStack;
import com.thoughtworks.xstream.core.util.ObjectStack;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
public class TreeUnmarshaller implements UnmarshallingContext {
private Object root;
protected HierarchicalStreamReader reader;
private ConverterLookup converterLookup;
private ClassMapper classMapper;
private String classAttributeIdentifier;
private ClassStack types = new ClassStack(16);
private ObjectStack currentObjects = new ObjectStack(16);
public TreeUnmarshaller(Object root, HierarchicalStreamReader reader,
ConverterLookup converterLookup, ClassMapper classMapper,
String classAttributeIdentifier)
public Object convertAnother(Object current, Class type) {
try
catch (ConversionException conversionException)
{ addInformationTo(conversionException, type); throw conversionException; }catch (RuntimeException e)
{ ConversionException conversionException = new ConversionException(e); addInformationTo(conversionException, type); throw conversionException; }}
private void addInformationTo(ErrorWriter errorWriter, Class type)
{ errorWriter.add("class", type.getName()); errorWriter.add("required-type", getRequiredType().getName()); reader.appendErrors(errorWriter); }public Object currentObject()
{ return currentObjects.peek(); }public Class getRequiredType()
{ return types.peek(); } public Object start() {
String classAttribute = reader.getAttribute(classAttributeIdentifier);
Class type;
if (classAttribute == null)
else
{ type = classMapper.lookupType(classAttribute); } return convertAnother(root, type);
}
}
=====================================================================
Issue Links
- is duplicated by
-
XSTR-482 CLONE -TreeUnmarshaller does not correctly implement currentObject()
I downloaded that latest version of TreeUnmarshaller (v1.6 I believe) and applied the changes I mentioned in the issue desc. Assuming there have been no changes since then (doubtful), this version should work as is...(don't forget the new ObjectStack class too...)