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 10 public class ReferenceByIdMarshaller extends TreeMarshaller { 11 12 private ObjectIdDictionary references = new ObjectIdDictionary(); 13 private IDGenerator idGenerator; 14 15 public static interface IDGenerator { 16 String next(); 17 } 18 19 public ReferenceByIdMarshaller(HierarchicalStreamWriter writer, 20 ConverterLookup converterLookup, 21 ClassMapper classMapper, 22 IDGenerator idGenerator) { 23 super(writer, converterLookup, classMapper); 24 this.idGenerator = idGenerator; 25 } 26 27 public ReferenceByIdMarshaller(HierarchicalStreamWriter writer, 28 ConverterLookup converterLookup, 29 ClassMapper classMapper) { 30 this(writer, converterLookup, classMapper, new SequenceGenerator(1)); 31 } 32 33 public void convertAnother(Object item) { 34 Converter converter = converterLookup.lookupConverterForType(item.getClass()); 35 36 if (isImmutableBasicType(converter)) { 37 converter.marshal(item, writer, this); 39 } else { 40 String idOfExistingReference = references.lookupId(item); 41 if (idOfExistingReference != null) { 42 writer.addAttribute("reference", idOfExistingReference); 43 } else { 44 String newId = idGenerator.next(); 45 writer.addAttribute("id", newId); 46 references.associateId(item, newId); 47 converter.marshal(item, writer, this); 48 } 49 } 50 } 51 52 private boolean isImmutableBasicType(Converter converter) { 53 return converter instanceof AbstractBasicConverter; 54 } 55 56 } 57 | Popular Tags |