package com.revolsys.record.io.format.xml; import java.io.Writer; import java.util.Collection; import java.util.Map; import java.util.Map.Entry; import javax.xml.namespace.QName; import com.revolsys.collection.NameProxy; import com.revolsys.io.AbstractMapWriter; import com.revolsys.io.FileUtil; import com.revolsys.io.IoConstants; public class XmlMapWriter extends AbstractMapWriter { private boolean opened; /** The writer */ private XmlWriter out; private boolean singleObject; public XmlMapWriter(final Writer out) { this.out = new XmlWriter(out); } /** * Closes the underlying reader. */ @Override public void close() { if (this.out != null) { try { if (this.opened) { if (!this.singleObject) { this.out.endTag(); } this.out.endDocument(); } } finally { FileUtil.closeSilent(this.out); this.out = null; } } } @Override public void flush() { this.out.flush(); } private void list(final Collection<? extends Object> list) { for (final Object value : list) { if (value instanceof Map) { final Map<String, ?> map = (Map<String, ?>)value; map(map); } else if (value instanceof Collection) { final Collection<?> subList = (Collection<?>)value; list(subList); } else { this.out.startTag(new QName("item")); this.out.text(value); this.out.endTag(); } } } @SuppressWarnings("unchecked") private void map(final Map<String, ? extends Object> values) { if (values instanceof NameProxy) { final NameProxy namedObject = (NameProxy)values; this.out.startTag(new QName(namedObject.getName())); } else { this.out.startTag(new QName("item")); } for (final Entry<String, ? extends Object> field : values.entrySet()) { final Object key = field.getKey(); final Object value = field.getValue(); final QName tagName = new QName(key.toString()); if (value instanceof Map) { final Map<String, ?> map = (Map<String, ?>)value; this.out.startTag(tagName); map(map); this.out.endTag(); } else if (value instanceof Collection) { final Collection<?> list = (Collection<?>)value; this.out.startTag(tagName); list(list); this.out.endTag(); } else if (isWritable(value)) { this.out.nillableElement(tagName, value); } } this.out.endTag(); } @Override public void setProperty(final String name, final Object value) { super.setProperty(name, value); if (name.equals(IoConstants.INDENT)) { this.out.setIndent((Boolean)value); } } @Override public void write(final Map<String, ? extends Object> values) { if (!this.opened) { writeHeader(); this.opened = true; } map(values); } private void writeHeader() { this.out.startDocument("UTF-8", "1.0"); this.singleObject = Boolean.TRUE.equals(getProperty(IoConstants.SINGLE_OBJECT_PROPERTY)); if (!this.singleObject) { this.out.startTag(new QName("items")); } } }