001package ezvcard.property; 002 003import java.net.URI; 004import java.net.URISyntaxException; 005import java.util.LinkedHashMap; 006import java.util.List; 007import java.util.Map; 008import java.util.Objects; 009 010import ezvcard.SupportedVersions; 011import ezvcard.VCard; 012import ezvcard.VCardVersion; 013import ezvcard.ValidationWarning; 014import ezvcard.parameter.ImppType; 015import ezvcard.parameter.Pid; 016 017/* 018 Copyright (c) 2012-2026, Michael Angstadt 019 All rights reserved. 020 021 Redistribution and use in source and binary forms, with or without 022 modification, are permitted provided that the following conditions are met: 023 024 1. Redistributions of source code must retain the above copyright notice, this 025 list of conditions and the following disclaimer. 026 2. Redistributions in binary form must reproduce the above copyright notice, 027 this list of conditions and the following disclaimer in the documentation 028 and/or other materials provided with the distribution. 029 030 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 031 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 032 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 033 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 034 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 035 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 036 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 037 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 038 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 039 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 040 041 The views and conclusions contained in the software and documentation are those 042 of the authors and should not be interpreted as representing official policies, 043 either expressed or implied, of the FreeBSD Project. 044 */ 045 046/** 047 * <p> 048 * Defines an instant messenger handle. The handle is represented as a URI in 049 * the format "{@code <PROTOCOL>:<HANDLE>}". For example, a Yahoo! Messenger 050 * handle of "johndoe@yahoo.com" would look like this: 051 * "ymsgr:johndoe@yahoo.com". 052 * </p> 053 * 054 * <p> 055 * <b>Code sample</b> 056 * </p> 057 * 058 * <pre class="brush:java"> 059 * VCard vcard = new VCard(); 060 * 061 * //URI 062 * Impp impp = new Impp("aim:johndoe@aol.com"); 063 * vcard.addImpp(impp); 064 * 065 * //static factory methods 066 * impp = Impp.msn("janedoe@msn.com"); 067 * vcard.addImpp(impp); 068 * </pre> 069 * 070 * <p> 071 * <b>Property name:</b> {@code IMPP} 072 * </p> 073 * <p> 074 * <b>Supported versions:</b> {@code 3.0, 4.0} 075 * </p> 076 * @author Michael Angstadt 077 * @see <a href="http://tools.ietf.org/html/rfc6350#page-36">RFC 6350 p.36</a> 078 * @see <a href="http://tools.ietf.org/html/rfc4770">RFC 4770</a> 079 */ 080@SupportedVersions({ VCardVersion.V3_0, VCardVersion.V4_0 }) 081public class Impp extends VCardProperty implements HasAltId { 082 private static final String AIM = "aim"; 083 private static final String ICQ = "icq"; 084 private static final String IRC = "irc"; 085 private static final String MSN = "msnim"; 086 private static final String SIP = "sip"; 087 private static final String SKYPE = "skype"; 088 private static final String XMPP = "xmpp"; 089 private static final String YAHOO = "ymsgr"; 090 091 private URI uri; 092 093 /** 094 * Creates an IMPP property. Note that this class has static factory methods 095 * for creating IMPP properties of common IM protocols. 096 * @param uri the IM URI (e.g. "aim:johndoe@aol.com") 097 * @throws IllegalArgumentException if the URI is not a valid URI 098 */ 099 public Impp(String uri) { 100 setUri(uri); 101 } 102 103 /** 104 * Creates an IMPP property. Note that this class has static factory methods 105 * for creating IMPP properties of common IM protocols. 106 * @param uri the IM URI (e.g. "aim:johndoe@aol.com") 107 */ 108 public Impp(URI uri) { 109 setUri(uri); 110 } 111 112 /** 113 * Creates an IMPP property. Note that this class has static factory methods 114 * for creating IMPP properties of common IM protocols. 115 * @param protocol the IM protocol (e.g. "aim") 116 * @param handle the IM handle (e.g. "johndoe@aol.com") 117 */ 118 public Impp(String protocol, String handle) { 119 setUri(protocol, handle); 120 } 121 122 /** 123 * Copy constructor. 124 * @param original the property to make a copy of 125 */ 126 public Impp(Impp original) { 127 super(original); 128 uri = original.uri; 129 } 130 131 /** 132 * Creates an IMPP property that contains a AOL Instant Messenger handle. 133 * @param handle the IM handle 134 * @return the IMPP property instance 135 */ 136 public static Impp aim(String handle) { 137 return new Impp(AIM, handle); 138 } 139 140 /** 141 * Determines if this IMPP property contains an AOL Instant Messenger 142 * handle. 143 * @return true if it contains an AOL Instant Messenger handle, false if not 144 */ 145 public boolean isAim() { 146 return isProtocol(AIM); 147 } 148 149 /** 150 * Creates an IMPP property that contains a Yahoo! Messenger handle. 151 * @param handle the IM handle 152 * @return the IMPP property instance 153 */ 154 public static Impp yahoo(String handle) { 155 return new Impp(YAHOO, handle); 156 } 157 158 /** 159 * Determines if this IMPP property contains a Yahoo! Messenger handle. 160 * @return true if it contains a Yahoo! Messenger handle, false if not 161 */ 162 public boolean isYahoo() { 163 return isProtocol(YAHOO); 164 } 165 166 /** 167 * Creates an IMPP property that contains an MSN IMPP property. 168 * @param handle the IM handle 169 * @return the IMPP property instance 170 */ 171 public static Impp msn(String handle) { 172 return new Impp(MSN, handle); 173 } 174 175 /** 176 * Determines if this IMPP property contains an MSN handle. 177 * @return true if it contains an MSN handle, false if not 178 */ 179 public boolean isMsn() { 180 return isProtocol(MSN); 181 } 182 183 /** 184 * Creates an IMPP property that contains an ICQ handle. 185 * @param handle the IM handle 186 * @return the IMPP property instance 187 */ 188 public static Impp icq(String handle) { 189 return new Impp(ICQ, handle); 190 } 191 192 /** 193 * Determines if this IMPP property contains an ICQ handle. 194 * @return true if it contains an ICQ handle, false if not 195 */ 196 public boolean isIcq() { 197 return isProtocol(ICQ); 198 } 199 200 /** 201 * Creates an IMPP property that contains an IRC handle. 202 * @param handle the IM handle 203 * @return the IMPP property instance 204 */ 205 public static Impp irc(String handle) { 206 return new Impp(IRC, handle); 207 } 208 209 /** 210 * Determines if this IMPP property contains an IRC handle. 211 * @return true if it contains an IRC handle, false if not 212 */ 213 public boolean isIrc() { 214 return isProtocol(IRC); 215 } 216 217 /** 218 * Creates an IMPP property that contains a Session Initiation Protocol 219 * handle. 220 * @param handle the IM handle 221 * @return the IMPP property instance 222 */ 223 public static Impp sip(String handle) { 224 return new Impp(SIP, handle); 225 } 226 227 /** 228 * Determines if this IMPP property contains a Session Initiation Protocol 229 * handle. 230 * @return true if it contains a SIP handle, false if not 231 */ 232 public boolean isSip() { 233 return isProtocol(SIP); 234 } 235 236 /** 237 * Creates an IMPP property that contains a Skype handle. 238 * @param handle the IM handle 239 * @return the IMPP property instance 240 */ 241 public static Impp skype(String handle) { 242 return new Impp(SKYPE, handle); 243 } 244 245 /** 246 * Determines if this IMPP property contains a Skype handle. 247 * @return true if it contains a Skype handle, false if not 248 */ 249 public boolean isSkype() { 250 return isProtocol(SKYPE); 251 } 252 253 /** 254 * Creates an IMPP property that contains an Extensible Messaging and 255 * Presence Protocol handle. 256 * @param handle the IM handle 257 * @return the IMPP property instance 258 */ 259 public static Impp xmpp(String handle) { 260 return new Impp(XMPP, handle); 261 } 262 263 /** 264 * Determines if this IMPP property contains an Extensible Messaging and 265 * Presence Protocol handle. 266 * @return true if it contains an XMPP handle, false if not 267 */ 268 public boolean isXmpp() { 269 return isProtocol(XMPP); 270 } 271 272 private boolean isProtocol(String protocol) { 273 return uri != null && protocol.equalsIgnoreCase(uri.getScheme()); 274 } 275 276 /** 277 * Gets the IM URI. 278 * @return the IM URI 279 */ 280 public URI getUri() { 281 return uri; 282 } 283 284 /** 285 * Sets the IM URI. 286 * @param uri the IM URI (e.g. "aim:theuser@aol.com") 287 * @throws IllegalArgumentException if the URI is not a valid URI 288 */ 289 public void setUri(String uri) { 290 setUri((uri == null) ? null : URI.create(uri)); 291 } 292 293 /** 294 * Sets the IM URI. 295 * @param uri the IM URI (e.g. "aim:theuser@aol.com") 296 */ 297 public void setUri(URI uri) { 298 this.uri = uri; 299 } 300 301 /** 302 * Sets the IM URI. 303 * @param protocol the IM protocol (e.g. "aim") 304 * @param handle the IM handle (e.g. "theuser@aol.com") 305 */ 306 public void setUri(String protocol, String handle) { 307 try { 308 this.uri = new URI(protocol, handle, null); 309 } catch (URISyntaxException e) { 310 throw new IllegalArgumentException(e); 311 } 312 } 313 314 /** 315 * Gets the IM protocol. Use {@link #setUri(String, String)} to set the 316 * protocol. 317 * @return the IM protocol (e.g. "aim") or null if not set 318 */ 319 public String getProtocol() { 320 if (uri == null) { 321 return null; 322 } 323 return uri.getScheme(); 324 } 325 326 /** 327 * Gets the IM handle. Use {@link #setUri(String, String)} to set the 328 * handle. 329 * @return the IM handle (e.g. "johndoe@aol.com") or null if not set 330 */ 331 public String getHandle() { 332 if (uri == null) { 333 return null; 334 } 335 return uri.getSchemeSpecificPart(); 336 } 337 338 /** 339 * Gets the list that stores this property's IMPP types (TYPE parameters). 340 * @return the IMPP types (e.g. "HOME", "WORK") (this list is mutable) 341 */ 342 public List<ImppType> getTypes() { 343 return parameters.new TypeParameterList<ImppType>() { 344 @Override 345 protected ImppType _asObject(String value) { 346 return ImppType.get(value); 347 } 348 }; 349 } 350 351 /** 352 * Gets the MEDIATYPE parameter. 353 * <p> 354 * <b>Supported versions:</b> {@code 4.0} 355 * </p> 356 * @return the media type or null if not set 357 */ 358 public String getMediaType() { 359 return parameters.getMediaType(); 360 } 361 362 /** 363 * Sets the MEDIATYPE parameter. 364 * <p> 365 * <b>Supported versions:</b> {@code 4.0} 366 * </p> 367 * @param mediaType the media type or null to remove 368 */ 369 public void setMediaType(String mediaType) { 370 parameters.setMediaType(mediaType); 371 } 372 373 @Override 374 public List<Pid> getPids() { 375 return super.getPids(); 376 } 377 378 @Override 379 public Integer getPref() { 380 return super.getPref(); 381 } 382 383 @Override 384 public void setPref(Integer pref) { 385 super.setPref(pref); 386 } 387 388 //@Override 389 public String getAltId() { 390 return parameters.getAltId(); 391 } 392 393 //@Override 394 public void setAltId(String altId) { 395 parameters.setAltId(altId); 396 } 397 398 @Override 399 protected void _validate(List<ValidationWarning> warnings, VCardVersion version, VCard vcard) { 400 if (uri == null) { 401 warnings.add(new ValidationWarning(8)); 402 } 403 } 404 405 @Override 406 protected Map<String, Object> toStringValues() { 407 Map<String, Object> values = new LinkedHashMap<>(); 408 values.put("uri", uri); 409 return values; 410 } 411 412 @Override 413 public Impp copy() { 414 return new Impp(this); 415 } 416 417 @Override 418 public int hashCode() { 419 final int prime = 31; 420 int result = super.hashCode(); 421 result = prime * result + Objects.hash(uri); 422 return result; 423 } 424 425 @Override 426 public boolean equals(Object obj) { 427 if (this == obj) return true; 428 if (!super.equals(obj)) return false; 429 if (getClass() != obj.getClass()) return false; 430 Impp other = (Impp) obj; 431 return Objects.equals(uri, other.uri); 432 } 433}