001    package ezvcard.types;
002    
003    import java.util.List;
004    
005    import ezvcard.VCardVersion;
006    import ezvcard.io.CompatibilityMode;
007    import ezvcard.util.VCardStringUtils;
008    import ezvcard.util.XCardElement;
009    
010    /*
011     Copyright (c) 2012, Michael Angstadt
012     All rights reserved.
013    
014     Redistribution and use in source and binary forms, with or without
015     modification, are permitted provided that the following conditions are met: 
016    
017     1. Redistributions of source code must retain the above copyright notice, this
018     list of conditions and the following disclaimer. 
019     2. Redistributions in binary form must reproduce the above copyright notice,
020     this list of conditions and the following disclaimer in the documentation
021     and/or other materials provided with the distribution. 
022    
023     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
024     ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
025     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
026     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
027     ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
028     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
029     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
030     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
031     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
032     SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
033    
034     The views and conclusions contained in the software and documentation are those
035     of the authors and should not be interpreted as representing official policies, 
036     either expressed or implied, of the FreeBSD Project.
037     */
038    
039    /**
040     * Defines the person's sex.
041     * 
042     * <p>
043     * <b>Setting the gender</b>
044     * </p>
045     * 
046     * <pre>
047     * VCard vcard = new VCard();
048     * GenderType gender = GenderType.male();
049     * vcard.setGender(gender);
050     * </pre>
051     * 
052     * <p>
053     * <b>Getting the gender</b>
054     * </p>
055     * 
056     * <pre>
057     * VCard vcard = ...
058     * GenderType gender = vcard.getGender();
059     * if (gender != null){
060     *   if (gender.isMale()){
061     *     ...
062     *   } else if (gender.isFemale()){
063     *     ...
064     *   }
065     *   ...
066     * }
067     * </pre>
068     * 
069     * <p>
070     * vCard property name: GENDER
071     * </p>
072     * <p>
073     * vCard versions: 4.0
074     * </p>
075     * @author Michael Angstadt
076     */
077    public class GenderType extends VCardType {
078            public static final String NAME = "GENDER";
079    
080            public static final String MALE = "M";
081            public static final String FEMALE = "F";
082            public static final String OTHER = "O";
083            public static final String NONE = "N";
084            public static final String UNKNOWN = "U";
085    
086            private String gender;
087            private String text;
088    
089            public GenderType() {
090                    super(NAME);
091            }
092    
093            /**
094             * Use of this constructor is discouraged. Please use one of the static
095             * methods to create a new GENDER type.
096             * @param gender the gender value (e.g. "F")
097             */
098            public GenderType(String gender) {
099                    super(NAME);
100                    this.gender = gender;
101            }
102    
103            /**
104             * Gets the additional text associated with this gender type.
105             * @return the additional text or null if there is no text
106             */
107            public String getText() {
108                    return text;
109            }
110    
111            /**
112             * Sets the additional text associated with this gender type.
113             * @param text additional text or null to remove
114             */
115            public void setText(String text) {
116                    this.text = text;
117            }
118    
119            /**
120             * Gets the gender value.
121             * @return the gender value (see static strings for the possible values)
122             */
123            public String getGender() {
124                    return gender;
125            }
126    
127            /**
128             * Sets the gender value.
129             * @param gender the gender value (see static strings for the possible
130             * values)
131             */
132            public void setGender(String gender) {
133                    this.gender = gender;
134            }
135    
136            /**
137             * Determines if the gender is "male" or not.
138             * @return true if the gender is "male", false if not
139             */
140            public boolean isMale() {
141                    return MALE.equals(gender);
142            }
143    
144            /**
145             * Determines if the gender is "female" or not.
146             * @return true if the gender is "female", false if not
147             */
148            public boolean isFemale() {
149                    return FEMALE.equals(gender);
150            }
151    
152            /**
153             * Determines if the gender is "other" or not.
154             * @return true if the gender is "other", false if not
155             */
156            public boolean isOther() {
157                    return OTHER.equals(gender);
158            }
159    
160            /**
161             * Determines if the gender is "none" or not. A group, organization, or
162             * location may have this gender type.
163             * @return true if the gender is "none", false if not
164             */
165            public boolean isNone() {
166                    return NONE.equals(gender);
167            }
168    
169            /**
170             * Determines if the gender is "unknown" or not.
171             * @return true if the gender is "unknown", false if not
172             */
173            public boolean isUnknown() {
174                    return UNKNOWN.equals(gender);
175            }
176    
177            /**
178             * Creates a gender type whose value is set to "male".
179             * @return a "male" gender type
180             */
181            public static GenderType male() {
182                    return new GenderType(MALE);
183            }
184    
185            /**
186             * Creates a gender type whose value is set to "female".
187             * @return a "female" gender type
188             */
189            public static GenderType female() {
190                    return new GenderType(FEMALE);
191            }
192    
193            /**
194             * Creates a gender type whose value is set to "other".
195             * @return an "other" gender type
196             */
197            public static GenderType other() {
198                    return new GenderType(OTHER);
199            }
200    
201            /**
202             * Creates a gender type whose value is set to "none". Groups,
203             * organizations, and locations should be given this gender type.
204             * @return a "none" gender type
205             */
206            public static GenderType none() {
207                    return new GenderType(NONE);
208            }
209    
210            /**
211             * Creates a gender type whose value is set to "unknown".
212             * @return a "unknown" gender type
213             */
214            public static GenderType unknown() {
215                    return new GenderType(UNKNOWN);
216            }
217    
218            @Override
219            public VCardVersion[] getSupportedVersions() {
220                    return new VCardVersion[] { VCardVersion.V4_0 };
221            }
222    
223            @Override
224            protected void doMarshalText(StringBuilder sb, VCardVersion version, List<String> warnings, CompatibilityMode compatibilityMode) {
225                    if (gender != null) {
226                            sb.append(gender);
227                    }
228                    if (text != null) {
229                            sb.append(';');
230                            sb.append(VCardStringUtils.escape(text));
231                    }
232            }
233    
234            @Override
235            protected void doUnmarshalText(String value, VCardVersion version, List<String> warnings, CompatibilityMode compatibilityMode) {
236                    String split[] = value.split(";", 2);
237                    setGender(split[0].toUpperCase());
238                    if (split.length > 1) {
239                            setText(VCardStringUtils.unescape(split[1]));
240                    }
241            }
242    
243            @Override
244            protected void doMarshalXml(XCardElement parent, List<String> warnings, CompatibilityMode compatibilityMode) {
245                    parent.append("sex", (gender == null) ? "" : gender);
246                    if (text != null) {
247                            parent.append("identity", text);
248                    }
249            }
250    
251            @Override
252            protected void doUnmarshalXml(XCardElement element, List<String> warnings, CompatibilityMode compatibilityMode) {
253                    setGender(element.get("sex"));
254                    setText(element.get("identity"));
255            }
256    }