001package biweekly.io.scribe.property;
002
003import java.util.ArrayList;
004import java.util.Date;
005import java.util.EnumSet;
006import java.util.List;
007import java.util.Set;
008
009import biweekly.ICalDataType;
010import biweekly.ICalVersion;
011import biweekly.io.CannotParseException;
012import biweekly.io.ParseContext;
013import biweekly.io.WriteContext;
014import biweekly.parameter.ICalParameters;
015import biweekly.property.VCalAlarmProperty;
016import biweekly.util.Duration;
017
018/*
019 Copyright (c) 2013-2015, Michael Angstadt
020 All rights reserved.
021
022 Redistribution and use in source and binary forms, with or without
023 modification, are permitted provided that the following conditions are met: 
024
025 1. Redistributions of source code must retain the above copyright notice, this
026 list of conditions and the following disclaimer. 
027 2. Redistributions in binary form must reproduce the above copyright notice,
028 this list of conditions and the following disclaimer in the documentation
029 and/or other materials provided with the distribution. 
030
031 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
032 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
033 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
034 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
035 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
036 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
037 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
038 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
039 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
040 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
041 */
042
043/**
044 * Marshals {@link VCalAlarmProperty} properties.
045 * @author Michael Angstadt
046 */
047public abstract class VCalAlarmPropertyScribe<T extends VCalAlarmProperty> extends ICalPropertyScribe<T> {
048        public VCalAlarmPropertyScribe(Class<T> clazz, String propertyName) {
049                super(clazz, propertyName);
050        }
051
052        public VCalAlarmPropertyScribe(Class<T> clazz, String propertyName, ICalDataType defaultDataType) {
053                super(clazz, propertyName, defaultDataType);
054        }
055
056        @Override
057        protected String _writeText(T property, WriteContext context) {
058                List<String> values = new ArrayList<String>(4);
059
060                Date start = property.getStart();
061                String value = date(start, property, context).extended(false).write();
062                values.add(value);
063
064                Duration snooze = property.getSnooze();
065                value = (snooze == null) ? "" : snooze.toString();
066                values.add(value);
067
068                Integer repeat = property.getRepeat();
069                value = (repeat == null) ? "" : repeat.toString();
070                values.add(value);
071
072                List<String> dataValues = writeData(property);
073                values.addAll(dataValues);
074
075                return structured(values.toArray());
076        }
077
078        @Override
079        protected T _parseText(String value, ICalDataType dataType, ICalParameters parameters, ParseContext context) {
080                SemiStructuredIterator it = semistructured(value);
081
082                String next = next(it);
083                Date start;
084                try {
085                        start = (next == null) ? null : date(next).parse();
086                } catch (IllegalArgumentException e) {
087                        throw new CannotParseException("");
088                }
089
090                next = next(it);
091                Duration snooze;
092                try {
093                        snooze = (next == null) ? null : Duration.parse(next);
094                } catch (IllegalArgumentException e) {
095                        throw new CannotParseException("");
096                }
097
098                next = next(it);
099                Integer repeat;
100                try {
101                        repeat = (next == null) ? null : Integer.valueOf(next);
102                } catch (IllegalArgumentException e) {
103                        throw new CannotParseException("");
104                }
105
106                T property = create(dataType, it);
107                property.setStart(start);
108                property.setSnooze(snooze);
109                property.setRepeat(repeat);
110                return property;
111        }
112
113        private String next(SemiStructuredIterator it) {
114                String next = it.next();
115                if (next == null) {
116                        return null;
117                }
118
119                next = next.trim();
120                return (next.length() == 0) ? null : next;
121        }
122
123        protected abstract List<String> writeData(T property);
124
125        protected abstract T create(ICalDataType dataType, SemiStructuredIterator it);
126
127        @Override
128        public Set<ICalVersion> getSupportedVersions() {
129                return EnumSet.of(ICalVersion.V1_0);
130        }
131}