001package ezvcard.property;
002
003import java.util.LinkedHashMap;
004import java.util.List;
005import java.util.Map;
006
007import ezvcard.VCard;
008import ezvcard.VCardVersion;
009import ezvcard.ValidationWarning;
010import ezvcard.parameter.Pid;
011import ezvcard.parameter.TelephoneType;
012import ezvcard.util.TelUri;
013
014/*
015 Copyright (c) 2012-2023, Michael Angstadt
016 All rights reserved.
017
018 Redistribution and use in source and binary forms, with or without
019 modification, are permitted provided that the following conditions are met: 
020
021 1. Redistributions of source code must retain the above copyright notice, this
022 list of conditions and the following disclaimer. 
023 2. Redistributions in binary form must reproduce the above copyright notice,
024 this list of conditions and the following disclaimer in the documentation
025 and/or other materials provided with the distribution. 
026
027 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
028 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
029 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
030 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
031 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
032 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
033 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
034 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
035 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
036 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
037
038 The views and conclusions contained in the software and documentation are those
039 of the authors and should not be interpreted as representing official policies, 
040 either expressed or implied, of the FreeBSD Project.
041 */
042
043/**
044 * <p>
045 * Defines a telephone number.
046 * </p>
047 * 
048 * <p>
049 * <b>Code sample</b>
050 * </p>
051 * 
052 * <pre class="brush:java">
053 * VCard vcard = new VCard();
054 * 
055 * //text
056 * Telephone tel = new Telephone("(123) 555-6789");
057 * tel.getTypes().add(TelephoneType.HOME);
058 * tel.setPref(2); //the second-most preferred
059 * vcard.addTelephoneNumber(tel);
060 * 
061 * //URI (vCard version 4.0 only)
062 * TelUri uri = new TelUri.Builder("+1-800-555-9876").extension("111").build();
063 * tel = new Telephone(uri);
064 * tel.getTypes().add(TelephoneType.WORK);
065 * tel.setPref(1); //the most preferred
066 * vcard.addTelephoneNumber(tel);
067 * </pre>
068 * 
069 * <p>
070 * <b>Property name:</b> {@code TEL}
071 * </p>
072 * <p>
073 * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
074 * </p>
075 * @author Michael Angstadt
076 * @see <a href="http://tools.ietf.org/html/rfc6350#page-34">RFC 6350 p.34</a>
077 * @see <a href="http://tools.ietf.org/html/rfc2426#page-14">RFC 2426 p.14</a>
078 * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.13</a>
079 */
080public class Telephone extends VCardProperty implements HasAltId {
081        private String text;
082        private TelUri uri;
083
084        /**
085         * Creates a telephone property.
086         * @param text the telephone number (e.g. "(123) 555-6789")
087         */
088        public Telephone(String text) {
089                setText(text);
090        }
091
092        /**
093         * Creates a telephone property.
094         * @param uri a "tel" URI representing the telephone number (vCard 4.0 only)
095         */
096        public Telephone(TelUri uri) {
097                setUri(uri);
098        }
099
100        /**
101         * Copy constructor.
102         * @param original the property to make a copy of
103         */
104        public Telephone(Telephone original) {
105                super(original);
106                text = original.text;
107                uri = original.uri;
108        }
109
110        /**
111         * Gets the telephone number as a text value.
112         * @return the telephone number or null if the text value is not set
113         */
114        public String getText() {
115                return text;
116        }
117
118        /**
119         * Sets the telephone number as a text value.
120         * @param text the telephone number
121         */
122        public void setText(String text) {
123                this.text = text;
124                uri = null;
125        }
126
127        /**
128         * Gets a "tel" URI representing the phone number.
129         * <p>
130         * <b>Supported versions:</b> {@code 4.0}
131         * </p>
132         * @return the "tel" URI or null if it is not set
133         */
134        public TelUri getUri() {
135                return uri;
136        }
137
138        /**
139         * Sets a "tel" URI representing the phone number.
140         * <p>
141         * <b>Supported versions:</b> {@code 4.0}
142         * </p>
143         * @param uri the "tel" URI
144         */
145        public void setUri(TelUri uri) {
146                text = null;
147                this.uri = uri;
148        }
149
150        /**
151         * Gets the list that stores this property's telephone types (TYPE
152         * parameters).
153         * @return the telephone types (e.g. "HOME", "WORK") (this list is mutable)
154         */
155        public List<TelephoneType> getTypes() {
156                return parameters.new TypeParameterList<TelephoneType>() {
157                        @Override
158                        protected TelephoneType _asObject(String value) {
159                                return TelephoneType.get(value);
160                        }
161                };
162        }
163
164        @Override
165        public List<Pid> getPids() {
166                return super.getPids();
167        }
168
169        @Override
170        public Integer getPref() {
171                return super.getPref();
172        }
173
174        @Override
175        public void setPref(Integer pref) {
176                super.setPref(pref);
177        }
178
179        //@Override
180        public String getAltId() {
181                return parameters.getAltId();
182        }
183
184        //@Override
185        public void setAltId(String altId) {
186                parameters.setAltId(altId);
187        }
188
189        @Override
190        protected void _validate(List<ValidationWarning> warnings, VCardVersion version, VCard vcard) {
191                if (uri == null && text == null) {
192                        warnings.add(new ValidationWarning(8));
193                }
194
195                if (uri != null && (version == VCardVersion.V2_1 || version == VCardVersion.V3_0)) {
196                        warnings.add(new ValidationWarning(19));
197                }
198
199                for (TelephoneType type : getTypes()) {
200                        if (type == TelephoneType.PREF) {
201                                //ignore because it is converted to a PREF parameter for 4.0 vCards
202                                continue;
203                        }
204
205                        if (!type.isSupportedBy(version)) {
206                                warnings.add(new ValidationWarning(9, type.getValue()));
207                        }
208                }
209        }
210
211        @Override
212        protected Map<String, Object> toStringValues() {
213                Map<String, Object> values = new LinkedHashMap<>();
214                values.put("uri", uri);
215                values.put("text", text);
216                return values;
217        }
218
219        @Override
220        public Telephone copy() {
221                return new Telephone(this);
222        }
223
224        @Override
225        public int hashCode() {
226                final int prime = 31;
227                int result = super.hashCode();
228                result = prime * result + ((text == null) ? 0 : text.hashCode());
229                result = prime * result + ((uri == null) ? 0 : uri.hashCode());
230                return result;
231        }
232
233        @Override
234        public boolean equals(Object obj) {
235                if (this == obj) return true;
236                if (!super.equals(obj)) return false;
237                Telephone other = (Telephone) obj;
238                if (text == null) {
239                        if (other.text != null) return false;
240                } else if (!text.equals(other.text)) return false;
241                if (uri == null) {
242                        if (other.uri != null) return false;
243                } else if (!uri.equals(other.uri)) return false;
244                return true;
245        }
246}