001package ezvcard.property; 002 003import java.util.LinkedHashMap; 004import java.util.List; 005import java.util.Map; 006 007import ezvcard.SupportedVersions; 008import ezvcard.VCard; 009import ezvcard.VCardVersion; 010import ezvcard.ValidationWarning; 011import ezvcard.parameter.Pid; 012import ezvcard.parameter.RelatedType; 013import ezvcard.util.TelUri; 014 015/* 016 Copyright (c) 2012-2023, 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 * <p> 046 * Defines someone that the person is related to. 047 * </p> 048 * 049 * <p> 050 * <b>Code sample</b> 051 * </p> 052 * 053 * <pre class="brush:java"> 054 * VCard vcard = new VCard(); 055 * 056 * //static factory methods 057 * Related related = Related.email("bob.smith@example.com"); 058 * related.getTypes().add(RelatedType.CO_WORKER); 059 * related.getTypes().add(RelatedType.FRIEND); 060 * vcard.addRelated(related); 061 * 062 * //free-form text 063 * related = new Related(); 064 * related.setText("Edna Smith"); 065 * related.getTypes().add(RelatedType.SPOUSE); 066 * vcard.addRelated(related); 067 * 068 * //reference another vCard by putting its UID property here 069 * related = new Related("urn:uuid:03a0e51f-d1aa-4385-8a53-e29025acd8af"); 070 * related.getTypes().add(RelatedType.SIBLING); 071 * vcard.addRelated(related); 072 * </pre> 073 * 074 * <p> 075 * <b>Property name:</b> {@code RELATED} 076 * </p> 077 * <p> 078 * <b>Supported versions:</b> {@code 4.0} 079 * </p> 080 * @author Michael Angstadt 081 * @see <a href="http://tools.ietf.org/html/rfc6350#page-42">RFC 6350 p.42</a> 082 */ 083@SupportedVersions(VCardVersion.V4_0) 084public class Related extends VCardProperty implements HasAltId { 085 private String uri; 086 private String text; 087 088 /** 089 * Creates a related property 090 */ 091 public Related() { 092 //empty 093 } 094 095 /** 096 * Creates a related property. 097 * @param uri the URI representing the person 098 */ 099 public Related(String uri) { 100 setUri(uri); 101 } 102 103 /** 104 * Copy constructor. 105 * @param original the property to make a copy of 106 */ 107 public Related(Related original) { 108 super(original); 109 uri = original.uri; 110 text = original.text; 111 } 112 113 /** 114 * Creates a related property whose value is an email address. 115 * @param email the email address 116 * @return the property 117 */ 118 public static Related email(String email) { 119 return new Related("mailto:" + email); 120 } 121 122 /** 123 * Creates a related property whose value is an instant messenger handle. 124 * @param protocol the instant messenger protocol (e.g. "aim") 125 * @param handle the instant messenger handle (e.g. "johndoe") 126 * @return the property 127 */ 128 public static Related im(String protocol, String handle) { 129 return new Related(protocol + ":" + handle); 130 } 131 132 /** 133 * Creates a related property whose value is a telephone number. 134 * @param telUri the telephone number 135 * @return the property 136 */ 137 public static Related telephone(TelUri telUri) { 138 return new Related(telUri.toString()); 139 } 140 141 /** 142 * Gets the URI value. 143 * @return the URI value or null if no URI value is set 144 */ 145 public String getUri() { 146 return uri; 147 } 148 149 /** 150 * Sets the URI. 151 * @param uri the URI 152 */ 153 public void setUri(String uri) { 154 this.uri = uri; 155 text = null; 156 } 157 158 /** 159 * Gets the text value. 160 * @return the text value or null if no text value is set 161 */ 162 public String getText() { 163 return text; 164 } 165 166 /** 167 * Sets the value to free-form text instead of a URI. 168 * @param text the text 169 */ 170 public void setText(String text) { 171 this.text = text; 172 uri = null; 173 } 174 175 /** 176 * Gets the list that stores this property's relationship types (TYPE 177 * parameters). 178 * @return the relationship types (e.g. "child", "co-worker") (this list is 179 * mutable) 180 */ 181 public List<RelatedType> getTypes() { 182 return parameters.new TypeParameterList<RelatedType>() { 183 @Override 184 protected RelatedType _asObject(String value) { 185 return RelatedType.get(value); 186 } 187 }; 188 } 189 190 @Override 191 public List<Pid> getPids() { 192 return super.getPids(); 193 } 194 195 @Override 196 public Integer getPref() { 197 return super.getPref(); 198 } 199 200 @Override 201 public void setPref(Integer pref) { 202 super.setPref(pref); 203 } 204 205 //@Override 206 public String getAltId() { 207 return parameters.getAltId(); 208 } 209 210 //@Override 211 public void setAltId(String altId) { 212 parameters.setAltId(altId); 213 } 214 215 @Override 216 protected void _validate(List<ValidationWarning> warnings, VCardVersion version, VCard vcard) { 217 if (uri == null && text == null) { 218 warnings.add(new ValidationWarning(8)); 219 } 220 } 221 222 @Override 223 protected Map<String, Object> toStringValues() { 224 Map<String, Object> values = new LinkedHashMap<>(); 225 values.put("uri", uri); 226 values.put("text", text); 227 return values; 228 } 229 230 @Override 231 public Related copy() { 232 return new Related(this); 233 } 234 235 @Override 236 public int hashCode() { 237 final int prime = 31; 238 int result = super.hashCode(); 239 result = prime * result + ((text == null) ? 0 : text.hashCode()); 240 result = prime * result + ((uri == null) ? 0 : uri.hashCode()); 241 return result; 242 } 243 244 @Override 245 public boolean equals(Object obj) { 246 if (this == obj) return true; 247 if (!super.equals(obj)) return false; 248 Related other = (Related) obj; 249 if (text == null) { 250 if (other.text != null) return false; 251 } else if (!text.equals(other.text)) return false; 252 if (uri == null) { 253 if (other.uri != null) return false; 254 } else if (!uri.equals(other.uri)) return false; 255 return true; 256 } 257}