001package ezvcard;
002
003import static ezvcard.VCardVersion.V2_1;
004import static ezvcard.VCardVersion.V3_0;
005import static ezvcard.VCardVersion.V4_0;
006
007import java.util.Collection;
008
009import ezvcard.util.CaseClasses;
010import ezvcard.util.SupportedVersionsHelper;
011
012/*
013 Copyright (c) 2012-2026, Michael Angstadt
014 All rights reserved.
015
016 Redistribution and use in source and binary forms, with or without
017 modification, are permitted provided that the following conditions are met: 
018
019 1. Redistributions of source code must retain the above copyright notice, this
020 list of conditions and the following disclaimer. 
021 2. Redistributions in binary form must reproduce the above copyright notice,
022 this list of conditions and the following disclaimer in the documentation
023 and/or other materials provided with the distribution. 
024
025 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
026 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
027 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
028 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
029 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
030 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
031 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
032 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
033 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
034 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
035
036 The views and conclusions contained in the software and documentation are those
037 of the authors and should not be interpreted as representing official policies, 
038 either expressed or implied, of the FreeBSD Project.
039 */
040
041/**
042 * Defines the data type of a property's value.
043 * @author Michael Angstadt
044 */
045public class VCardDataType {
046        private static final CaseClasses<VCardDataType, String> enums = new CaseClasses<VCardDataType, String>(VCardDataType.class) {
047                @Override
048                protected VCardDataType create(String value) {
049                        return new VCardDataType(value);
050                }
051
052                @Override
053                protected boolean matches(VCardDataType dataType, String value) {
054                        return dataType.name.equalsIgnoreCase(value);
055                }
056        };
057
058        /**
059         * A uniform resource locator (for example,
060         * "http://www.example.com/image.jpg"). This data type is only used in 2.1
061         * vCards. All other vCard versions use {@link #URI}.
062         */
063        @SupportedVersions(V2_1)
064        public static final VCardDataType URL = new VCardDataType("url");
065
066        /**
067         * Refers to a MIME entity within an email.
068         */
069        @SupportedVersions(V2_1)
070        public static final VCardDataType CONTENT_ID = new VCardDataType("content-id");
071
072        /**
073         * A non-textual value, such as a picture or sound file.
074         */
075        @SupportedVersions(V3_0)
076        public static final VCardDataType BINARY = new VCardDataType("binary");
077
078        /**
079         * A uniform resource identifier (for example,
080         * "http://www.example.com/image.jpg"). 2.1 vCards use {@link #URL} instead.
081         */
082        @SupportedVersions({ V3_0, V4_0 })
083        public static final VCardDataType URI = new VCardDataType("uri");
084
085        /**
086         * A plain text value.
087         */
088        public static final VCardDataType TEXT = new VCardDataType("text");
089
090        /**
091         * A date that does not have a time component (for example, "2015-02-16").
092         */
093        @SupportedVersions({ V3_0, V4_0 })
094        public static final VCardDataType DATE = new VCardDataType("date");
095
096        /**
097         * A time that does not have a date component (for example, "08:34:00").
098         */
099        @SupportedVersions({ V3_0, V4_0 })
100        public static final VCardDataType TIME = new VCardDataType("time");
101
102        /**
103         * A date with a time component (for example, "2015-02-16 08:34:00").
104         */
105        @SupportedVersions({ V3_0, V4_0 })
106        public static final VCardDataType DATE_TIME = new VCardDataType("date-time");
107
108        /**
109         * Any sort of date/time combination. The value can be a date (e.g.
110         * "2015-02-16"), a time (e.g. "08:34:00"), or a date with a time component
111         * (e.g. "2015-02-16 08:34:00").
112         */
113        @SupportedVersions(V4_0)
114        public static final VCardDataType DATE_AND_OR_TIME = new VCardDataType("date-and-or-time");
115
116        /**
117         * A specific moment in time. Timestamps should be in UTC time.
118         */
119        @SupportedVersions(V4_0)
120        public static final VCardDataType TIMESTAMP = new VCardDataType("timestamp");
121
122        /**
123         * A boolean value ("true" or "false").
124         */
125        @SupportedVersions(V4_0)
126        public static final VCardDataType BOOLEAN = new VCardDataType("boolean");
127
128        /**
129         * An integer value (for example, "42").
130         */
131        @SupportedVersions(V4_0)
132        public static final VCardDataType INTEGER = new VCardDataType("integer");
133
134        /**
135         * A floating-point value (for example, "3.14").
136         */
137        @SupportedVersions(V4_0)
138        public static final VCardDataType FLOAT = new VCardDataType("float");
139
140        /**
141         * An offset from UTC time, in hours and minutes (for example, "-0500").
142         */
143        @SupportedVersions(V4_0)
144        public static final VCardDataType UTC_OFFSET = new VCardDataType("utc-offset");
145
146        /**
147         * A standardized abbreviation for a language (for example, "en-us" for
148         * American English).
149         * @see <a href="http://tools.ietf.org/html/rfc5646">RFC 5646</a>
150         */
151        @SupportedVersions(V4_0)
152        public static final VCardDataType LANGUAGE_TAG = new VCardDataType("language-tag");
153
154        private final String name;
155
156        /**
157         * @param name the data type name
158         */
159        private VCardDataType(String name) {
160                this.name = name;
161        }
162
163        /**
164         * Gets the name of the data type.
165         * @return the name of the data type (e.g. "text")
166         */
167        public String getName() {
168                return name;
169        }
170
171        /**
172         * <p>
173         * Gets the vCard versions that support this data type.
174         * </p>
175         * <p>
176         * The supported versions are defined by assigning a
177         * {@link SupportedVersions} annotation to the data type's static field (for
178         * example, {@link VCardDataType#CONTENT_ID}). Dynamically-created data
179         * types (i.e. non-standard data types) are considered to be supported by
180         * all versions.
181         * </p>
182         * @return the vCard versions that support this data type
183         */
184        public VCardVersion[] getSupportedVersions() {
185                return SupportedVersionsHelper.getSupportedVersions(this);
186        }
187
188        /**
189         * <p>
190         * Determines if this data type is supported by the given vCard version.
191         * </p>
192         * <p>
193         * The supported versions are defined by assigning a
194         * {@link SupportedVersions} annotation to the data type's static field (for
195         * example, {@link VCardDataType#CONTENT_ID}). Dynamically-created data
196         * types (i.e. non-standard data types) are considered to be supported by
197         * all versions.
198         * </p>
199         * @param version the vCard version
200         * @return true if it is supported, false if not
201         */
202        public boolean isSupportedBy(VCardVersion version) {
203                return SupportedVersionsHelper.isSupportedBy(version, this);
204        }
205
206        @Override
207        public String toString() {
208                return name;
209        }
210
211        /**
212         * Searches for a data type that is defined as a static constant in this
213         * class.
214         * @param dataType the data type name (e.g. "text")
215         * @return the data type or null if not found
216         */
217        public static VCardDataType find(String dataType) {
218                return enums.find(dataType);
219        }
220
221        /**
222         * Searches for a data type and creates one if it cannot be found. All
223         * objects are guaranteed to be unique, so they can be compared with
224         * {@code ==} equality.
225         * @param dataType data type name (e.g. "text")
226         * @return the data type
227         */
228        public static VCardDataType get(String dataType) {
229                return enums.get(dataType);
230        }
231
232        /**
233         * Gets all of the data types that are defined as static constants in this
234         * class.
235         * @return the data types
236         */
237        public static Collection<VCardDataType> all() {
238                return enums.all();
239        }
240
241        /*
242         * Note: This class doesn't need equals() or hashCode() because the
243         * CaseClasses object enforces reference equality.
244         */
245
246        @Override
247        public int hashCode() {
248                return super.hashCode();
249        }
250
251        @Override
252        public boolean equals(Object obj) {
253                return super.equals(obj);
254        }
255}