001 package ezvcard.types;
002
003 import java.util.List;
004
005 import ezvcard.VCard;
006 import ezvcard.VCardSubTypes;
007 import ezvcard.VCardVersion;
008 import ezvcard.io.CompatibilityMode;
009 import ezvcard.io.SkipMeException;
010 import ezvcard.parameters.RelatedTypeParameter;
011 import ezvcard.parameters.ValueParameter;
012 import ezvcard.util.VCardStringUtils;
013 import ezvcard.util.XCardElement;
014
015 /*
016 Copyright (c) 2012, 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 The views and conclusions contained in the software and documentation are those
040 of the authors and should not be interpreted as representing official policies,
041 either expressed or implied, of the FreeBSD Project.
042 */
043
044 /**
045 * Someone that the person is related to. It can contain either a URI or a plain
046 * text value.
047 *
048 * <pre>
049 * VCard vcard = new VCard();
050 *
051 * RelatedType related = new RelatedType();
052 * related.addType(RelatedTypeParameter.FRIEND);
053 * related.setUri("urn:uuid:03a0e51f-d1aa-4385-8a53-e29025acd8af");
054 * vcard.addRelated(related);
055 *
056 * related = new RelatedType();
057 * related.addType(RelatedTypeParameter.CO_WORKER);
058 * related.addType(RelatedTypeParameter.FRIEND);
059 * related.setUri("http://joesmoe.name/vcard.vcf");
060 * vcard.addRelated(related);
061 *
062 * related = new RelatedType();
063 * related.addType(RelatedTypeParameter.SPOUSE);
064 * related.setText("My wife's name is Edna Smith");
065 * vcard.addRelated(related);
066 * </pre>
067 *
068 * <p>
069 * vCard property name: RELATED
070 * </p>
071 * <p>
072 * vCard versions: 4.0
073 * </p>
074 * @author Michael Angstadt
075 */
076 public class RelatedType extends MultiValuedTypeParameterType<RelatedTypeParameter> {
077 public static final String NAME = "RELATED";
078
079 private String uri;
080 private String text;
081
082 public RelatedType() {
083 super(NAME);
084 }
085
086 /**
087 * Gets the URI value.
088 * @return the URI value or null if no URI value is set
089 */
090 public String getUri() {
091 return uri;
092 }
093
094 /**
095 * Sets the URI to an email address.
096 * @param email the email address
097 */
098 public void setUriEmail(String email) {
099 setUri("mailto:" + email);
100 }
101
102 /**
103 * Sets the URI to an instant messaging handle.
104 * @param protocol the IM protocol (e.g. "aim")
105 * @param handle the handle
106 */
107 public void setUriIM(String protocol, String handle) {
108 setUri(protocol + ":" + handle);
109 }
110
111 /**
112 * Sets the URI to a telephone number.
113 * @param telephone the telephone number
114 */
115 public void setUriTelephone(String telephone) {
116 setUri("tel:" + telephone);
117 }
118
119 /**
120 * Sets the URI.
121 * @param uri the URI
122 */
123 public void setUri(String uri) {
124 this.uri = uri;
125 text = null;
126 }
127
128 /**
129 * Gets the text value.
130 * @return the text value or null if no text value is set
131 */
132 public String getText() {
133 return text;
134 }
135
136 /**
137 * Sets the value to free-form text instead of a URI.
138 * @param text the text
139 */
140 public void setText(String text) {
141 this.text = text;
142 uri = null;
143 }
144
145 /**
146 * Gets all PID parameter values.
147 * <p>
148 * vCard versions: 4.0
149 * </p>
150 * @return the PID values or empty set if there are none
151 * @see VCardSubTypes#getPids
152 */
153 public List<Integer[]> getPids() {
154 return subTypes.getPids();
155 }
156
157 /**
158 * Adds a PID value.
159 * <p>
160 * vCard versions: 4.0
161 * </p>
162 * @param localId the local ID
163 * @param clientPidMapRef the ID used to reference the property's globally
164 * unique identifier in the CLIENTPIDMAP property.
165 * @see VCardSubTypes#addPid(int, int)
166 */
167 public void addPid(int localId, int clientPidMapRef) {
168 subTypes.addPid(localId, clientPidMapRef);
169 }
170
171 /**
172 * Removes all PID values.
173 * <p>
174 * vCard versions: 4.0
175 * </p>
176 * @see VCardSubTypes#removePids
177 */
178 public void removePids() {
179 subTypes.removePids();
180 }
181
182 /**
183 * Gets the preference value.
184 * <p>
185 * vCard versions: 4.0
186 * </p>
187 * @return the preference value or null if it doesn't exist
188 * @see VCardSubTypes#getPref
189 */
190 public Integer getPref() {
191 return subTypes.getPref();
192 }
193
194 /**
195 * Sets the preference value.
196 * <p>
197 * vCard versions: 4.0
198 * </p>
199 * @param pref the preference value or null to remove
200 * @see VCardSubTypes#setPref
201 */
202 public void setPref(Integer pref) {
203 subTypes.setPref(pref);
204 }
205
206 /**
207 * Gets the ALTID.
208 * <p>
209 * vCard versions: 4.0
210 * </p>
211 * @return the ALTID or null if it doesn't exist
212 * @see VCardSubTypes#getAltId
213 */
214 public String getAltId() {
215 return subTypes.getAltId();
216 }
217
218 /**
219 * Sets the ALTID.
220 * <p>
221 * vCard versions: 4.0
222 * </p>
223 * @param altId the ALTID or null to remove
224 * @see VCardSubTypes#setAltId
225 */
226 public void setAltId(String altId) {
227 subTypes.setAltId(altId);
228 }
229
230 @Override
231 public VCardVersion[] getSupportedVersions() {
232 return new VCardVersion[] { VCardVersion.V4_0 };
233 }
234
235 @Override
236 protected RelatedTypeParameter buildTypeObj(String type) {
237 RelatedTypeParameter param = RelatedTypeParameter.valueOf(type);
238 if (param == null) {
239 param = new RelatedTypeParameter(type);
240 }
241 return param;
242 }
243
244 @Override
245 protected void doMarshalSubTypes(VCardSubTypes copy, VCardVersion version, List<String> warnings, CompatibilityMode compatibilityMode, VCard vcard) {
246 if (uri != null) {
247 copy.setValue(ValueParameter.URI);
248 } else if (text != null) {
249 copy.setValue(ValueParameter.TEXT);
250 }
251 }
252
253 @Override
254 protected void doMarshalText(StringBuilder sb, VCardVersion version, List<String> warnings, CompatibilityMode compatibilityMode) {
255 if (uri != null) {
256 sb.append(VCardStringUtils.escape(uri));
257 } else if (text != null) {
258 sb.append(VCardStringUtils.escape(text));
259 } else {
260 throw new SkipMeException("Property has neither a URI nor a text value associated with it.");
261 }
262 }
263
264 @Override
265 protected void doUnmarshalText(String value, VCardVersion version, List<String> warnings, CompatibilityMode compatibilityMode) {
266 value = VCardStringUtils.unescape(value);
267 if (subTypes.getValue() == ValueParameter.URI) {
268 setUri(value);
269 } else if (subTypes.getValue() == ValueParameter.TEXT) {
270 setText(value);
271 } else {
272 warnings.add("No valid VALUE parameter specified for " + NAME + " type. Assuming it's text.");
273 setText(value);
274 }
275 }
276
277 @Override
278 protected void doMarshalXml(XCardElement parent, List<String> warnings, CompatibilityMode compatibilityMode) {
279 if (uri != null) {
280 parent.uri(uri);
281 } else if (text != null) {
282 parent.text(text);
283 } else {
284 throw new SkipMeException("Property has neither a URI nor a text value associated with it.");
285 }
286 }
287
288 @Override
289 protected void doUnmarshalXml(XCardElement element, List<String> warnings, CompatibilityMode compatibilityMode) {
290 String value = element.uri();
291 if (value != null) {
292 setUri(value);
293 } else {
294 setText(element.text());
295 }
296 }
297 }