001package ezvcard.property; 002 003import java.util.LinkedHashMap; 004import java.util.List; 005import java.util.Map; 006import java.util.Objects; 007 008import ezvcard.VCard; 009import ezvcard.VCardVersion; 010import ezvcard.ValidationWarning; 011import ezvcard.parameter.Pid; 012import ezvcard.parameter.TelephoneType; 013import ezvcard.util.TelUri; 014 015/* 016 Copyright (c) 2012-2026, 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 a telephone number. 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 * //text 057 * Telephone tel = new Telephone("(123) 555-6789"); 058 * tel.getTypes().add(TelephoneType.HOME); 059 * tel.setPref(2); //the second-most preferred 060 * vcard.addTelephoneNumber(tel); 061 * 062 * //URI (vCard version 4.0 only) 063 * TelUri uri = new TelUri.Builder("+1-800-555-9876").extension("111").build(); 064 * tel = new Telephone(uri); 065 * tel.getTypes().add(TelephoneType.WORK); 066 * tel.setPref(1); //the most preferred 067 * vcard.addTelephoneNumber(tel); 068 * </pre> 069 * 070 * <p> 071 * <b>Property name:</b> {@code TEL} 072 * </p> 073 * <p> 074 * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0} 075 * </p> 076 * @author Michael Angstadt 077 * @see <a href="http://tools.ietf.org/html/rfc6350#page-34">RFC 6350 p.34</a> 078 * @see <a href="http://tools.ietf.org/html/rfc2426#page-14">RFC 2426 p.14</a> 079 * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.13</a> 080 */ 081public class Telephone extends VCardProperty implements HasAltId { 082 private String text; 083 private TelUri uri; 084 085 /** 086 * Creates a telephone property. 087 * @param text the telephone number (e.g. "(123) 555-6789") 088 */ 089 public Telephone(String text) { 090 setText(text); 091 } 092 093 /** 094 * Creates a telephone property. 095 * @param uri a "tel" URI representing the telephone number (vCard 4.0 only) 096 */ 097 public Telephone(TelUri uri) { 098 setUri(uri); 099 } 100 101 /** 102 * Copy constructor. 103 * @param original the property to make a copy of 104 */ 105 public Telephone(Telephone original) { 106 super(original); 107 text = original.text; 108 uri = original.uri; 109 } 110 111 /** 112 * Gets the telephone number as a text value. 113 * @return the telephone number or null if the text value is not set 114 */ 115 public String getText() { 116 return text; 117 } 118 119 /** 120 * Sets the telephone number as a text value. 121 * @param text the telephone number 122 */ 123 public void setText(String text) { 124 this.text = text; 125 uri = null; 126 } 127 128 /** 129 * Gets a "tel" URI representing the phone number. 130 * <p> 131 * <b>Supported versions:</b> {@code 4.0} 132 * </p> 133 * @return the "tel" URI or null if it is not set 134 */ 135 public TelUri getUri() { 136 return uri; 137 } 138 139 /** 140 * Sets a "tel" URI representing the phone number. 141 * <p> 142 * <b>Supported versions:</b> {@code 4.0} 143 * </p> 144 * @param uri the "tel" URI 145 */ 146 public void setUri(TelUri uri) { 147 text = null; 148 this.uri = uri; 149 } 150 151 /** 152 * Gets the list that stores this property's telephone types (TYPE 153 * parameters). 154 * @return the telephone types (e.g. "HOME", "WORK") (this list is mutable) 155 */ 156 public List<TelephoneType> getTypes() { 157 return parameters.new TypeParameterList<TelephoneType>() { 158 @Override 159 protected TelephoneType _asObject(String value) { 160 return TelephoneType.get(value); 161 } 162 }; 163 } 164 165 @Override 166 public List<Pid> getPids() { 167 return super.getPids(); 168 } 169 170 @Override 171 public Integer getPref() { 172 return super.getPref(); 173 } 174 175 @Override 176 public void setPref(Integer pref) { 177 super.setPref(pref); 178 } 179 180 //@Override 181 public String getAltId() { 182 return parameters.getAltId(); 183 } 184 185 //@Override 186 public void setAltId(String altId) { 187 parameters.setAltId(altId); 188 } 189 190 @Override 191 protected void _validate(List<ValidationWarning> warnings, VCardVersion version, VCard vcard) { 192 if (uri == null && text == null) { 193 warnings.add(new ValidationWarning(8)); 194 } 195 196 if (uri != null && (version == VCardVersion.V2_1 || version == VCardVersion.V3_0)) { 197 warnings.add(new ValidationWarning(19)); 198 } 199 200 //@formatter:off 201 getTypes().stream() 202 .filter(type -> type != TelephoneType.PREF) //ignore TYPE=PREF because it is converted to a PREF parameter for 4.0 vCards 203 .filter(type -> !type.isSupportedBy(version)) 204 .map(TelephoneType::getValue) 205 .map(value -> new ValidationWarning(9, value)) 206 .forEach(warnings::add); 207 //@formatter:on 208 } 209 210 @Override 211 protected Map<String, Object> toStringValues() { 212 Map<String, Object> values = new LinkedHashMap<>(); 213 values.put("uri", uri); 214 values.put("text", text); 215 return values; 216 } 217 218 @Override 219 public Telephone copy() { 220 return new Telephone(this); 221 } 222 223 @Override 224 public int hashCode() { 225 final int prime = 31; 226 int result = super.hashCode(); 227 result = prime * result + Objects.hash(text, uri); 228 return result; 229 } 230 231 @Override 232 public boolean equals(Object obj) { 233 if (this == obj) return true; 234 if (!super.equals(obj)) return false; 235 if (getClass() != obj.getClass()) return false; 236 Telephone other = (Telephone) obj; 237 return Objects.equals(text, other.text) && Objects.equals(uri, other.uri); 238 } 239}