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