001package ezvcard.io.scribe;
002
003import com.github.mangstadt.vinnie.io.VObjectPropertyValues;
004
005import ezvcard.VCardDataType;
006import ezvcard.VCardVersion;
007import ezvcard.io.ParseContext;
008import ezvcard.io.json.JCardValue;
009import ezvcard.io.text.WriteContext;
010import ezvcard.io.xml.XCardElement;
011import ezvcard.parameter.VCardParameters;
012import ezvcard.property.PlaceProperty;
013import ezvcard.util.GeoUri;
014
015/*
016 Copyright (c) 2012-2023, Michael Angstadt
017 All rights reserved.
018
019 Redistribution and use in source and binary forms, with or without
020 modification, are permitted provided that the following conditions are met: 
021
022 1. Redistributions of source code must retain the above copyright notice, this
023 list of conditions and the following disclaimer. 
024 2. Redistributions in binary form must reproduce the above copyright notice,
025 this list of conditions and the following disclaimer in the documentation
026 and/or other materials provided with the distribution. 
027
028 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
029 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
030 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
031 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
032 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
033 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
034 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
035 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
036 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
037 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
038 */
039
040/**
041 * Marshals {@link PlaceProperty} properties.
042 * @param <T> the property class
043 * @author Michael Angstadt
044 */
045public abstract class PlacePropertyScribe<T extends PlaceProperty> extends VCardPropertyScribe<T> {
046        public PlacePropertyScribe(Class<T> clazz, String propertyName) {
047                super(clazz, propertyName);
048        }
049
050        @Override
051        protected VCardDataType _defaultDataType(VCardVersion version) {
052                return VCardDataType.TEXT;
053        }
054
055        @Override
056        protected VCardDataType _dataType(T property, VCardVersion version) {
057                if (property.getText() != null) {
058                        return VCardDataType.TEXT;
059                }
060
061                if (property.getUri() != null || property.getGeoUri() != null) {
062                        return VCardDataType.URI;
063                }
064
065                return _defaultDataType(version);
066        }
067
068        @Override
069        protected String _writeText(T property, WriteContext context) {
070                String text = property.getText();
071                if (text != null) {
072                        return VObjectPropertyValues.escape(text);
073                }
074
075                String uri = property.getUri();
076                if (uri != null) {
077                        return uri;
078                }
079
080                GeoUri geoUri = property.getGeoUri();
081                if (geoUri != null) {
082                        return geoUri.toString();
083                }
084
085                return "";
086        }
087
088        @Override
089        protected T _parseText(String value, VCardDataType dataType, VCardParameters parameters, ParseContext context) {
090                T property = newInstance();
091                value = VObjectPropertyValues.unescape(value);
092
093                if (dataType == VCardDataType.TEXT) {
094                        property.setText(value);
095                        return property;
096                }
097
098                if (dataType == VCardDataType.URI) {
099                        try {
100                                property.setGeoUri(GeoUri.parse(value));
101                        } catch (IllegalArgumentException e) {
102                                property.setUri(value);
103                        }
104                        return property;
105                }
106
107                property.setText(value);
108                return property;
109        }
110
111        @Override
112        protected void _writeXml(T property, XCardElement parent) {
113                String text = property.getText();
114                if (text != null) {
115                        parent.append(VCardDataType.TEXT, text);
116                        return;
117                }
118
119                String uri = property.getUri();
120                if (uri != null) {
121                        parent.append(VCardDataType.URI, uri);
122                        return;
123                }
124
125                GeoUri geoUri = property.getGeoUri();
126                if (geoUri != null) {
127                        parent.append(VCardDataType.URI, geoUri.toString());
128                        return;
129                }
130
131                parent.append(VCardDataType.TEXT, "");
132        }
133
134        @Override
135        protected T _parseXml(XCardElement element, VCardParameters parameters, ParseContext context) {
136                T property = newInstance();
137
138                String text = element.first(VCardDataType.TEXT);
139                if (text != null) {
140                        property.setText(text);
141                        return property;
142                }
143
144                String uri = element.first(VCardDataType.URI);
145                if (uri != null) {
146                        try {
147                                property.setGeoUri(GeoUri.parse(uri));
148                        } catch (IllegalArgumentException e) {
149                                property.setUri(uri);
150                        }
151                        return property;
152                }
153
154                throw missingXmlElements(VCardDataType.TEXT, VCardDataType.URI);
155        }
156
157        @Override
158        protected JCardValue _writeJson(T property) {
159                String text = property.getText();
160                if (text != null) {
161                        return JCardValue.single(text);
162                }
163
164                String uri = property.getUri();
165                if (uri != null) {
166                        return JCardValue.single(uri);
167                }
168
169                GeoUri geoUri = property.getGeoUri();
170                if (geoUri != null) {
171                        return JCardValue.single(geoUri.toString());
172                }
173
174                return JCardValue.single("");
175        }
176
177        @Override
178        protected T _parseJson(JCardValue value, VCardDataType dataType, VCardParameters parameters, ParseContext context) {
179                T property = newInstance();
180                String valueStr = value.asSingle();
181
182                if (dataType == VCardDataType.TEXT) {
183                        property.setText(valueStr);
184                        return property;
185                }
186
187                if (dataType == VCardDataType.URI) {
188                        try {
189                                property.setGeoUri(GeoUri.parse(valueStr));
190                        } catch (IllegalArgumentException e) {
191                                property.setUri(valueStr);
192                        }
193                        return property;
194                }
195
196                property.setText(valueStr);
197                return property;
198        }
199
200        protected abstract T newInstance();
201}