001package biweekly.io.scribe.property;
002
003import java.util.List;
004
005import biweekly.ICalDataType;
006import biweekly.Warning;
007import biweekly.io.json.JCalValue;
008import biweekly.io.xml.XCalElement;
009import biweekly.parameter.Encoding;
010import biweekly.parameter.ICalParameters;
011import biweekly.property.Attachment;
012import 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 */
043public class AttachmentScribe extends ICalPropertyScribe<Attachment> {
044        public AttachmentScribe() {
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}