| package org.unicode.cldr.draft.keyboard.out; |
| |
| import static com.google.common.base.Preconditions.checkNotNull; |
| import static com.google.common.base.Preconditions.checkState; |
| |
| import java.io.Writer; |
| import java.util.Map; |
| import java.util.Map.Entry; |
| |
| import javax.xml.stream.XMLOutputFactory; |
| import javax.xml.stream.XMLStreamException; |
| import javax.xml.stream.XMLStreamWriter; |
| |
| import com.google.common.collect.ImmutableMap; |
| |
| /** |
| * Object which wraps around an XML stream writer. Automatically adds proper formatting |
| * (indentation and line breaks) to the written XML elements. |
| */ |
| final class XmlWriter { |
| private final XMLStreamWriter writer; |
| private int depth = 0; |
| |
| private XmlWriter(XMLStreamWriter writer) { |
| this.writer = checkNotNull(writer); |
| } |
| |
| static XmlWriter newXmlWriter(Writer writer) { |
| XMLOutputFactory outputFactory = XMLOutputFactory.newInstance(); |
| XMLStreamWriter xmlStreamWriter; |
| try { |
| xmlStreamWriter = outputFactory.createXMLStreamWriter(writer); |
| } catch (XMLStreamException e) { |
| throw new RuntimeException(e); |
| } |
| return new XmlWriter(xmlStreamWriter); |
| } |
| |
| XmlWriter startDocument(String doctype, String dtdLocation) { |
| try { |
| writer.writeStartDocument("UTF-8", "1.0"); |
| writer.writeCharacters("\n"); |
| writer.writeDTD("<!DOCTYPE " + doctype + " SYSTEM \"" + dtdLocation + "\">"); |
| writer.writeCharacters("\n"); |
| } catch (XMLStreamException e) { |
| throw new RuntimeException(e); |
| } |
| return this; |
| } |
| |
| XmlWriter endDocument() { |
| checkState(depth == 0, "Cannot close document with unclosed elements"); |
| try { |
| writer.writeEndDocument(); |
| writer.close(); |
| } catch (XMLStreamException e) { |
| throw new RuntimeException(e); |
| } |
| return this; |
| } |
| |
| XmlWriter startElement(String name) { |
| return startElement(name, ImmutableMap.<String, Object>of()); |
| } |
| |
| XmlWriter startElement(String name, Map<String, ?> attributeToValue) { |
| addIndent(); |
| try { |
| writer.writeStartElement(name); |
| for (Entry<String, ?> entry : attributeToValue.entrySet()) { |
| writer.writeAttribute(entry.getKey(), "" + entry.getValue()); |
| } |
| writer.writeCharacters("\n"); |
| } catch (XMLStreamException e) { |
| throw new RuntimeException(e); |
| } |
| depth++; |
| return this; |
| } |
| |
| XmlWriter endElement() { |
| depth--; |
| addIndent(); |
| try { |
| writer.writeEndElement(); |
| writer.writeCharacters("\n"); |
| } catch (XMLStreamException e) { |
| throw new RuntimeException(e); |
| } |
| return this; |
| } |
| |
| XmlWriter addElement(String name, Map<String, ?> attributeToValue) { |
| return addElement(name, attributeToValue, ""); |
| } |
| |
| XmlWriter addElement(String name, Map<String, ?> attributeToValue, String comment) { |
| addIndent(); |
| try { |
| writer.writeEmptyElement(name); |
| for (Entry<String, ?> entry : attributeToValue.entrySet()) { |
| writer.writeAttribute(entry.getKey(), "" + entry.getValue()); |
| } |
| if (!comment.isEmpty()) { |
| writer.writeCharacters(" "); |
| writer.writeComment(" " + comment + " "); |
| } |
| writer.writeCharacters("\n"); |
| } catch (XMLStreamException e) { |
| throw new RuntimeException(e); |
| } |
| return this; |
| } |
| |
| private void addIndent() { |
| for (int i = 0; i < depth; i++) { |
| try { |
| writer.writeCharacters("\t"); |
| } catch (XMLStreamException e) { |
| throw new RuntimeException(e); |
| } |
| } |
| } |
| } |