001package biweekly.io.scribe.property;
002
003import java.util.Date;
004import java.util.EnumSet;
005import java.util.Set;
006
007import biweekly.ICalDataType;
008import biweekly.ICalVersion;
009import biweekly.io.CannotParseException;
010import biweekly.io.ParseContext;
011import biweekly.io.WriteContext;
012import biweekly.io.json.JCalValue;
013import biweekly.io.xml.XCalElement;
014import biweekly.parameter.ICalParameters;
015import biweekly.property.Trigger;
016import biweekly.util.Duration;
017import biweekly.util.ICalDate;
018
019/*
020 Copyright (c) 2013-2015, Michael Angstadt
021 All rights reserved.
022
023 Redistribution and use in source and binary forms, with or without
024 modification, are permitted provided that the following conditions are met: 
025
026 1. Redistributions of source code must retain the above copyright notice, this
027 list of conditions and the following disclaimer. 
028 2. Redistributions in binary form must reproduce the above copyright notice,
029 this list of conditions and the following disclaimer in the documentation
030 and/or other materials provided with the distribution. 
031
032 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
033 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
034 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
035 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
036 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
037 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
038 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
039 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
040 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
041 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
042 */
043
044/**
045 * Marshals {@link Trigger} properties.
046 * @author Michael Angstadt
047 */
048public class TriggerScribe extends ICalPropertyScribe<Trigger> {
049        public TriggerScribe() {
050                super(Trigger.class, "TRIGGER", ICalDataType.DURATION);
051        }
052
053        @Override
054        protected ICalDataType _dataType(Trigger property, ICalVersion version) {
055                return (property.getDate() == null) ? ICalDataType.DURATION : ICalDataType.DATE_TIME;
056        }
057
058        @Override
059        protected String _writeText(Trigger property, WriteContext context) {
060                Duration duration = property.getDuration();
061                if (duration != null) {
062                        return duration.toString();
063                }
064
065                Date date = property.getDate();
066                return date(date, property, context).extended(false).write();
067        }
068
069        @Override
070        protected Trigger _parseText(String value, ICalDataType dataType, ICalParameters parameters, ParseContext context) {
071                value = unescape(value);
072
073                try {
074                        ICalDate date = date(value).parse();
075                        Trigger property = new Trigger(date);
076                        context.addDate(date, property, parameters);
077                        return property;
078                } catch (IllegalArgumentException e) {
079                        //unable to parse value as date, must be a duration
080                }
081
082                try {
083                        return new Trigger(Duration.parse(value), parameters.getRelated());
084                } catch (IllegalArgumentException e) {
085                        //unable to parse duration
086                }
087
088                throw new CannotParseException(25);
089        }
090
091        @Override
092        protected void _writeXml(Trigger property, XCalElement element, WriteContext context) {
093                Duration duration = property.getDuration();
094                if (duration != null) {
095                        element.append(ICalDataType.DURATION, duration.toString());
096                        return;
097                }
098
099                Date date = property.getDate();
100                if (date != null) {
101                        String dateStr = date(date, property, context).extended(true).write();
102                        element.append(ICalDataType.DATE_TIME, dateStr);
103                        return;
104                }
105
106                element.append(defaultDataType(context.getVersion()), "");
107        }
108
109        @Override
110        protected Trigger _parseXml(XCalElement element, ICalParameters parameters, ParseContext context) {
111                String value = element.first(ICalDataType.DURATION);
112                if (value != null) {
113                        try {
114                                return new Trigger(Duration.parse(value), parameters.getRelated());
115                        } catch (IllegalArgumentException e) {
116                                throw new CannotParseException(26, value);
117                        }
118                }
119
120                value = element.first(ICalDataType.DATE_TIME);
121                if (value != null) {
122                        try {
123                                ICalDate date = date(value).parse();
124                                Trigger property = new Trigger(date);
125                                context.addDate(date, property, parameters);
126                                return property;
127                        } catch (IllegalArgumentException e) {
128                                throw new CannotParseException(27, value);
129                        }
130                }
131
132                throw missingXmlElements(ICalDataType.DURATION, ICalDataType.DATE_TIME);
133        }
134
135        @Override
136        protected JCalValue _writeJson(Trigger property, WriteContext context) {
137                Duration duration = property.getDuration();
138                if (duration != null) {
139                        return JCalValue.single(duration.toString());
140                }
141
142                Date date = property.getDate();
143                if (date != null) {
144                        String dateStr = date(date, property, context).extended(true).write();
145                        return JCalValue.single(dateStr);
146                }
147
148                return JCalValue.single("");
149        }
150
151        @Override
152        protected Trigger _parseJson(JCalValue value, ICalDataType dataType, ICalParameters parameters, ParseContext context) {
153                String valueStr = value.asSingle();
154
155                try {
156                        ICalDate date = date(valueStr).parse();
157                        Trigger property = new Trigger(date);
158                        context.addDate(date, property, parameters);
159                        return property;
160                } catch (IllegalArgumentException e) {
161                        //must be a duration
162                }
163
164                try {
165                        return new Trigger(Duration.parse(valueStr), parameters.getRelated());
166                } catch (IllegalArgumentException e) {
167                        throw new CannotParseException(25);
168                }
169        }
170
171        @Override
172        public Set<ICalVersion> getSupportedVersions() {
173                return EnumSet.of(ICalVersion.V2_0_DEPRECATED, ICalVersion.V2_0);
174        }
175}