001package ezvcard.io.scribe;
002
003import java.util.List;
004
005import com.github.mangstadt.vinnie.io.VObjectPropertyValues;
006
007import ezvcard.VCardDataType;
008import ezvcard.VCardVersion;
009import ezvcard.io.ParseContext;
010import ezvcard.io.json.JCardValue;
011import ezvcard.io.text.WriteContext;
012import ezvcard.io.xml.XCardElement;
013import ezvcard.parameter.VCardParameters;
014import ezvcard.property.TextListProperty;
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 properties that contain a list of values.
043 * @param <T> the property class
044 * @author Michael Angstadt
045 */
046public abstract class ListPropertyScribe<T extends TextListProperty> extends VCardPropertyScribe<T> {
047        public ListPropertyScribe(Class<T> clazz, String propertyName) {
048                super(clazz, propertyName);
049        }
050
051        @Override
052        protected VCardDataType _defaultDataType(VCardVersion version) {
053                return VCardDataType.TEXT;
054        }
055
056        @Override
057        protected String _writeText(T property, WriteContext context) {
058                return VObjectPropertyValues.writeList(property.getValues());
059        }
060
061        @Override
062        protected T _parseText(String value, VCardDataType dataType, VCardParameters parameters, ParseContext context) {
063                List<String> values = VObjectPropertyValues.parseList(value);
064                return parse(values);
065        }
066
067        @Override
068        protected void _writeXml(T property, XCardElement parent) {
069                parent.append(VCardDataType.TEXT.getName().toLowerCase(), property.getValues());
070        }
071
072        @Override
073        protected T _parseXml(XCardElement element, VCardParameters parameters, ParseContext context) {
074                List<String> values = element.all(VCardDataType.TEXT);
075                if (!values.isEmpty()) {
076                        return parse(values);
077                }
078
079                throw missingXmlElements(VCardDataType.TEXT);
080        }
081
082        @Override
083        protected JCardValue _writeJson(T property) {
084                List<String> values = property.getValues();
085                if (values.isEmpty()) {
086                        return JCardValue.single("");
087                }
088
089                return JCardValue.multi(values);
090        }
091
092        @Override
093        protected T _parseJson(JCardValue value, VCardDataType dataType, VCardParameters parameters, ParseContext context) {
094                List<String> values = value.asMulti();
095                return parse(values);
096        }
097
098        private T parse(List<String> values) {
099                T property = _newInstance();
100                property.getValues().addAll(values);
101                return property;
102        }
103
104        protected abstract T _newInstance();
105}