com.feilong.lib.xstream.core.TreeUnmarshaller Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of feilong Show documentation
Show all versions of feilong Show documentation
feilong is a suite of core and expanded libraries that include utility classes, http, excel,cvs, io classes, and much much more.
/*
* Copyright (C) 2004, 2005, 2006 Joe Walnes.
* Copyright (C) 2006, 2007, 2008, 2009, 2011, 2018 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 15. March 2004 by Joe Walnes
*/
package com.feilong.lib.xstream.core;
import java.util.Iterator;
import com.feilong.lib.xstream.converters.ConversionException;
import com.feilong.lib.xstream.converters.Converter;
import com.feilong.lib.xstream.converters.ConverterLookup;
import com.feilong.lib.xstream.converters.DataHolder;
import com.feilong.lib.xstream.converters.ErrorReporter;
import com.feilong.lib.xstream.converters.ErrorWriter;
import com.feilong.lib.xstream.converters.UnmarshallingContext;
import com.feilong.lib.xstream.core.util.FastStack;
import com.feilong.lib.xstream.core.util.HierarchicalStreams;
import com.feilong.lib.xstream.core.util.PrioritizedList;
import com.feilong.lib.xstream.io.HierarchicalStreamReader;
import com.feilong.lib.xstream.mapper.Mapper;
public class TreeUnmarshaller implements UnmarshallingContext{
private Object root;
protected HierarchicalStreamReader reader;
private ConverterLookup converterLookup;
private Mapper mapper;
private FastStack types = new FastStack(16);
private DataHolder dataHolder;
private final PrioritizedList validationList = new PrioritizedList();
public TreeUnmarshaller(Object root, HierarchicalStreamReader reader, ConverterLookup converterLookup, Mapper mapper){
this.root = root;
this.reader = reader;
this.converterLookup = converterLookup;
this.mapper = mapper;
}
@Override
public Object convertAnother(Object parent,Class type){
return convertAnother(parent, type, null);
}
@Override
public Object convertAnother(Object parent,Class type,Converter converter){
type = mapper.defaultImplementationOf(type);
if (converter == null){
converter = converterLookup.lookupConverterForType(type);
}else{
if (!converter.canConvert(type)){
ConversionException e = new ConversionException("Explicit selected converter cannot handle type");
e.add("item-type", type.getName());
e.add("converter-type", converter.getClass().getName());
throw e;
}
}
return convert(parent, type, converter);
}
protected Object convert(Object parent,Class type,Converter converter){
types.push(type);
try{
return converter.unmarshal(reader, this);
}catch (final ConversionException conversionException){
addInformationTo(conversionException, type, converter, parent);
throw conversionException;
}catch (RuntimeException e){
ConversionException conversionException = new ConversionException(e);
addInformationTo(conversionException, type, converter, parent);
throw conversionException;
}finally{
types.popSilently();
}
}
private void addInformationTo(ErrorWriter errorWriter,Class type,Converter converter,Object parent){
errorWriter.add("class", type.getName());
errorWriter.add("required-type", getRequiredType().getName());
errorWriter.add("converter-type", converter.getClass().getName());
if (converter instanceof ErrorReporter){
((ErrorReporter) converter).appendErrors(errorWriter);
}
if (parent instanceof ErrorReporter){
((ErrorReporter) parent).appendErrors(errorWriter);
}
reader.appendErrors(errorWriter);
}
@Override
public void addCompletionCallback(Runnable work,int priority){
validationList.add(work, priority);
}
@Override
public Object currentObject(){
return types.size() == 1 ? root : null;
}
@Override
public Class getRequiredType(){
return (Class) types.peek();
}
@Override
public Object get(Object key){
lazilyCreateDataHolder();
return dataHolder.get(key);
}
@Override
public void put(Object key,Object value){
lazilyCreateDataHolder();
dataHolder.put(key, value);
}
@Override
public Iterator keys(){
lazilyCreateDataHolder();
return dataHolder.keys();
}
private void lazilyCreateDataHolder(){
if (dataHolder == null){
dataHolder = new MapBackedDataHolder();
}
}
public Object start(DataHolder dataHolder){
this.dataHolder = dataHolder;
Class type = HierarchicalStreams.readClassType(reader, mapper);
Object result = convertAnother(null, type);
Iterator validations = validationList.iterator();
while (validations.hasNext()){
Runnable runnable = (Runnable) validations.next();
runnable.run();
}
return result;
}
protected Mapper getMapper(){
return this.mapper;
}
}