1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.jadira.cdt.phonenumber.impl;
17
18 import java.io.Serializable;
19
20 import org.jadira.bindings.core.annotation.typesafe.FromString;
21 import org.jadira.bindings.core.annotation.typesafe.ToString;
22 import org.jadira.cdt.country.CountryCode;
23 import org.jadira.cdt.country.ISOCountryCode;
24 import org.jadira.cdt.phonenumber.api.PhoneNumber;
25 import org.jadira.cdt.phonenumber.api.PhoneNumberParseException;
26
27 import com.google.i18n.phonenumbers.NumberParseException;
28 import com.google.i18n.phonenumbers.PhoneNumberUtil;
29 import com.google.i18n.phonenumbers.PhoneNumberUtil.PhoneNumberFormat;
30 import com.google.i18n.phonenumbers.Phonenumber;
31
32
33
34
35
36
37
38
39
40
41
42
43
44 public class E164PhoneNumberWithExtension implements PhoneNumber, Serializable {
45
46 private static final long serialVersionUID = -7665314825162464754L;
47
48 private static final PhoneNumberUtil PHONE_NUMBER_UTIL = PhoneNumberUtil.getInstance();
49
50 private static final String RFC3966_EXTN_PREFIX = ";ext=";
51
52 private Phonenumber.PhoneNumber number;
53
54 private static final String EX_PARSE_MSG_PREFIX = "Could not parse {";
55
56
57
58
59
60 public E164PhoneNumberWithExtension(Phonenumber.PhoneNumber prototype) {
61
62 StringBuilder e164Builder = new StringBuilder();
63 PHONE_NUMBER_UTIL.format(prototype, PhoneNumberFormat.E164, e164Builder);
64
65 try {
66 this.number = PHONE_NUMBER_UTIL.parse(e164Builder.toString(), "GB");
67 } catch (NumberParseException e) {
68 throw new PhoneNumberParseException(
69 EX_PARSE_MSG_PREFIX + prototype.getNationalNumber() +"}", e);
70 }
71
72 if (prototype.hasExtension()) {
73 this.number.setExtension(prototype.getExtension());
74 }
75 }
76
77
78
79
80
81
82 protected E164PhoneNumberWithExtension(String e164PhoneNumberWithExtension) {
83
84 if (!e164PhoneNumberWithExtension.startsWith("+")) {
85 throw new PhoneNumberParseException("Only international numbers can be interpreted without a country code");
86 }
87
88 final String e164PhoneNumber;
89 final String extension;
90 if (e164PhoneNumberWithExtension.contains(RFC3966_EXTN_PREFIX)) {
91 extension = e164PhoneNumberWithExtension.substring(e164PhoneNumberWithExtension.indexOf(RFC3966_EXTN_PREFIX) + RFC3966_EXTN_PREFIX.length());
92 e164PhoneNumber = e164PhoneNumberWithExtension.substring(0, e164PhoneNumberWithExtension.indexOf(RFC3966_EXTN_PREFIX));
93 } else {
94 extension = null;
95 e164PhoneNumber = e164PhoneNumberWithExtension;
96 }
97
98 try {
99 number = PHONE_NUMBER_UTIL.parse(e164PhoneNumber, "GB");
100 } catch (NumberParseException e) {
101 throw new PhoneNumberParseException(
102 EX_PARSE_MSG_PREFIX + e164PhoneNumber +"}", e);
103 }
104
105 if (extension != null) {
106 number.setExtension(extension);
107 }
108 }
109
110
111
112
113
114
115 protected E164PhoneNumberWithExtension(String e164PhoneNumber, String extension) {
116
117 if (!e164PhoneNumber.startsWith("+")) {
118 throw new PhoneNumberParseException("Only international numbers can be interpreted without a country code");
119 }
120
121 try {
122 number = PHONE_NUMBER_UTIL.parse(e164PhoneNumber, "GB");
123 } catch (NumberParseException e) {
124 throw new PhoneNumberParseException(
125 EX_PARSE_MSG_PREFIX + e164PhoneNumber +"}", e);
126 }
127
128 number.setExtension(extension);
129 }
130
131
132
133
134
135
136 protected E164PhoneNumberWithExtension(String phoneNumber, CountryCode defaultCountryCode) {
137
138 try {
139 number = PHONE_NUMBER_UTIL.parse(phoneNumber, defaultCountryCode.toString());
140 } catch (NumberParseException e) {
141 throw new PhoneNumberParseException(
142 EX_PARSE_MSG_PREFIX + phoneNumber + "} for country {" + defaultCountryCode +"}", e);
143 }
144 }
145
146
147
148
149
150
151
152 protected E164PhoneNumberWithExtension(String phoneNumber, String extension, CountryCode defaultCountryCode) {
153
154 try {
155 number = PHONE_NUMBER_UTIL.parse(phoneNumber, defaultCountryCode.toString());
156 } catch (NumberParseException e) {
157 throw new PhoneNumberParseException(
158 EX_PARSE_MSG_PREFIX + phoneNumber + "} for country {" + defaultCountryCode +"}", e);
159 }
160 if (extension != null) {
161 number.setExtension(extension);
162 }
163 }
164
165
166
167
168
169
170 public static E164PhoneNumberWithExtension ofE164PhoneNumberString(String e164PhoneNumber) {
171 return new E164PhoneNumberWithExtension(e164PhoneNumber, (String)null);
172 }
173
174
175
176
177
178
179
180 @FromString
181 public static E164PhoneNumberWithExtension ofE164PhoneNumberWithExtensionString(String e164PhoneNumber) {
182 return new E164PhoneNumberWithExtension(e164PhoneNumber);
183 }
184
185
186
187
188
189
190
191 public static E164PhoneNumberWithExtension ofE164PhoneNumberStringAndExtension(String e164PhoneNumber, String extension) {
192 return new E164PhoneNumberWithExtension(e164PhoneNumber, extension);
193 }
194
195
196
197
198
199
200
201 public static E164PhoneNumberWithExtension ofPhoneNumberString(String phoneNumber, CountryCode defaultCountryCode) {
202 return new E164PhoneNumberWithExtension(phoneNumber, defaultCountryCode);
203 }
204
205
206
207
208
209
210
211
212 public static E164PhoneNumberWithExtension ofPhoneNumberStringAndExtension(String phoneNumber, String extension, CountryCode defaultCountryCode) {
213 return new E164PhoneNumberWithExtension(phoneNumber, extension, defaultCountryCode);
214 }
215
216
217
218
219
220
221 public Phonenumber.PhoneNumber getUnderlyingPhoneNumber() {
222
223 Phonenumber.PhoneNumber copy;
224
225 StringBuilder e164Builder = new StringBuilder();
226 PHONE_NUMBER_UTIL.format(number, PhoneNumberFormat.E164, e164Builder);
227
228 try {
229 copy = PHONE_NUMBER_UTIL.parse(e164Builder.toString(), "GB");
230 } catch (NumberParseException e) {
231 throw new PhoneNumberParseException(
232 EX_PARSE_MSG_PREFIX + number.getNationalNumber() +"}", e);
233 }
234
235 if (number.hasExtension()) {
236 copy.setExtension(number.getExtension());
237 }
238 return copy;
239 }
240
241
242
243
244 public ISOCountryCode extractCountryCode() {
245 return ISOCountryCode.valueOf(PHONE_NUMBER_UTIL.getRegionCodeForNumber(number));
246 }
247
248
249
250
251 public String getCountryDiallingCode() {
252 return "+" + number.getCountryCode();
253 }
254
255
256
257
258 public String getNationalNumber() {
259 return "" + number.getNationalNumber();
260 }
261
262
263
264
265 public String getExtension() {
266 return number.hasExtension() ? number.getExtension() : null;
267 }
268
269
270
271
272 public String toE164NumberString() {
273 StringBuilder result = new StringBuilder();
274 PHONE_NUMBER_UTIL.format(number, PhoneNumberFormat.E164, result);
275
276 return result.toString();
277 }
278
279
280
281
282 @ToString
283 public String toE164NumberWithExtensionString() {
284
285 StringBuilder formattedString = new StringBuilder(toE164NumberString());
286
287 if(number.hasExtension()) {
288 formattedString.append(RFC3966_EXTN_PREFIX);
289 formattedString.append(number.getExtension());
290 }
291
292 return formattedString.toString();
293 }
294
295
296
297
298 public String extractAreaCode() {
299
300 final String nationalSignificantNumber = PHONE_NUMBER_UTIL.getNationalSignificantNumber(number);
301 final String areaCode;
302
303 int areaCodeLength = PHONE_NUMBER_UTIL.getLengthOfGeographicalAreaCode(number);
304 if (areaCodeLength > 0) {
305 areaCode = nationalSignificantNumber.substring(0, areaCodeLength);
306 } else {
307 areaCode = "";
308 }
309
310 return areaCode;
311 }
312
313
314
315
316 public String extractSubscriberNumber() {
317
318 final String nationalSignificantNumber = PHONE_NUMBER_UTIL.getNationalSignificantNumber(number);
319 final String subscriberNumber;
320
321 int areaCodeLength = PHONE_NUMBER_UTIL.getLengthOfGeographicalAreaCode(number);
322 if (areaCodeLength > 0) {
323 subscriberNumber = nationalSignificantNumber.substring(areaCodeLength);
324 } else {
325 subscriberNumber = nationalSignificantNumber;
326 }
327
328 return subscriberNumber;
329 }
330
331
332
333
334 @Override
335 public String toString() {
336 return toE164NumberWithExtensionString();
337 }
338
339
340
341
342 @Override
343 public boolean equals(Object obj) {
344 if (obj == null) {
345 return false;
346 }
347 if (!this.getClass().equals(obj.getClass())) {
348 return false;
349 }
350
351 final E164PhoneNumberWithExtension obj2 = (E164PhoneNumberWithExtension) obj;
352 if (this.toString().equals(obj2.toString())) {
353 return true;
354 }
355
356 return false;
357 }
358
359
360
361
362 @Override
363 public int hashCode() {
364 return toString().hashCode();
365 }
366 }