001 package ezvcard.property;
002
003 import java.util.ArrayList;
004 import java.util.Arrays;
005 import java.util.EnumSet;
006 import java.util.List;
007 import java.util.Set;
008
009 import ezvcard.VCard;
010 import ezvcard.VCardVersion;
011 import ezvcard.Warning;
012 import ezvcard.parameter.VCardParameters;
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 The views and conclusions contained in the software and documentation are those
039 of the authors and should not be interpreted as representing official policies,
040 either expressed or implied, of the FreeBSD Project.
041 */
042
043 /**
044 * Represents a vCard key/value pair entry (called a "type" or "property").
045 * @author Michael Angstadt
046 */
047 public abstract class VCardProperty implements Comparable<VCardProperty> {
048 /**
049 * The group that this property belongs to or null if it doesn't belong to a
050 * group.
051 */
052 protected String group;
053
054 /**
055 * The property's parameters.
056 */
057 protected VCardParameters parameters = new VCardParameters();
058
059 /**
060 * Gets the vCard versions that support this property.
061 * @return the vCard versions that support this property.
062 */
063 public final Set<VCardVersion> getSupportedVersions() {
064 return _supportedVersions();
065 }
066
067 /**
068 * <p>
069 * Gets the vCard versions that support this property.
070 * </p>
071 * <p>
072 * This method should be overridden by child classes if the property does
073 * not support all vCard versions. The default implementation of this method
074 * returns all vCard versions.
075 * </p>
076 * @return the vCard versions that support this property.
077 */
078 protected Set<VCardVersion> _supportedVersions() {
079 return EnumSet.copyOf(Arrays.asList(VCardVersion.values()));
080 }
081
082 /**
083 * Checks the property for data consistency problems or deviations from the
084 * spec. These problems will not prevent the property from being written to
085 * a data stream, but may prevent it from being parsed correctly by the
086 * consuming application. These problems can largely be avoided by reading
087 * the Javadocs of the property class, or by being familiar with the vCard
088 * standard.
089 * @param version the version to check the property against (use 4.0 for
090 * xCard and jCard)
091 * @param vcard the vCard this property belongs to
092 * @see VCard#validate
093 * @return a list of warnings or an empty list if no problems were found
094 */
095 public final List<Warning> validate(VCardVersion version, VCard vcard) {
096 List<Warning> warnings = new ArrayList<Warning>(0);
097
098 //check the supported versions
099 Set<VCardVersion> supportedVersions = getSupportedVersions();
100 if (!supportedVersions.contains(version)) {
101 warnings.add(new Warning(2, supportedVersions));
102 }
103
104 //check parameters
105 warnings.addAll(parameters.validate(version));
106
107 _validate(warnings, version, vcard);
108
109 return warnings;
110 }
111
112 /**
113 * Checks the property for data consistency problems or deviations from the
114 * spec. Meant to be overridden by child classes that wish to provide
115 * validation logic.
116 * @param warnings the list to add the warnings to
117 * @param version the version to check the property against
118 * @param vcard the vCard this property belongs to
119 */
120 protected void _validate(List<Warning> warnings, VCardVersion version, VCard vcard) {
121 //empty
122 }
123
124 /**
125 * Gets all of the property's parameters.
126 * @return the property's parameters
127 */
128 public VCardParameters getParameters() {
129 return parameters;
130 }
131
132 /**
133 * Sets the property's parameters.
134 * @param parameters the parameters
135 */
136 public void setParameters(VCardParameters parameters) {
137 this.parameters = parameters;
138 }
139
140 /**
141 * Gets the first value of a parameter.
142 * @param name the parameter name (case insensitive, e.g. "LANGUAGE")
143 * @return the parameter value or null if not found
144 */
145 public String getParameter(String name) {
146 return parameters.first(name);
147 }
148
149 /**
150 * Gets all values of a parameter.
151 * @param name the parameter name (case insensitive, e.g. "LANGUAGE")
152 * @return the parameter values
153 */
154 public List<String> getParameters(String name) {
155 return parameters.get(name);
156 }
157
158 /**
159 * Replaces all existing values of a parameter with the given value.
160 * @param name the parameter name (case insensitive, e.g. "LANGUAGE")
161 * @param value the parameter value
162 */
163 public void setParameter(String name, String value) {
164 parameters.replace(name, value);
165 }
166
167 /**
168 * Adds a value to a parameter.
169 * @param name the parameter name (case insensitive, e.g. "LANGUAGE")
170 * @param value the parameter value
171 */
172 public void addParameter(String name, String value) {
173 parameters.put(name, value);
174 }
175
176 /**
177 * Removes a parameter from the property.
178 * @param name the parameter name (case insensitive, e.g. "LANGUAGE")
179 */
180 public void removeParameter(String name) {
181 parameters.removeAll(name);
182 }
183
184 /**
185 * Gets this property's group.
186 * @return the group or null if it does not belong to a group
187 */
188 public String getGroup() {
189 return group;
190 }
191
192 /**
193 * Sets this property's group.
194 * @param group the group or null to remove the property's group
195 */
196 public void setGroup(String group) {
197 this.group = group;
198 }
199
200 /**
201 * Sorts by PREF parameter ascending. Properties that do not have a PREF
202 * parameter are pushed to the end of the list.
203 */
204 public int compareTo(VCardProperty that) {
205 Integer pref0 = this.getParameters().getPref();
206 Integer pref1 = that.getParameters().getPref();
207 if (pref0 == null && pref1 == null) {
208 return 0;
209 }
210 if (pref0 == null) {
211 return 1;
212 }
213 if (pref1 == null) {
214 return -1;
215 }
216 return pref1.compareTo(pref0);
217 }
218
219 //Note: The following parameter helper methods are package-scoped to prevent them from cluttering up the Javadocs
220
221 /**
222 * <p>
223 * Gets all PID values.
224 * </p>
225 * <p>
226 * <b>Supported versions:</b> {@code 4.0}
227 * </p>
228 * @return the PID values or empty set if there are none
229 * @see VCardParameters#getPids
230 */
231 List<Integer[]> getPids() {
232 return parameters.getPids();
233 }
234
235 /**
236 * <p>
237 * Adds a PID value.
238 * </p>
239 * <p>
240 * <b>Supported versions:</b> {@code 4.0}
241 * </p>
242 * @param localId the local ID
243 * @param clientPidMapRef the ID used to reference the property's globally
244 * unique identifier in the CLIENTPIDMAP property.
245 * @see VCardParameters#addPid(int, int)
246 */
247 void addPid(int localId, int clientPidMapRef) {
248 parameters.addPid(localId, clientPidMapRef);
249 }
250
251 /**
252 * <p>
253 * Removes all PID values.
254 * </p>
255 * <p>
256 * <b>Supported versions:</b> {@code 4.0}
257 * </p>
258 * @see VCardParameters#removePids
259 */
260 void removePids() {
261 parameters.removePids();
262 }
263
264 /**
265 * <p>
266 * Gets the preference value. The lower the number, the more preferred this
267 * property instance is compared with other properties in the same vCard of
268 * the same type. If a property doesn't have a preference value, then it is
269 * considered the least preferred.
270 * </p>
271 * <p>
272 * <b>Supported versions:</b> {@code 4.0}
273 * </p>
274 * @return the preference value or null if it doesn't exist
275 * @see VCardParameters#getPref
276 */
277 Integer getPref() {
278 return parameters.getPref();
279 }
280
281 /**
282 * <p>
283 * Sets the preference value. The lower the number, the more preferred this
284 * property instance is compared with other properties in the same vCard of
285 * the same type. If a property doesn't have a preference value, then it is
286 * considered the least preferred.
287 * </p>
288 * <p>
289 * <b>Supported versions:</b> {@code 4.0}
290 * </p>
291 * @param pref the preference value or null to remove
292 * @see VCardParameters#setPref
293 */
294 void setPref(Integer pref) {
295 parameters.setPref(pref);
296 }
297
298 /**
299 * Gets the language that the property value is written in.
300 * @return the language or null if not set
301 * @see VCardParameters#getLanguage
302 */
303 String getLanguage() {
304 return parameters.getLanguage();
305 }
306
307 /**
308 * Sets the language that the property value is written in.
309 * @param language the language or null to remove
310 * @see VCardParameters#setLanguage
311 */
312 void setLanguage(String language) {
313 parameters.setLanguage(language);
314 }
315
316 /**
317 * Gets the sorted position of this property when it is grouped together
318 * with other properties of the same type. Properties with low index values
319 * are put at the beginning of the sorted list and properties with high
320 * index values are put at the end of the list.
321 * @return the index or null if not set
322 * @see VCardParameters#setIndex
323 */
324 Integer getIndex() {
325 return parameters.getIndex();
326 }
327
328 /**
329 * Sets the sorted position of this property when it is grouped together
330 * with other properties of the same type. Properties with low index values
331 * are put at the beginning of the sorted list and properties with high
332 * index values are put at the end of the list.
333 * @param index the index or null to remove
334 * @see VCardParameters#setIndex
335 */
336 void setIndex(Integer index) {
337 parameters.setIndex(index);
338 }
339 }