001 package biweekly.property.marshaller;
002
003 import java.util.HashMap;
004 import java.util.List;
005 import java.util.Map;
006
007 import javax.xml.transform.OutputKeys;
008
009 import org.w3c.dom.Document;
010 import org.w3c.dom.Element;
011 import org.xml.sax.SAXException;
012
013 import biweekly.io.CannotParseException;
014 import biweekly.io.xml.XCalElement;
015 import biweekly.io.xml.XCalNamespaceContext;
016 import biweekly.parameter.ICalParameters;
017 import biweekly.property.Xml;
018 import biweekly.util.XmlUtils;
019
020 /*
021 Copyright (c) 2013, Michael Angstadt
022 All rights reserved.
023
024 Redistribution and use in source and binary forms, with or without
025 modification, are permitted provided that the following conditions are met:
026
027 1. Redistributions of source code must retain the above copyright notice, this
028 list of conditions and the following disclaimer.
029 2. Redistributions in binary form must reproduce the above copyright notice,
030 this list of conditions and the following disclaimer in the documentation
031 and/or other materials provided with the distribution.
032
033 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
034 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
035 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
036 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
037 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
038 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
039 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
040 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
041 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
042 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
043 */
044
045 /**
046 * Marshals {@link Xml} properties.
047 * @author Michael Angstadt
048 */
049 public class XmlMarshaller extends ICalPropertyMarshaller<Xml> {
050 //TODO on writing to plain text: convert to base64 if the string contains values that are illegal within a plain text value (p.17)
051 public XmlMarshaller() {
052 super(Xml.class, "XML");
053 }
054
055 @Override
056 protected String _writeText(Xml property) {
057 Document value = property.getValue();
058 if (value == null) {
059 return "";
060 }
061
062 Map<String, String> props = new HashMap<String, String>();
063 props.put(OutputKeys.OMIT_XML_DECLARATION, "yes");
064 String xml = XmlUtils.toString(value, props);
065 return escape(xml);
066 }
067
068 @Override
069 protected Xml _parseText(String value, ICalParameters parameters, List<String> warnings) {
070 value = unescape(value);
071 try {
072 return new Xml(value);
073 } catch (SAXException e) {
074 throw new CannotParseException("Cannot parse value as XML: " + value);
075 }
076 }
077
078 @Override
079 protected void _writeXml(Xml property, XCalElement element) {
080 super._writeXml(property, element);
081 //Xml properties are handled as a special case when writing xCal documents, so this method should never get called (see: XCalDocument class)
082 }
083
084 @Override
085 protected Xml _parseXml(XCalElement element, ICalParameters parameters, List<String> warnings) {
086 Xml xml = new Xml(element.getElement());
087
088 //remove the <parameters> element
089 Element root = XmlUtils.getRootElement(xml.getValue());
090 for (Element child : XmlUtils.toElementList(root.getChildNodes())) {
091 if ("parameters".equals(child.getLocalName()) && XCalNamespaceContext.XCAL_NS.equals(child.getNamespaceURI())) {
092 root.removeChild(child);
093 }
094 }
095
096 return xml;
097 }
098 }