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; 012import ezvcard.parameter.Pid; 013import ezvcard.parameter.RelatedType; 014import ezvcard.util.TelUri; 015 016/* 017 Copyright (c) 2012-2026, Michael Angstadt 018 All rights reserved. 019 020 Redistribution and use in source and binary forms, with or without 021 modification, are permitted provided that the following conditions are met: 022 023 1. Redistributions of source code must retain the above copyright notice, this 024 list of conditions and the following disclaimer. 025 2. Redistributions in binary form must reproduce the above copyright notice, 026 this list of conditions and the following disclaimer in the documentation 027 and/or other materials provided with the distribution. 028 029 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 030 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 031 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 032 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 033 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 034 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 035 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 036 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 037 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 038 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 039 040 The views and conclusions contained in the software and documentation are those 041 of the authors and should not be interpreted as representing official policies, 042 either expressed or implied, of the FreeBSD Project. 043 */ 044 045/** 046 * <p> 047 * Defines someone that the person is related to. 048 * </p> 049 * 050 * <p> 051 * <b>Code sample</b> 052 * </p> 053 * 054 * <pre class="brush:java"> 055 * VCard vcard = new VCard(); 056 * 057 * //static factory methods 058 * Related related = Related.email("bob.smith@example.com"); 059 * related.getTypes().add(RelatedType.CO_WORKER); 060 * related.getTypes().add(RelatedType.FRIEND); 061 * vcard.addRelated(related); 062 * 063 * //free-form text 064 * related = new Related(); 065 * related.setText("Edna Smith"); 066 * related.getTypes().add(RelatedType.SPOUSE); 067 * vcard.addRelated(related); 068 * 069 * //reference another vCard by putting its UID property here 070 * related = new Related("urn:uuid:03a0e51f-d1aa-4385-8a53-e29025acd8af"); 071 * related.getTypes().add(RelatedType.SIBLING); 072 * vcard.addRelated(related); 073 * </pre> 074 * 075 * <p> 076 * <b>Property name:</b> {@code RELATED} 077 * </p> 078 * <p> 079 * <b>Supported versions:</b> {@code 4.0} 080 * </p> 081 * @author Michael Angstadt 082 * @see <a href="http://tools.ietf.org/html/rfc6350#page-42">RFC 6350 p.42</a> 083 */ 084@SupportedVersions(VCardVersion.V4_0) 085public class Related extends VCardProperty implements HasAltId { 086 private String uri; 087 private String text; 088 089 /** 090 * Creates a related property 091 */ 092 public Related() { 093 //empty 094 } 095 096 /** 097 * Creates a related property. 098 * @param uri the URI representing the person 099 */ 100 public Related(String uri) { 101 setUri(uri); 102 } 103 104 /** 105 * Copy constructor. 106 * @param original the property to make a copy of 107 */ 108 public Related(Related original) { 109 super(original); 110 uri = original.uri; 111 text = original.text; 112 } 113 114 /** 115 * Creates a related property whose value is an email address. 116 * @param email the email address 117 * @return the property 118 */ 119 public static Related email(String email) { 120 return new Related("mailto:" + email); 121 } 122 123 /** 124 * Creates a related property whose value is an instant messenger handle. 125 * @param protocol the instant messenger protocol (e.g. "aim") 126 * @param handle the instant messenger handle (e.g. "johndoe") 127 * @return the property 128 */ 129 public static Related im(String protocol, String handle) { 130 return new Related(protocol + ":" + handle); 131 } 132 133 /** 134 * Creates a related property whose value is a telephone number. 135 * @param telUri the telephone number 136 * @return the property 137 */ 138 public static Related telephone(TelUri telUri) { 139 return new Related(telUri.toString()); 140 } 141 142 /** 143 * Gets the URI value. 144 * @return the URI value or null if no URI value is set 145 */ 146 public String getUri() { 147 return uri; 148 } 149 150 /** 151 * Sets the URI. 152 * @param uri the URI 153 */ 154 public void setUri(String uri) { 155 this.uri = uri; 156 text = null; 157 } 158 159 /** 160 * Gets the text value. 161 * @return the text value or null if no text value is set 162 */ 163 public String getText() { 164 return text; 165 } 166 167 /** 168 * Sets the value to free-form text instead of a URI. 169 * @param text the text 170 */ 171 public void setText(String text) { 172 this.text = text; 173 uri = null; 174 } 175 176 /** 177 * Gets the list that stores this property's relationship types (TYPE 178 * parameters). 179 * @return the relationship types (e.g. "child", "co-worker") (this list is 180 * mutable) 181 */ 182 public List<RelatedType> getTypes() { 183 return parameters.new TypeParameterList<RelatedType>() { 184 @Override 185 protected RelatedType _asObject(String value) { 186 return RelatedType.get(value); 187 } 188 }; 189 } 190 191 @Override 192 public List<Pid> getPids() { 193 return super.getPids(); 194 } 195 196 @Override 197 public Integer getPref() { 198 return super.getPref(); 199 } 200 201 @Override 202 public void setPref(Integer pref) { 203 super.setPref(pref); 204 } 205 206 //@Override 207 public String getAltId() { 208 return parameters.getAltId(); 209 } 210 211 //@Override 212 public void setAltId(String altId) { 213 parameters.setAltId(altId); 214 } 215 216 @Override 217 protected void _validate(List<ValidationWarning> warnings, VCardVersion version, VCard vcard) { 218 if (uri == null && text == null) { 219 warnings.add(new ValidationWarning(8)); 220 } 221 } 222 223 @Override 224 protected Map<String, Object> toStringValues() { 225 Map<String, Object> values = new LinkedHashMap<>(); 226 values.put("uri", uri); 227 values.put("text", text); 228 return values; 229 } 230 231 @Override 232 public Related copy() { 233 return new Related(this); 234 } 235 236 @Override 237 public int hashCode() { 238 final int prime = 31; 239 int result = super.hashCode(); 240 result = prime * result + Objects.hash(text, uri); 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 if (getClass() != obj.getClass()) return false; 249 Related other = (Related) obj; 250 return Objects.equals(text, other.text) && Objects.equals(uri, other.uri); 251 } 252}