package net.sourceforge.phpeclipse.wiki.xml; import java.util.ArrayList; import com.thoughtworks.xstream.alias.ClassMapper; import com.thoughtworks.xstream.converters.ConversionException; import com.thoughtworks.xstream.converters.Converter; import com.thoughtworks.xstream.converters.MarshallingContext; import com.thoughtworks.xstream.converters.UnmarshallingContext; import com.thoughtworks.xstream.io.HierarchicalStreamReader; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; /** * Converts a Page object from and to xml */ public class PageConverter implements Converter { protected ClassMapper classMapper; protected String classAttributeIdentifier; public PageConverter(ClassMapper classMapper, String classAttributeIdentifier) { this.classMapper = classMapper; this.classAttributeIdentifier = classAttributeIdentifier; } public boolean canConvert(Class type) { return type.equals(Page.class); } public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { Page page = (Page) source; writer.startNode("title"); writer.setValue(page.title); writer.endNode(); ArrayList list = page.listOfRevisions; for (int i = 0; i < list.size(); i++) { Object item = list.get(i); writeItem(item, context, writer); } } public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { Page page = (Page) createPage(context.getRequiredType()); reader.moveDown(); page.title = (String) reader.getValue(); reader.moveUp(); populatePage(reader, context, page); return page; } protected void populatePage(HierarchicalStreamReader reader, UnmarshallingContext context, Page page) { ArrayList list = page.listOfRevisions; if (list == null) { page.listOfRevisions = new ArrayList(); list = page.listOfRevisions; } while (reader.hasMoreChildren()) { reader.moveDown(); Object item = readItem(reader, context, page); list.add(item); reader.moveUp(); } } protected void writeItem(Object item, MarshallingContext context, HierarchicalStreamWriter writer) { // PUBLISHED API METHOD! If changing signature, ensure backwards compatability. if (item == null) { // todo: this is duplicated in TreeMarshaller.start() writer.startNode(classMapper.lookupName(ClassMapper.Null.class)); writer.endNode(); } else { writer.startNode(classMapper.lookupName(item.getClass())); context.convertAnother(item); writer.endNode(); } } protected Object readItem(HierarchicalStreamReader reader, UnmarshallingContext context, Object current) { // PUBLISHED API METHOD! If changing signature, ensure backwards compatability. String classAttribute = reader.getAttribute(classAttributeIdentifier); Class type; if (classAttribute == null) { type = classMapper.lookupType(reader.getNodeName()); } else { type = classMapper.lookupType(classAttribute); } return context.convertAnother(current, type); } protected Object createPage(Class type) { Class defaultType = classMapper.lookupDefaultType(type); try { return defaultType.newInstance(); } catch (InstantiationException e) { throw new ConversionException("Cannot instantiate " + defaultType.getName(), e); } catch (IllegalAccessException e) { throw new ConversionException("Cannot instantiate " + defaultType.getName(), e); } } }