001package ezvcard.io.chain; 002 003import java.io.IOException; 004import java.io.OutputStream; 005import java.io.Writer; 006import java.nio.file.Path; 007import java.util.Collection; 008import java.util.HashMap; 009import java.util.Map; 010 011import javax.xml.transform.Transformer; 012import javax.xml.transform.TransformerException; 013 014import org.w3c.dom.Document; 015 016import ezvcard.Ezvcard; 017import ezvcard.VCard; 018import ezvcard.VCardDataType; 019import ezvcard.io.scribe.VCardPropertyScribe; 020import ezvcard.io.xml.XCardDocument; 021import ezvcard.io.xml.XCardDocument.XCardDocumentStreamWriter; 022import ezvcard.io.xml.XCardOutputProperties; 023import ezvcard.property.VCardProperty; 024 025/* 026 Copyright (c) 2012-2023, Michael Angstadt 027 All rights reserved. 028 029 Redistribution and use in source and binary forms, with or without 030 modification, are permitted provided that the following conditions are met: 031 032 1. Redistributions of source code must retain the above copyright notice, this 033 list of conditions and the following disclaimer. 034 2. Redistributions in binary form must reproduce the above copyright notice, 035 this list of conditions and the following disclaimer in the documentation 036 and/or other materials provided with the distribution. 037 038 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 039 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 040 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 041 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 042 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 043 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 044 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 045 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 046 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 047 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 048 */ 049 050/** 051 * Chainer class for writing xCards (XML-encoded vCards). 052 * @see Ezvcard#writeXml(Collection) 053 * @see Ezvcard#writeXml(VCard...) 054 * @author Michael Angstadt 055 */ 056public class ChainingXmlWriter extends ChainingWriter<ChainingXmlWriter> { 057 private final XCardOutputProperties outputProperties = new XCardOutputProperties(); 058 private final Map<String, VCardDataType> parameterDataTypes = new HashMap<>(0); 059 060 /** 061 * @param vcards the vCards to write 062 */ 063 public ChainingXmlWriter(Collection<VCard> vcards) { 064 super(vcards); 065 } 066 067 /** 068 * Sets the number of indent spaces to use for pretty-printing. If not set, 069 * then the XML will not be pretty-printed. 070 * @param indent the number of spaces in the indent string or null not to 071 * pretty-print (disabled by default) 072 * @return this 073 */ 074 public ChainingXmlWriter indent(Integer indent) { 075 outputProperties.setIndent(indent); 076 return this; 077 } 078 079 /** 080 * Sets the XML version to use. Note that many JDKs only support 1.0 081 * natively. For XML 1.1 support, add a JAXP library like <a href= 082 * "http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22xalan%22%20AND%20a%3A%22xalan%22" 083 * >xalan</a> to your project. 084 * @param xmlVersion the XML version (defaults to "1.0") 085 * @return this 086 */ 087 public ChainingXmlWriter xmlVersion(String xmlVersion) { 088 outputProperties.setXmlVersion(xmlVersion); 089 return this; 090 } 091 092 /** 093 * Assigns an output property to the JAXP transformer (see 094 * {@link Transformer#setOutputProperty}). 095 * @param name the property name 096 * @param value the property value 097 * @return this 098 */ 099 public ChainingXmlWriter outputProperty(String name, String value) { 100 outputProperties.put(name, value); 101 return this; 102 } 103 104 /** 105 * Assigns all of the given output properties to the JAXP transformer (see 106 * {@link Transformer#setOutputProperty}). 107 * @param outputProperties the properties 108 * @return this 109 */ 110 public ChainingXmlWriter outputProperties(Map<String, String> outputProperties) { 111 this.outputProperties.putAll(outputProperties); 112 return this; 113 } 114 115 @Override 116 public ChainingXmlWriter prodId(boolean include) { 117 return super.prodId(include); 118 } 119 120 @Override 121 public ChainingXmlWriter versionStrict(boolean versionStrict) { 122 return super.versionStrict(versionStrict); 123 } 124 125 @Override 126 public ChainingXmlWriter register(VCardPropertyScribe<? extends VCardProperty> scribe) { 127 return super.register(scribe); 128 } 129 130 /** 131 * Registers the data type of a non-standard parameter. Non-standard 132 * parameters use the "unknown" data type by default. 133 * @param parameterName the parameter name (e.g. "x-foo") 134 * @param dataType the data type 135 * @return this 136 */ 137 public ChainingXmlWriter register(String parameterName, VCardDataType dataType) { 138 parameterDataTypes.put(parameterName, dataType); 139 return this; 140 } 141 142 /** 143 * Writes the xCards to a string. 144 * @return the XML document 145 */ 146 public String go() { 147 return createXCardDocument().write(outputProperties); 148 } 149 150 /** 151 * Writes the xCards to an output stream. 152 * @param out the output stream to write to 153 * @throws TransformerException if there's a problem writing to the output 154 * stream 155 */ 156 public void go(OutputStream out) throws TransformerException { 157 createXCardDocument().write(out, outputProperties); 158 } 159 160 /** 161 * Writes the xCards to a file. 162 * @param file the file to write to 163 * @throws IOException if the file can't be opened 164 * @throws TransformerException if there's a problem writing to the file 165 */ 166 public void go(Path file) throws IOException, TransformerException { 167 createXCardDocument().write(file, outputProperties); 168 } 169 170 /** 171 * Writes the xCards to a writer. 172 * @param writer the writer to write to 173 * @throws TransformerException if there's a problem writing to the writer 174 */ 175 public void go(Writer writer) throws TransformerException { 176 createXCardDocument().write(writer, outputProperties); 177 } 178 179 /** 180 * Generates an XML document object model (DOM) containing the xCards. 181 * @return the DOM 182 */ 183 public Document dom() { 184 return createXCardDocument().getDocument(); 185 } 186 187 private XCardDocument createXCardDocument() { 188 XCardDocument document = new XCardDocument(); 189 190 XCardDocumentStreamWriter writer = document.writer(); 191 writer.setAddProdId(prodId); 192 writer.setVersionStrict(versionStrict); 193 for (Map.Entry<String, VCardDataType> entry : parameterDataTypes.entrySet()) { 194 String parameterName = entry.getKey(); 195 VCardDataType dataType = entry.getValue(); 196 writer.registerParameterDataType(parameterName, dataType); 197 } 198 if (index != null) { 199 writer.setScribeIndex(index); 200 } 201 202 for (VCard vcard : vcards) { 203 writer.write(vcard); 204 } 205 206 return document; 207 } 208}