001package ezvcard.io.scribe;
002
003import java.time.temporal.Temporal;
004
005import ezvcard.VCardDataType;
006import ezvcard.VCardVersion;
007import ezvcard.io.CannotParseException;
008import ezvcard.io.ParseContext;
009import ezvcard.io.html.HCardElement;
010import ezvcard.io.json.JCardValue;
011import ezvcard.io.text.WriteContext;
012import ezvcard.io.xml.XCardElement;
013import ezvcard.parameter.VCardParameters;
014import ezvcard.property.Revision;
015
016/*
017 Copyright (c) 2012-2023, Michael Angstadt
018 All rights reserved.
019
020 Redistribution and use in source and binary forms, with or without
021 modification, are permitted provided that the following conditions are met: 
022
023 1. Redistributions of source code must retain the above copyright notice, this
024 list of conditions and the following disclaimer. 
025 2. Redistributions in binary form must reproduce the above copyright notice,
026 this list of conditions and the following disclaimer in the documentation
027 and/or other materials provided with the distribution. 
028
029 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
030 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
031 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
032 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
033 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
034 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
035 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
036 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
037 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
038 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
039 */
040
041/**
042 * Marshals {@link Revision} properties.
043 * @author Michael Angstadt
044 */
045public class RevisionScribe extends VCardPropertyScribe<Revision> {
046        public RevisionScribe() {
047                super(Revision.class, "REV");
048        }
049
050        @Override
051        protected VCardDataType _defaultDataType(VCardVersion version) {
052                return VCardDataType.TIMESTAMP;
053        }
054
055        @Override
056        protected String _writeText(Revision property, WriteContext context) {
057                boolean extended = (context.getVersion() == VCardVersion.V3_0);
058                return write(property, extended);
059        }
060
061        @Override
062        protected Revision _parseText(String value, VCardDataType dataType, VCardParameters parameters, ParseContext context) {
063                return parse(value);
064        }
065
066        @Override
067        protected void _writeXml(Revision property, XCardElement parent) {
068                parent.append(VCardDataType.TIMESTAMP, write(property, false));
069        }
070
071        @Override
072        protected Revision _parseXml(XCardElement element, VCardParameters parameters, ParseContext context) {
073                String value = element.first(VCardDataType.TIMESTAMP);
074                if (value != null) {
075                        return parse(value);
076                }
077
078                throw missingXmlElements(VCardDataType.TIMESTAMP);
079        }
080
081        @Override
082        protected Revision _parseHtml(HCardElement element, ParseContext context) {
083                String value = null;
084                if ("time".equals(element.tagName())) {
085                        String datetime = element.attr("datetime");
086                        if (datetime.length() > 0) {
087                                value = datetime;
088                        }
089                }
090                if (value == null) {
091                        value = element.value();
092                }
093
094                return parse(value);
095        }
096
097        @Override
098        protected JCardValue _writeJson(Revision property) {
099                return JCardValue.single(write(property, true));
100        }
101
102        @Override
103        protected Revision _parseJson(JCardValue value, VCardDataType dataType, VCardParameters parameters, ParseContext context) {
104                String valueStr = value.asSingle();
105                return parse(valueStr);
106        }
107
108        private String write(Revision property, boolean extended) {
109                Temporal timestamp = property.getValue();
110                if (timestamp == null) {
111                        return "";
112                }
113
114                return date(timestamp).extended(extended).write();
115        }
116
117        private Revision parse(String value) {
118                if (value == null || value.isEmpty()) {
119                        return new Revision((Temporal)null);
120                }
121
122                try {
123                        return new Revision(date(value));
124                } catch (IllegalArgumentException e) {
125                        throw new CannotParseException(5);
126                }
127        }
128}