1 package com.thoughtworks.xstream.core; 2 3 import com.thoughtworks.xstream.alias.ClassMapper; 4 import com.thoughtworks.xstream.converters.Converter; 5 import com.thoughtworks.xstream.converters.ConverterLookup; 6 import com.thoughtworks.xstream.converters.basic.AbstractBasicConverter; 7 import com.thoughtworks.xstream.core.util.ObjectIdDictionary; 8 import com.thoughtworks.xstream.io.HierarchicalStreamWriter; 9 import com.thoughtworks.xstream.io.path.PathTracker; 10 import com.thoughtworks.xstream.io.path.PathTrackingWriter; 11 import com.thoughtworks.xstream.io.path.RelativePathCalculator; 12 13 public class ReferenceByXPathMarshaller extends TreeMarshaller { 14 15 private PathTracker pathTracker = new PathTracker(); 16 private ObjectIdDictionary references = new ObjectIdDictionary(); 17 private RelativePathCalculator relativePathCalculator = new RelativePathCalculator(); 18 19 public ReferenceByXPathMarshaller(HierarchicalStreamWriter writer, ConverterLookup converterLookup, ClassMapper classMapper) { 20 super(writer, converterLookup, classMapper); 21 this.writer = new PathTrackingWriter(writer, pathTracker); 22 } 23 24 public void convertAnother(Object item) { 25 Converter converter = converterLookup.lookupConverterForType(item.getClass()); 26 27 if (isImmutableBasicType(converter)) { 28 converter.marshal(item, writer, this); 30 } else { 31 String currentPath = pathTracker.getCurrentPath(); 32 String pathOfExistingReference = references.lookupId(item); 33 if (pathOfExistingReference != null) { 34 String absolutePath = relativePathCalculator.relativePath(currentPath, pathOfExistingReference); 35 writer.addAttribute("reference", absolutePath); 36 } else { 37 references.associateId(item, currentPath); 38 converter.marshal(item, writer, this); 39 } 40 } 41 } 42 43 private boolean isImmutableBasicType(Converter converter) { 44 return converter instanceof AbstractBasicConverter; 45 } 46 } 47 | Popular Tags |