001    package biweekly.property.marshaller;
002    
003    import java.util.List;
004    
005    import biweekly.ICalDataType;
006    import biweekly.Warning;
007    import biweekly.io.json.JCalValue;
008    import biweekly.io.xml.XCalElement;
009    import biweekly.parameter.Encoding;
010    import biweekly.parameter.ICalParameters;
011    import biweekly.property.Attachment;
012    import biweekly.util.Base64;
013    
014    /*
015     Copyright (c) 2013, Michael Angstadt
016     All rights reserved.
017    
018     Redistribution and use in source and binary forms, with or without
019     modification, are permitted provided that the following conditions are met: 
020    
021     1. Redistributions of source code must retain the above copyright notice, this
022     list of conditions and the following disclaimer. 
023     2. Redistributions in binary form must reproduce the above copyright notice,
024     this list of conditions and the following disclaimer in the documentation
025     and/or other materials provided with the distribution. 
026    
027     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
028     ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
029     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
030     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
031     ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
032     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
033     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
034     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
035     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
036     SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
037     */
038    
039    /**
040     * Marshals {@link Attachment} properties.
041     * @author Michael Angstadt
042     */
043    public class AttachmentMarshaller extends ICalPropertyMarshaller<Attachment> {
044            public AttachmentMarshaller() {
045                    super(Attachment.class, "ATTACH", ICalDataType.URI);
046            }
047    
048            @Override
049            protected void _prepareParameters(Attachment property, ICalParameters copy) {
050                    if (property.getUri() != null) {
051                            copy.setEncoding(null);
052                    } else if (property.getData() != null) {
053                            copy.setEncoding(Encoding.BASE64);
054                    }
055            }
056    
057            @Override
058            protected ICalDataType _dataType(Attachment property) {
059                    if (property.getUri() != null) {
060                            return ICalDataType.URI;
061                    }
062                    if (property.getData() != null) {
063                            return ICalDataType.BINARY;
064                    }
065                    return defaultDataType;
066            }
067    
068            @Override
069            protected String _writeText(Attachment property) {
070                    String uri = property.getUri();
071                    if (uri != null) {
072                            return uri;
073                    }
074    
075                    byte data[] = property.getData();
076                    if (data != null) {
077                            return Base64.encode(data);
078                    }
079    
080                    return "";
081            }
082    
083            @Override
084            protected Attachment _parseText(String value, ICalDataType dataType, ICalParameters parameters, List<Warning> warnings) {
085                    value = unescape(value);
086    
087                    if (dataType == ICalDataType.BINARY || parameters.getEncoding() == Encoding.BASE64) {
088                            return new Attachment(null, Base64.decode(value));
089                    }
090                    return new Attachment(null, value);
091            }
092    
093            @Override
094            protected void _writeXml(Attachment property, XCalElement element) {
095                    String uri = property.getUri();
096                    if (uri != null) {
097                            element.append(ICalDataType.URI, uri);
098                            return;
099                    }
100    
101                    byte data[] = property.getData();
102                    if (data != null) {
103                            element.append(ICalDataType.BINARY, Base64.encode(data));
104                            return;
105                    }
106    
107                    element.append(defaultDataType, "");
108            }
109    
110            @Override
111            protected Attachment _parseXml(XCalElement element, ICalParameters parameters, List<Warning> warnings) {
112                    String uri = element.first(ICalDataType.URI);
113                    if (uri != null) {
114                            return new Attachment(null, uri);
115                    }
116    
117                    String base64Data = element.first(ICalDataType.BINARY);
118                    if (base64Data != null) {
119                            return new Attachment(null, Base64.decode(base64Data)); //formatType will be set when the parameters are assigned to the property object
120                    }
121    
122                    throw missingXmlElements(ICalDataType.URI, ICalDataType.BINARY);
123            }
124    
125            @Override
126            protected JCalValue _writeJson(Attachment property) {
127                    String uri = property.getUri();
128                    if (uri != null) {
129                            return JCalValue.single(uri);
130                    }
131    
132                    byte data[] = property.getData();
133                    if (data != null) {
134                            return JCalValue.single(Base64.encode(data));
135                    }
136    
137                    return JCalValue.single("");
138            }
139    
140            @Override
141            protected Attachment _parseJson(JCalValue value, ICalDataType dataType, ICalParameters parameters, List<Warning> warnings) {
142                    String valueStr = value.asSingle();
143    
144                    if (dataType == ICalDataType.BINARY) {
145                            return new Attachment(null, Base64.decode(valueStr));
146                    }
147                    return new Attachment(null, valueStr);
148            }
149    }