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 }