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.ValueParameter;
011    import ezvcard.util.VCardStringUtils;
012    import ezvcard.util.XCardElement;
013    
014    /*
015     Copyright (c) 2012, 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     * Defines the location of the person's birth.
045     * 
046     * <pre>
047     * VCard vcard = new VCard();
048     * 
049     * //URI (geo)
050     * BirthplaceType birthplace = new BirthplaceType();
051     * birthplace.setUri(&quot;geo:39.970806,-75.174809&quot;);
052     * vcard.setBirthplace(birthplace);
053     * 
054     * //URI (website)
055     * birthplace = new BirthplaceType();
056     * birthplace.setUri(&quot;http://www.chop.edu&quot;);
057     * vcard.setBirthplace(birthplace);
058     * 
059     * //text
060     * birthplace = new BirthplaceType();
061     * birthplace.setText(&quot;The Children's Hospital of Philadelphia&quot;);
062     * vcard.setBirthplace(birthplace);
063     * 
064     * //text
065     * birthplace = new BirthplaceType();
066     * birthplace.setText(&quot;Philadelphia, PA&quot;);
067     * vcard.setBirthplace(birthplace);
068     * </pre>
069     * 
070     * <p>
071     * vCard property name: BIRTHPLACE
072     * </p>
073     * <p>
074     * vCard versions: 4.0
075     * </p>
076     * @author Michael Angstadt
077     * @see <a href="http://tools.ietf.org/html/rfc6474">RFC 6474</a>
078     */
079    public class BirthplaceType extends VCardType {
080            public static final String NAME = "BIRTHPLACE";
081    
082            private String uri;
083            private String text;
084    
085            public BirthplaceType() {
086                    super(NAME);
087            }
088    
089            /**
090             * Gets the URI value.
091             * @return the URI value or null if no URI value is set
092             */
093            public String getUri() {
094                    return uri;
095            }
096    
097            /**
098             * Sets the value to a URI.
099             * @param uri the URI
100             */
101            public void setUri(String uri) {
102                    this.uri = uri;
103                    text = null;
104            }
105    
106            /**
107             * Gets the text value.
108             * @return the text value or null if no text value is set
109             */
110            public String getText() {
111                    return text;
112            }
113    
114            /**
115             * Sets the value to free-form text.
116             * @param text the text
117             */
118            public void setText(String text) {
119                    this.text = text;
120                    uri = null;
121            }
122    
123            /**
124             * Gets the ALTID.
125             * <p>
126             * vCard versions: 4.0
127             * </p>
128             * @return the ALTID or null if it doesn't exist
129             * @see VCardSubTypes#getAltId
130             */
131            public String getAltId() {
132                    return subTypes.getAltId();
133            }
134    
135            /**
136             * Sets the ALTID.
137             * <p>
138             * vCard versions: 4.0
139             * </p>
140             * @param altId the ALTID or null to remove
141             * @see VCardSubTypes#setAltId
142             */
143            public void setAltId(String altId) {
144                    subTypes.setAltId(altId);
145            }
146    
147            /**
148             * Gets the LANGUAGE parameter.
149             * @return the language or null if not set
150             * @see VCardSubTypes#getLanguage
151             */
152            public String getLanguage() {
153                    return subTypes.getLanguage();
154            }
155    
156            /**
157             * Sets the LANGUAGE parameter.
158             * @param language the language or null to remove
159             * @see VCardSubTypes#setLanguage
160             */
161            public void setLanguage(String language) {
162                    subTypes.setLanguage(language);
163            }
164    
165            @Override
166            public VCardVersion[] getSupportedVersions() {
167                    return new VCardVersion[] { VCardVersion.V4_0 };
168            }
169    
170            @Override
171            protected void doMarshalSubTypes(VCardSubTypes copy, VCardVersion version, List<String> warnings, CompatibilityMode compatibilityMode, VCard vcard) {
172                    if (uri != null) {
173                            copy.setValue(ValueParameter.URI);
174                    } else if (text != null) {
175                            copy.setValue(ValueParameter.TEXT);
176                    }
177            }
178    
179            @Override
180            protected void doMarshalText(StringBuilder sb, VCardVersion version, List<String> warnings, CompatibilityMode compatibilityMode) {
181                    if (uri != null) {
182                            sb.append(VCardStringUtils.escape(uri));
183                    } else if (text != null) {
184                            sb.append(VCardStringUtils.escape(text));
185                    } else {
186                            throw new SkipMeException("Property has neither a URI nor a text value associated with it.");
187                    }
188            }
189    
190            @Override
191            protected void doUnmarshalText(String value, VCardVersion version, List<String> warnings, CompatibilityMode compatibilityMode) {
192                    value = VCardStringUtils.unescape(value);
193                    if (subTypes.getValue() == ValueParameter.URI) {
194                            setUri(value);
195                    } else if (subTypes.getValue() == ValueParameter.TEXT) {
196                            setText(value);
197                    } else {
198                            warnings.add("No valid VALUE parameter specified for " + NAME + " type.  Assuming it's text.");
199                            setText(value);
200                    }
201            }
202    
203            @Override
204            protected void doMarshalXml(XCardElement parent, List<String> warnings, CompatibilityMode compatibilityMode) {
205                    if (uri != null) {
206                            parent.uri(uri);
207                    } else if (text != null) {
208                            parent.text(text);
209                    } else {
210                            throw new SkipMeException("Property has neither a URI nor a text value associated with it.");
211                    }
212            }
213    
214            @Override
215            protected void doUnmarshalXml(XCardElement element, List<String> warnings, CompatibilityMode compatibilityMode) {
216                    String value = element.uri();
217                    if (value != null) {
218                            setUri(value);
219                    } else {
220                            setText(element.text());
221                    }
222            }
223    }