package com.t3.xstreamversioned.model; import java.util.HashMap; import org.apache.commons.lang3.StringUtils; import com.t3.xstreamversioned.version.Version; import com.thoughtworks.xstream.converters.UnmarshallingContext; import com.thoughtworks.xstream.io.HierarchicalStreamReader; public class GenericObjectManager { private HashMap<Integer, GenericObject> parsedObjects=new HashMap<>(); private int nextId=0; private int nextNegativeId=-1; public GenericObject parse(HierarchicalStreamReader reader, UnmarshallingContext context) { int internalId=reader.getAttribute("id")==null?nextNegativeId--:Integer.parseInt(reader.getAttribute("id")); GenericObject go=new GenericObject(this,internalId); parsedObjects.put(internalId, go); nextId=Math.max(internalId+1, nextId); go.setName(reader.getNodeName()); //collect all attributes to ensure compatibility HashMap<String, String> xStreamAttributes=new HashMap<String, String>(); for(int i=0;i<reader.getAttributeCount();i++) { String attrName=reader.getAttributeName(i); if(!"version".equals(attrName)) xStreamAttributes.put(attrName, reader.getAttribute(i)); } go.setXStreamAttributes(xStreamAttributes); //version String version=reader.getAttribute("version"); if(version!=null) go.setCurrentVersion(Version.parseVersion(version)); //reference String referencedId=reader.getAttribute("reference"); if(referencedId!=null) { GenericObject ref=parsedObjects.get(Integer.parseInt(referencedId)); if(ref==null) throw new RuntimeException("Reference to object "+referencedId+" before it occured directly"); else go.setReferencing(ref); } //child elements or content if(reader.hasMoreChildren()) { while(reader.hasMoreChildren()) { reader.moveDown(); go.addChild(parse(reader, null)); reader.moveUp(); } } else go.setContent(reader.getValue()); return go; } public GenericObject getObject(Integer childId) { GenericObject go=parsedObjects.get(childId); if(go==null) throw new IllegalArgumentException("No Object of id "+childId+" was parsed."); else return go; } public GenericObject createObject() { GenericObject go= new GenericObject(this, nextId++); parsedObjects.put(go.getInternalId(), go); return go; } public void updateObject(GenericObject go) { parsedObjects.put(go.getInternalId(), go); } }