Skip to content

Commit

Permalink
Added ability to specify XML version when writing xCards.
Browse files Browse the repository at this point in the history
  • Loading branch information
mangstadt committed Oct 14, 2015
1 parent a2a632b commit 10e22e7
Show file tree
Hide file tree
Showing 7 changed files with 412 additions and 65 deletions.
20 changes: 13 additions & 7 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,21 @@
<dependency>
<groupId>xmlunit</groupId>
<artifactId>xmlunit</artifactId>
<version>1.5</version>
<version>1.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.10.19</version>
<scope>test</scope>
</dependency>
<dependency> <!-- For testing XML 1.1 -->
<groupId>xalan</groupId>
<artifactId>xalan</artifactId>
<version>2.7.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.10.19</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
36 changes: 25 additions & 11 deletions src/main/java/ezvcard/io/chain/ChainingXmlWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
*/
public class ChainingXmlWriter extends ChainingWriter<ChainingXmlWriter> {
private int indent = -1;
private String xmlVersion;

/**
* @param vcards the vCards to write
Expand All @@ -59,16 +60,30 @@ public ChainingXmlWriter(Collection<VCard> vcards) {
}

/**
* Sets the number of indent spaces to use for pretty-printing. If not
* set, then the XML will not be pretty-printed.
* @param indent the number of spaces in the indent string
* Sets the number of indent spaces to use for pretty-printing. If not set,
* then the XML will not be pretty-printed.
* @param indent the number of spaces in the indent string (pretty-printing
* disabled by default)
* @return this
*/
public ChainingXmlWriter indent(int indent) {
this.indent = indent;
return this;
}

/**
* Sets the XML version to use. Note that many JDKs only support 1.0
* natively. For XML 1.1 support, add a JAXP library like <a href=
* "http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22xalan%22%20AND%20a%3A%22xalan%22"
* >xalan</a> to your project.
* @param xmlVersion the XML version (defaults to "1.0")
* @return this
*/
public ChainingXmlWriter xmlVersion(String xmlVersion) {
this.xmlVersion = xmlVersion;
return this;
}

@Override
public ChainingXmlWriter prodId(boolean include) {
return super.prodId(include);
Expand All @@ -89,17 +104,17 @@ public ChainingXmlWriter register(VCardPropertyScribe<? extends VCardProperty> s
* @return the XML document
*/
public String go() {
return createXCardDocument().write(indent);
return createXCardDocument().write(indent, xmlVersion);
}

/**
* Writes the xCards to an output stream.
* @param out the output stream to write to
* @throws TransformerException if there's a problem writing to the
* output stream
* @throws TransformerException if there's a problem writing to the output
* stream
*/
public void go(OutputStream out) throws TransformerException {
createXCardDocument().write(out, indent);
createXCardDocument().write(out, indent, xmlVersion);
}

/**
Expand All @@ -109,17 +124,16 @@ public void go(OutputStream out) throws TransformerException {
* @throws TransformerException if there's a problem writing to the file
*/
public void go(File file) throws IOException, TransformerException {
createXCardDocument().write(file, indent);
createXCardDocument().write(file, indent, xmlVersion);
}

/**
* Writes the xCards to a writer.
* @param writer the writer to write to
* @throws TransformerException if there's a problem writing to the
* writer
* @throws TransformerException if there's a problem writing to the writer
*/
public void go(Writer writer) throws TransformerException {
createXCardDocument().write(writer, indent);
createXCardDocument().write(writer, indent, xmlVersion);
}

/**
Expand Down
156 changes: 121 additions & 35 deletions src/main/java/ezvcard/io/xml/XCardDocument.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;

import ezvcard.VCard;
Expand Down Expand Up @@ -278,22 +279,38 @@ public void add(VCard vcard) {
}

/**
* Writes the XML document to a string without pretty-printing it.
* Writes the XML document to a string.
* @return the XML string
*/
public String write() {
return write(-1);
}

/**
* Writes the XML document to a string, pretty-printing the XML string.
* @param indent the number of indent spaces to use for pretty-printing
* Writes the XML document to a string.
* @param indent the number of indent spaces to use for pretty-printing or
* "-1" to disable pretty-printing (disabled by default)
* @return the XML string
*/
public String write(int indent) {
return write(indent, null);
}

/**
* Writes the XML document to a string.
* @param indent the number of indent spaces to use for pretty-printing or
* "-1" to disable pretty-printing (disabled by default)
* @param xmlVersion the XML version to use (defaults to "1.0") (Note: Many
* JDKs only support 1.0 natively. For XML 1.1 support, add a JAXP library
* like <a href=
* "http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22xalan%22%20AND%20a%3A%22xalan%22"
* >xalan</a> to your project)
* @return the XML string
*/
public String write(int indent, String xmlVersion) {
StringWriter sw = new StringWriter();
try {
write(sw, indent);
write(sw, indent, xmlVersion);
} catch (TransformerException e) {
//should not be thrown because we're writing to a string
throw new RuntimeException(e);
Expand All @@ -302,8 +319,8 @@ public String write(int indent) {
}

/**
* Writes the XML document to an output stream without pretty-printing it.
* @param out the output stream
* Writes the XML document to an output stream.
* @param out the output stream (UTF-8 encoding will be used)
* @throws TransformerException if there's a problem writing to the output
* stream
*/
Expand All @@ -312,20 +329,37 @@ public void write(OutputStream out) throws TransformerException {
}

/**
* Writes the XML document to an output stream, pretty-printing the XML
* string.
* @param out the output stream
* @param indent the number of indent spaces to use for pretty-printing
* Writes the XML document to an output stream.
* @param out the output stream (UTF-8 encoding will be used)
* @param indent the number of indent spaces to use for pretty-printing or
* "-1" to disable pretty-printing (disabled by default)
* @throws TransformerException if there's a problem writing to the output
* stream
*/
public void write(OutputStream out, int indent) throws TransformerException {
write(utf8Writer(out), indent);
write(out, indent, null);
}

/**
* Writes the XML document to an output stream.
* @param out the output stream (UTF-8 encoding will be used)
* @param indent the number of indent spaces to use for pretty-printing or
* "-1" to disable pretty-printing (disabled by default)
* @param xmlVersion the XML version to use (defaults to "1.0") (Note: Many
* JDKs only support 1.0 natively. For XML 1.1 support, add a JAXP library
* like <a href=
* "http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22xalan%22%20AND%20a%3A%22xalan%22"
* >xalan</a> to your project)
* @throws TransformerException if there's a problem writing to the output
* stream
*/
public void write(OutputStream out, int indent, String xmlVersion) throws TransformerException {
write(utf8Writer(out), indent, xmlVersion);
}

/**
* Writes the XML document to a file without pretty-printing it.
* @param file the file
* Writes the XML document to a file.
* @param file the file to write to (UTF-8 encoding will be used)
* @throws TransformerException if there's a problem writing to the file
* @throws IOException if there's a problem writing to the file
*/
Expand All @@ -334,23 +368,41 @@ public void write(File file) throws TransformerException, IOException {
}

/**
* Writes the XML document to a file, pretty-printing the XML string.
* @param file the file stream
* @param indent the number of indent spaces to use for pretty-printing
* Writes the XML document to a file.
* @param file the file to write to (UTF-8 encoding will be used)
* @param indent the number of indent spaces to use for pretty-printing or
* "-1" to disable pretty-printing (disabled by default)
* @throws TransformerException if there's a problem writing to the file
* @throws IOException if there's a problem writing to the file
*/
public void write(File file, int indent) throws TransformerException, IOException {
write(file, indent, null);
}

/**
* Writes the XML document to a file.
* @param file the file to write to (UTF-8 encoding will be used)
* @param indent the number of indent spaces to use for pretty-printing or
* "-1" to disable pretty-printing (disabled by default)
* @param xmlVersion the XML version to use (defaults to "1.0") (Note: Many
* JDKs only support 1.0 natively. For XML 1.1 support, add a JAXP library
* like <a href=
* "http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22xalan%22%20AND%20a%3A%22xalan%22"
* >xalan</a> to your project)
* @throws TransformerException if there's a problem writing to the file
* @throws IOException if there's a problem writing to the file
*/
public void write(File file, int indent, String xmlVersion) throws TransformerException, IOException {
Writer writer = utf8Writer(file);
try {
write(writer, indent);
write(writer, indent, xmlVersion);
} finally {
writer.close();
}
}

/**
* Writes the XML document to a writer without pretty-printing it.
* Writes the XML document to a writer.
* @param writer the writer
* @throws TransformerException if there's a problem writing to the writer
*/
Expand All @@ -359,18 +411,42 @@ public void write(Writer writer) throws TransformerException {
}

/**
* Writes the XML document to a writer, pretty-printing the XML string.
* Writes the XML document to a writer.
* @param writer the writer
* @param indent the number of indent spaces to use for pretty-printing
* @param indent the number of indent spaces to use for pretty-printing or
* "-1" to disable pretty-printing (disabled by default)
* @throws TransformerException if there's a problem writing to the writer
*/
public void write(Writer writer, int indent) throws TransformerException {
Map<String, String> properties = new HashMap<String, String>();
write(writer, indent, null);
}

/**
* Writes the XML document to a writer.
* @param writer the writer
* @param indent the number of indent spaces to use for pretty-printing or
* "-1" to disable pretty-printing (disabled by default)
* @param xmlVersion the XML version to use (defaults to "1.0") (Note: Many
* JDKs only support 1.0 natively. For XML 1.1 support, add a JAXP library
* like <a href=
* "http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22xalan%22%20AND%20a%3A%22xalan%22"
* >xalan</a> to your project)
* @throws TransformerException if there's a problem writing to the writer
*/
public void write(Writer writer, int indent, String xmlVersion) throws TransformerException {
Map<String, String> outputProperties = new HashMap<String, String>();
outputProperties.put(OutputKeys.METHOD, "xml");

if (indent >= 0) {
properties.put(OutputKeys.INDENT, "yes");
properties.put("{http://xml.apache.org/xslt}indent-amount", indent + "");
outputProperties.put(OutputKeys.INDENT, "yes");
outputProperties.put("{http://xml.apache.org/xslt}indent-amount", indent + "");
}
XmlUtils.toWriter(document, writer, properties);

if (xmlVersion != null) {
outputProperties.put(OutputKeys.VERSION, xmlVersion);
}

XmlUtils.toWriter(document, writer, outputProperties);
}

private class XCardDocumentStreamReader extends StreamReader {
Expand Down Expand Up @@ -607,27 +683,37 @@ public void close() {

/**
* Marshals a type object to an XML element.
* @param type the type object to marshal
* @param property the property to marshal
* @param vcard the vcard the type belongs to
* @return the XML element
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
private Element marshalProperty(VCardProperty type, VCard vcard) {
VCardPropertyScribe scribe = index.getPropertyScribe(type);
VCardParameters parameters = scribe.prepareParameters(type, version4, vcard);

QName qname = scribe.getQName();
Element propertyElement = createElement(qname);
private Element marshalProperty(VCardProperty property, VCard vcard) {
VCardPropertyScribe scribe = index.getPropertyScribe(property);

Element propertyElement;
if (property instanceof Xml) {
Xml xml = (Xml) property;
Document propertyDocument = xml.getValue();
if (propertyDocument == null) {
throw new SkipMeException();
}
propertyElement = XmlUtils.getRootElement(propertyDocument);
propertyElement = (Element) document.importNode(propertyElement, true);
} else {
QName qname = scribe.getQName();
propertyElement = createElement(qname);
scribe.writeXml(property, propertyElement);
}

//marshal the parameters
VCardParameters parameters = scribe.prepareParameters(property, version4, vcard);
if (!parameters.isEmpty()) {
Element parametersElement = marshalParameters(parameters);
propertyElement.appendChild(parametersElement);
Node firstChild = propertyElement.getFirstChild();
propertyElement.insertBefore(parametersElement, firstChild);
}

//marshal the value
scribe.writeXml(type, propertyElement);

return propertyElement;
}

Expand Down
Loading

0 comments on commit 10e22e7

Please sign in to comment.