001    package ezvcard.property;
002    
003    import java.net.URI;
004    import java.net.URISyntaxException;
005    import java.util.EnumSet;
006    import java.util.HashSet;
007    import java.util.List;
008    import java.util.Set;
009    
010    import ezvcard.VCard;
011    import ezvcard.VCardVersion;
012    import ezvcard.Warning;
013    import ezvcard.parameter.ImppType;
014    
015    /*
016     Copyright (c) 2013, 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     * An instant message handle. The handle is represented as a URI in the format "
046     * {@code <IM-PROTOCOL>:<IM-HANDLE>}". For example, someone with a Yahoo!
047     * Messenger handle of "johndoe@yahoo.com" would have an IMPP vCard property
048     * value of "ymsgr:johndoe@yahoo.com".
049     * 
050     * <p>
051     * <b>Code sample</b>
052     * </p>
053     * 
054     * <pre class="brush:java">
055     * VCard vcard = new VCard();
056     * 
057     * //URI
058     * Impp impp = new Impp(&quot;aim:johndoe@aol.com&quot;);
059     * vcard.addImpp(impp);
060     * 
061     * //static factory methods
062     * impp = Impp.msn(&quot;janedoe@msn.com&quot;);
063     * vcard.addImpp(impp);
064     * </pre>
065     * 
066     * <p>
067     * <b>Property name:</b> {@code IMPP}
068     * </p>
069     * <p>
070     * <b>Supported versions:</b> {@code 3.0, 4.0}
071     * </p>
072     * @author Michael Angstadt
073     */
074    public class Impp extends VCardProperty implements HasAltId {
075            private static final String AIM = "aim";
076            private static final String ICQ = "icq";
077            private static final String IRC = "irc";
078            private static final String MSN = "msnim";
079            private static final String SIP = "sip";
080            private static final String SKYPE = "skype";
081            private static final String XMPP = "xmpp";
082            private static final String YAHOO = "ymsgr";
083    
084            private URI uri;
085    
086            /**
087             * Creates an IMPP property. Note that this class has static factory methods
088             * for creating IMPP properties of common IM protocols.
089             * @param uri the IM URI (e.g. "aim:johndoe@aol.com")
090             * @throws IllegalArgumentException if the URI is not a valid URI
091             */
092            public Impp(String uri) {
093                    setUri(uri);
094            }
095    
096            /**
097             * Creates an IMPP property. Note that this class has static factory methods
098             * for creating IMPP properties of common IM protocols.
099             * @param uri the IM URI (e.g. "aim:johndoe@aol.com")
100             */
101            public Impp(URI uri) {
102                    setUri(uri);
103            }
104    
105            /**
106             * Creates an IMPP property. Note that this class has static factory methods
107             * for creating IMPP properties of common IM protocols.
108             * @param protocol the IM protocol (e.g. "aim")
109             * @param handle the IM handle (e.g. "johndoe@aol.com")
110             */
111            public Impp(String protocol, String handle) {
112                    setUri(protocol, handle);
113            }
114    
115            @Override
116            public Set<VCardVersion> _supportedVersions() {
117                    return EnumSet.of(VCardVersion.V3_0, VCardVersion.V4_0);
118            }
119    
120            /**
121             * Creates an IMPP property that contains a AOL Instant Messenger handle.
122             * @param handle the IM handle
123             * @return the IMPP property instance
124             */
125            public static Impp aim(String handle) {
126                    return new Impp(AIM, handle);
127            }
128    
129            /**
130             * Determines if this IMPP property contains an AOL Instant Messenger
131             * handle.
132             * @return true if it contains an AOL Instant Messenger handle, false if not
133             */
134            public boolean isAim() {
135                    return isProtocol(AIM);
136            }
137    
138            /**
139             * Creates an IMPP property that contains a Yahoo! Messenger handle.
140             * @param handle the IM handle
141             * @return the IMPP property instance
142             */
143            public static Impp yahoo(String handle) {
144                    return new Impp(YAHOO, handle);
145            }
146    
147            /**
148             * Determines if this IMPP property contains a Yahoo! Messenger handle.
149             * @return true if it contains a Yahoo! Messenger handle, false if not
150             */
151            public boolean isYahoo() {
152                    return isProtocol(YAHOO);
153            }
154    
155            /**
156             * Creates an IMPP property that contains an MSN IMPP property.
157             * @param handle the IM handle
158             * @return the IMPP property instance
159             */
160            public static Impp msn(String handle) {
161                    return new Impp(MSN, handle);
162            }
163    
164            /**
165             * Determines if this IMPP property contains an MSN handle.
166             * @return true if it contains an MSN handle, false if not
167             */
168            public boolean isMsn() {
169                    return isProtocol(MSN);
170            }
171    
172            /**
173             * Creates an IMPP property that contains an ICQ handle.
174             * @param handle the IM handle
175             * @return the IMPP property instance
176             */
177            public static Impp icq(String handle) {
178                    return new Impp(ICQ, handle);
179            }
180    
181            /**
182             * Determines if this IMPP property contains an ICQ handle.
183             * @return true if it contains an ICQ handle, false if not
184             */
185            public boolean isIcq() {
186                    return isProtocol(ICQ);
187            }
188    
189            /**
190             * Creates an IMPP property that contains an IRC handle.
191             * @param handle the IM handle
192             * @return the IMPP property instance
193             */
194            public static Impp irc(String handle) {
195                    return new Impp(IRC, handle);
196            }
197    
198            /**
199             * Determines if this IMPP property contains an IRC handle.
200             * @return true if it contains an IRC handle, false if not
201             */
202            public boolean isIrc() {
203                    return isProtocol(IRC);
204            }
205    
206            /**
207             * Creates an IMPP property that contains a Session Initiation Protocol
208             * handle.
209             * @param handle the IM handle
210             * @return the IMPP property instance
211             */
212            public static Impp sip(String handle) {
213                    return new Impp(SIP, handle);
214            }
215    
216            /**
217             * Determines if this IMPP property contains a Session Initiation Protocol
218             * handle.
219             * @return true if it contains a SIP handle, false if not
220             */
221            public boolean isSip() {
222                    return isProtocol(SIP);
223            }
224    
225            /**
226             * Creates an IMPP property that contains a Skype handle.
227             * @param handle the IM handle
228             * @return the IMPP property instance
229             */
230            public static Impp skype(String handle) {
231                    return new Impp(SKYPE, handle);
232            }
233    
234            /**
235             * Determines if this IMPP property contains a Skype handle.
236             * @return true if it contains a Skype handle, false if not
237             */
238            public boolean isSkype() {
239                    return isProtocol(SKYPE);
240            }
241    
242            /**
243             * Creates an IMPP property that contains an Extensible Messaging and
244             * Presence Protocol handle.
245             * @param handle the IM handle
246             * @return the IMPP property instance
247             */
248            public static Impp xmpp(String handle) {
249                    return new Impp(XMPP, handle);
250            }
251    
252            /**
253             * Determines if this IMPP property contains an Extensible Messaging and
254             * Presence Protocol handle.
255             * @return true if it contains an XMPP handle, false if not
256             */
257            public boolean isXmpp() {
258                    return isProtocol(XMPP);
259            }
260    
261            private boolean isProtocol(String protocol) {
262                    return uri != null && protocol.equals(uri.getScheme());
263            }
264    
265            /**
266             * Gets the IM URI.
267             * @return the IM URI
268             */
269            public URI getUri() {
270                    return uri;
271            }
272    
273            /**
274             * Sets the IM URI.
275             * @param uri the IM URI (e.g. "aim:theuser@aol.com")
276             * @throws IllegalArgumentException if the URI is not a valid URI
277             */
278            public void setUri(String uri) {
279                    setUri((uri == null) ? null : URI.create(uri));
280            }
281    
282            /**
283             * Sets the IM URI.
284             * @param uri the IM URI (e.g. "aim:theuser@aol.com")
285             */
286            public void setUri(URI uri) {
287                    this.uri = uri;
288            }
289    
290            /**
291             * Sets the IM URI.
292             * @param protocol the IM protocol (e.g. "aim")
293             * @param handle the IM handle (e.g. "theuser@aol.com")
294             */
295            public void setUri(String protocol, String handle) {
296                    try {
297                            this.uri = new URI(protocol, handle, null);
298                    } catch (URISyntaxException e) {
299                            throw new IllegalArgumentException(e);
300                    }
301            }
302    
303            /**
304             * Gets the IM protocol. Use {@link #setUri(String, String)} to set the
305             * protocol.
306             * @return the IM protocol (e.g. "aim") or null if not set
307             */
308            public String getProtocol() {
309                    if (uri == null) {
310                            return null;
311                    }
312                    return uri.getScheme();
313            }
314    
315            /**
316             * Gets the IM handle. Use {@link #setUri(String, String)} to set the
317             * handle.
318             * @return the IM handle (e.g. "johndoe@aol.com") or null if not set
319             */
320            public String getHandle() {
321                    if (uri == null) {
322                            return null;
323                    }
324                    return uri.getSchemeSpecificPart();
325            }
326    
327            /**
328             * Gets all the TYPE parameters.
329             * @return the TYPE parameters or empty set if there are none
330             */
331            public Set<ImppType> getTypes() {
332                    Set<String> values = parameters.getTypes();
333                    Set<ImppType> types = new HashSet<ImppType>(values.size());
334                    for (String value : values) {
335                            types.add(ImppType.get(value));
336                    }
337                    return types;
338            }
339    
340            /**
341             * Adds a TYPE parameter.
342             * @param type the TYPE parameter to add
343             */
344            public void addType(ImppType type) {
345                    parameters.addType(type.getValue());
346            }
347    
348            /**
349             * Removes a TYPE parameter.
350             * @param type the TYPE parameter to remove
351             */
352            public void removeType(ImppType type) {
353                    parameters.removeType(type.getValue());
354            }
355    
356            /**
357             * Gets the MEDIATYPE parameter.
358             * <p>
359             * <b>Supported versions:</b> {@code 4.0}
360             * </p>
361             * @return the media type or null if not set
362             */
363            public String getMediaType() {
364                    return parameters.getMediaType();
365            }
366    
367            /**
368             * Sets the MEDIATYPE parameter.
369             * <p>
370             * <b>Supported versions:</b> {@code 4.0}
371             * </p>
372             * @param mediaType the media type or null to remove
373             */
374            public void setMediaType(String mediaType) {
375                    parameters.setMediaType(mediaType);
376            }
377    
378            @Override
379            public List<Integer[]> getPids() {
380                    return super.getPids();
381            }
382    
383            @Override
384            public void addPid(int localId, int clientPidMapRef) {
385                    super.addPid(localId, clientPidMapRef);
386            }
387    
388            @Override
389            public void removePids() {
390                    super.removePids();
391            }
392    
393            @Override
394            public Integer getPref() {
395                    return super.getPref();
396            }
397    
398            @Override
399            public void setPref(Integer pref) {
400                    super.setPref(pref);
401            }
402    
403            //@Override
404            public String getAltId() {
405                    return parameters.getAltId();
406            }
407    
408            //@Override
409            public void setAltId(String altId) {
410                    parameters.setAltId(altId);
411            }
412    
413            @Override
414            protected void _validate(List<Warning> warnings, VCardVersion version, VCard vcard) {
415                    if (uri == null) {
416                            warnings.add(new Warning(8));
417                    }
418            }
419    }