001    package ezvcard.types;
002    
003    import java.util.List;
004    import java.util.UUID;
005    
006    import ezvcard.VCardSubTypes;
007    import ezvcard.VCardVersion;
008    import ezvcard.io.CompatibilityMode;
009    import ezvcard.util.VCardStringUtils;
010    import ezvcard.util.XCardElement;
011    
012    /*
013     Copyright (c) 2012, 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     * <p>
043     * Maps a globally-unique URI to a PID parameter value. The PID parameter can be
044     * set on any type where multiple instances are allowed (such as EMAIL or ADR,
045     * but not N because only 1 instance of N is allowed). It allows an individual
046     * type instance to be uniquely identifiable.
047     * </p>
048     * 
049     * <p>
050     * The CLIENTPIDMAP type and the PID parameter are used during the
051     * synchronization (merging) process of two versions of the same vCard. For
052     * example, if the user has a copy of her vCard on her desktop computer and her
053     * smart phone, and she makes different modifications to each copy, then the two
054     * copies could be synchronized in order to merge all the changes into a single,
055     * new vCard.
056     * </p>
057     * 
058     * <pre>
059     * VCard vcard = new VCard();
060     * 
061     * AddressType adr = new AddressType();
062     * adr.addPid(1, 1);
063     * vcard.addAddress(adr);
064     * 
065     * EmailType email = new EmailType(&quot;my-email@hotmail.com&quot;);
066     * emai.addPid(1, 1);
067     * vcard.addEmail(email);
068     * email = new EmailType(&quot;my-other-email@yahoo.com&quot;);
069     * emai.addPid(2, 2);
070     * vcard.addEmail(email);
071     * 
072     * //specify the URI to use
073     * ClientPidMapType clientpidmap = new ClientPidMapType(1, &quot;urn:uuid:03a0e51f-d1aa-4385-8a53-e29025acd8af&quot;);
074     * vcard.addClientPidMap(clientpidmap);
075     * 
076     * //generate a random URI
077     * clientpidmap = ClientPidMapType.random(2);
078     * vcard.addClientPidMap(clientpidmap);
079     * </pre>
080     * 
081     * <p>
082     * vCard property name: CLIENTPIDMAP
083     * </p>
084     * <p>
085     * vCard versions: 4.0
086     * </p>
087     * @author Michael Angstadt
088     */
089    public class ClientPidMapType extends VCardType {
090            public static final String NAME = "CLIENTPIDMAP";
091    
092            private Integer pid;
093            private String uri;
094    
095            public ClientPidMapType() {
096                    super(NAME);
097            }
098    
099            /**
100             * @param pid the PID
101             * @param uri the globally unique URI
102             */
103            public ClientPidMapType(int pid, String uri) {
104                    super(NAME);
105                    this.pid = pid;
106                    this.uri = uri;
107            }
108    
109            /**
110             * Generates a CLIENTPIDMAP type that contains a random UID URI.
111             * @param pid the PID
112             * @return a CLIENTPIDMAP type with a random UID URI
113             */
114            public static ClientPidMapType random(int pid) {
115                    String uuid = UUID.randomUUID().toString();
116                    return new ClientPidMapType(pid, "urn:uuid:" + uuid);
117            }
118    
119            /**
120             * Gets the value that is used to link the URI in this property to the
121             * property that the URI belongs to.
122             * @return the PID
123             * @see VCardSubTypes#getPids
124             */
125            public Integer getPid() {
126                    return pid;
127            }
128    
129            /**
130             * Gets the value that is used to link the URI in this property to the
131             * property that the URI belongs to.
132             * @param pid the PID
133             * @see VCardSubTypes#getPids
134             */
135            public void setPid(Integer pid) {
136                    this.pid = pid;
137            }
138    
139            /**
140             * Gets the URI.
141             * @return the URI
142             */
143            public String getUri() {
144                    return uri;
145            }
146    
147            /**
148             * Sets the URI.
149             * @param uri the URI
150             */
151            public void setUri(String uri) {
152                    this.uri = uri;
153            }
154    
155            @Override
156            public VCardVersion[] getSupportedVersions() {
157                    return new VCardVersion[] { VCardVersion.V4_0 };
158            }
159    
160            @Override
161            protected void doMarshalText(StringBuilder sb, VCardVersion version, List<String> warnings, CompatibilityMode compatibilityMode) {
162                    sb.append(pid + ";" + VCardStringUtils.escape(uri));
163            }
164    
165            @Override
166            protected void doUnmarshalText(String value, VCardVersion version, List<String> warnings, CompatibilityMode compatibilityMode) {
167                    String split[] = value.split(";", 2);
168                    if (split.length < 2) {
169                            warnings.add("Incorrect format of " + NAME + " type value: \"" + value + "\"");
170                    } else {
171                            pid = Integer.parseInt(split[0]);
172                            uri = VCardStringUtils.unescape(split[1]);
173                    }
174            }
175    
176            @Override
177            protected void doMarshalXml(XCardElement parent, List<String> warnings, CompatibilityMode compatibilityMode) {
178                    if (uri != null) {
179                            parent.uri(uri);
180                    }
181                    if (pid != null) {
182                            parent.append("sourceid", pid.toString());
183                    }
184            }
185    
186            @Override
187            protected void doUnmarshalXml(XCardElement element, List<String> warnings, CompatibilityMode compatibilityMode) {
188                    uri = element.uri();
189    
190                    String value = element.get("sourceid");
191                    pid = (value != null) ? Integer.parseInt(value) : null;
192            }
193    }