001    package biweekly.property.marshaller;
002    
003    import java.util.Date;
004    import java.util.List;
005    
006    import biweekly.ICalDataType;
007    import biweekly.Warning;
008    import biweekly.io.CannotParseException;
009    import biweekly.io.json.JCalValue;
010    import biweekly.io.xml.XCalElement;
011    import biweekly.parameter.ICalParameters;
012    import biweekly.property.DateTimeProperty;
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 properties that have "date-time" values.
041     * @param <T> the property class
042     * @author Michael Angstadt
043     */
044    public abstract class DateTimePropertyMarshaller<T extends DateTimeProperty> extends ICalPropertyMarshaller<T> {
045            public DateTimePropertyMarshaller(Class<T> clazz, String propertyName) {
046                    super(clazz, propertyName, ICalDataType.DATE_TIME);
047            }
048    
049            @Override
050            protected String _writeText(T property) {
051                    Date value = property.getValue();
052                    if (value != null) {
053                            return date(value).write(); //should always be in UTC time
054                    }
055    
056                    return "";
057            }
058    
059            @Override
060            protected T _parseText(String value, ICalDataType dataType, ICalParameters parameters, List<Warning> warnings) {
061                    value = unescape(value);
062                    return parse(value, parameters, warnings);
063            }
064    
065            @Override
066            protected void _writeXml(T property, XCalElement element) {
067                    String dateStr = null;
068    
069                    Date value = property.getValue();
070                    if (value != null) {
071                            dateStr = date(value).extended(true).write(); //should always be in UTC time
072                    }
073    
074                    element.append(dataType(property), dateStr);
075            }
076    
077            @Override
078            protected T _parseXml(XCalElement element, ICalParameters parameters, List<Warning> warnings) {
079                    String value = element.first(defaultDataType);
080                    if (value != null) {
081                            return parse(value, parameters, warnings);
082                    }
083    
084                    throw missingXmlElements(defaultDataType);
085            }
086    
087            @Override
088            protected JCalValue _writeJson(T property) {
089                    Date value = property.getValue();
090                    if (value != null) {
091                            return JCalValue.single(date(value).extended(true).write());
092                    }
093    
094                    return JCalValue.single("");
095            }
096    
097            @Override
098            protected T _parseJson(JCalValue value, ICalDataType dataType, ICalParameters parameters, List<Warning> warnings) {
099                    String valueStr = value.asSingle();
100                    return parse(valueStr, parameters, warnings);
101            }
102    
103            private T parse(String value, ICalParameters parameters, List<Warning> warnings) {
104                    try {
105                            Date date = date(value).tzid(parameters.getTimezoneId(), warnings).parse();
106                            return newInstance(date);
107                    } catch (IllegalArgumentException e) {
108                            throw new CannotParseException(17);
109                    }
110            }
111    
112            protected abstract T newInstance(Date date);
113    }