Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / libaddressinput / src / java / src / com / android / i18n / addressinput / AddressData.java
1 /*
2  * Copyright (C) 2010 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.android.i18n.addressinput;
18
19 import java.util.HashMap;
20 import java.util.Map;
21
22 /**
23  * A simple data structure for international postal addresses.
24  *
25  * Addresses may seem simple, but even within the US there are many quirks (hyphenated street
26  * addresses, etc.), and internationally addresses vary a great deal. The most sane and complete in
27  * many ways is the OASIS "extensible Address Language", xAL, which is a published and documented
28  * XML schema:
29  *
30  * http://www.oasis-open.org/committees/ciq/download.shtml
31  *
32  * We have not represented all the fields, but the intent is that if you need to add something, you
33  * should follow the OASIS standard.
34  *
35  * An example address:
36  * <p>postalCountry: US</p>
37  * <p>addressLine1: 1098 Alta Ave</p>
38  * <p>addressLine2:</p>
39  * <p>adminstrativeArea: CA</p>
40  * <p>locality: Mountain View</p>
41  * <p>dependentLocality:</p>
42  * <p>postalCode: 94043</p>
43  * <p>sortingCode:</p>
44  * <p>organization: Google</p>
45  * <p>recipient: Chen-Kang Yang</p>
46  * <p>language code: en</p>
47  *
48  * Note that sub-administrative area is NOT used in Address Widget. Sub-administrative Area is
49  * second-level administrative subdivision of this country. For examples: US county, IT province, UK
50  * county. This level of geo information is not required to fill out address form, therefore is
51  * neglected.
52  *
53  * All values stored in this class are trimmed. Also, if you try to set a field with an empty string
54  * or a string consists of only spaces, it will not be set.
55  */
56 public class AddressData {
57   // CLDR (Common Locale Data Repository) country code.
58   // For example, "US" for United States.
59   // (Note: Use "GB", not "UK", for Great Britain)
60   private final String postalCountry;
61
62   // street street, line 1
63   private final String addressLine1;
64
65   // street street, line 2
66   private final String addressLine2;
67
68   // Top-level administrative subdivision of this country.
69   // Examples: US state, IT region, UK constituent nation, JP prefecture.
70   private final String administrativeArea;
71
72   // Locality. A fuzzy term, but it generally refers to
73   // the city/town portion of an address.  In regions of the world where
74   // localities are not well defined or do not fit into this structure well
75   // (for example, Japan and China), leave locality empty and use
76   // addressLine1.
77   // Examples: US city, IT comune, UK post town.
78   private final String locality;
79
80   // Dependent locality or sublocality.  Used for UK dependent localities,
81   // or neighborhoods or boroughs in other locations.  If trying to
82   // represent a UK double-dependent locality, include both the
83   // double-dependent locality and the dependent locality in this field,
84   // e.g. "Whaley, Langwith".
85   private final String dependentLocality;
86
87   // Postal Code. values are frequently alphanumeric.
88   // Examples: "94043", "94043-1351", "SW1W", "SW1W 9TQ".
89   private final String postalCode;
90
91   // Sorting code - use is very country-specific.
92   // This corresponds to the SortingCode sub-element of the xAL
93   // PostalServiceElements element.
94   // Examples: FR CEDEX.
95   private final String sortingCode;
96
97   // The firm or organization. This goes at a finer granularity than
98   // address lines in the address. Omit if not needed.
99   private final String organization;
100
101   // The recipient. This goes at a finer granularity than address lines
102   // in the address. Not present in xAL. Omit if not needed.
103   private final String recipient;
104
105   // Language code of the address. Can be set to null. See its getter and setter
106   // for more information.
107   private final String languageCode;
108
109   /**
110    * Use {@link Builder} to create instances.
111    */
112   private AddressData(Builder builder) {
113     postalCountry = builder.values.get(AddressField.COUNTRY);
114     administrativeArea = builder.values.get(AddressField.ADMIN_AREA);
115     locality = builder.values.get(AddressField.LOCALITY);
116     dependentLocality = builder.values.get(AddressField.DEPENDENT_LOCALITY);
117     postalCode = builder.values.get(AddressField.POSTAL_CODE);
118     sortingCode = builder.values.get(AddressField.SORTING_CODE);
119     organization = builder.values.get(AddressField.ORGANIZATION);
120     recipient = builder.values.get(AddressField.RECIPIENT);
121     addressLine1 = builder.values.get(AddressField.ADDRESS_LINE_1);
122     addressLine2 = builder.values.get(AddressField.ADDRESS_LINE_2);
123     languageCode = builder.language;
124   }
125
126   /**
127    * Returns the postal country.
128    *
129    * <p>The returned value is not user-presentable. For example, {@code getPostalCountry()} may
130    * return {@code "GB"}, while addresses in Great Britain should be displayed using "UK".
131    */
132   public String getPostalCountry() {
133     return postalCountry;
134   }
135
136   public String getAddressLine1() {
137     return addressLine1;
138   }
139
140   public String getAddressLine2() {
141     return addressLine2;
142   }
143
144   /**
145    * Returns the top-level administrative subdivision of this country. Different postal countries
146    * use different names to refer to their administrative areas. For example, this is called
147    * "state" in the United States, "region" in Italy, "constituent nation" in Great Britain, or
148    * "prefecture" in Japan.
149    */
150   public String getAdministrativeArea() {
151     return administrativeArea;
152   }
153
154   /**
155    * Returns the locality. The usage of this field varies by region, but it generally refers to
156    * the "city" or "town" of the address. Some regions do not use this field; their address lines
157    * are sufficient to locate an address within a sub-administrative area. For example, this is
158    * called "city" in the United States, "comune" in Italy, or "post town" in Great Britain.
159    */
160   public String getLocality() {
161     return locality;
162   }
163
164   /**
165    * Returns the dependent locality.
166    *
167    * <p>This is used for Great Britain dependent localities, or neighborhoods or boroughs in other
168    * locations.
169    *
170    * <p>In cases such as Great Britain, this field may contain a double-dependent locality, such
171    * as "Whaley, Langwith".
172    */
173   public String getDependentLocality() {
174     return dependentLocality;
175   }
176
177   /**
178    * Returns the firm or organization.
179    */
180   public String getOrganization() {
181     return organization;
182   }
183
184   /**
185    * Returns the recipient. Examples: "Jesse Wilson" or "Jesse Wilson c/o Apurva Mathad".
186    */
187   public String getRecipient() {
188     return recipient;
189   }
190
191   /**
192    * Returns the country-specific postal code. Examples: "94043", "94043-1351", "SW1W",
193    * "SW1W 9TQ".
194    */
195   public String getPostalCode() {
196     return postalCode;
197   }
198
199   /**
200    * Returns the country-specific sorting code. For example, the
201    * <a href="http://en.wikipedia.org/wiki/List_of_postal_codes_in_France"> French CEDEX</a>
202    */
203   public String getSortingCode() {
204     return sortingCode;
205   }
206
207   public String getFieldValue(AddressField field) {
208     switch (field) {
209       case COUNTRY:
210         return postalCountry;
211       case ADMIN_AREA:
212         return administrativeArea;
213       case LOCALITY:
214         return locality;
215       case DEPENDENT_LOCALITY:
216         return dependentLocality;
217       case POSTAL_CODE:
218         return postalCode;
219       case SORTING_CODE:
220         return sortingCode;
221       case ADDRESS_LINE_1:
222         return addressLine1;
223       case ADDRESS_LINE_2:
224         return addressLine2;
225       case ORGANIZATION:
226         return organization;
227       case RECIPIENT:
228         return recipient;
229       default:
230         throw new IllegalArgumentException("unrecognized key: " + field);
231     }
232   }
233
234   /**
235    * Returns the language of the text of this address. Languages are used to guide how the address
236    * is <a href="http://en.wikipedia.org/wiki/Mailing_address_format_by_country"> formatted for
237    * display</a>. The same address may have different {@link AddressData} representations in
238    * different languages. For example, the French name of "New Mexico" is "Nouveau-Mexique".
239    */
240   public String getLanguageCode() {
241     return languageCode;
242   }
243
244   /**
245    * Builder for AddressData
246    */
247   public static class Builder {
248
249     private final Map<AddressField, String> values;
250
251     private String language = null;
252
253     public Builder() {
254       values = new HashMap<AddressField, String>();
255     }
256
257     /**
258      * A constructor that sets address field with input data. Street fields will be normalized
259      * in the process. I.e., after copy, there will not be any empty street line in front of
260      * non-empty ones. For example, if input data's street line 1 is null but street line 2
261      * has a value, this method will copy street line 2's value and set it to street line 1.
262      */
263     public Builder(AddressData addr) {
264       values = new HashMap<AddressField, String>();
265       set(addr);
266     }
267
268     public Builder setCountry(String value) {
269       return set(AddressField.COUNTRY, value);
270     }
271
272     public Builder setAdminArea(String value) {
273       return set(AddressField.ADMIN_AREA, value);
274     }
275
276     public Builder setLocality(String value) {
277       return set(AddressField.LOCALITY, value);
278     }
279
280     public Builder setDependentLocality(String value) {
281       return set(AddressField.DEPENDENT_LOCALITY, value);
282     }
283
284     public Builder setPostalCode(String value) {
285       return set(AddressField.POSTAL_CODE, value);
286     }
287
288     public Builder setSortingCode(String value) {
289       return set(AddressField.SORTING_CODE, value);
290     }
291
292     /**
293      * Sets the language code.
294      *
295      * @param languageCode the language to use, or {@code null} for no specified language.
296      */
297     public Builder setLanguageCode(String languageCode) {
298       this.language = languageCode;
299       return this;
300     }
301
302     /**
303      * Sets address lines 1 and 2 (if necessary) from a string that may contain multiple lines.
304      *
305      * <p> Example: Input "  \n   \n1600 Amphitheatre Ave\n\nRoom 122" will set the following
306      * values:<br/> line 1: 1600 Amphitheatre Ave<br/> line 2: Room 122<br/> </p>
307      *
308      * @param value a street string
309      */
310     public Builder setAddress(String value) {
311       setAddressLine1(value);
312       return this;
313     }
314
315     /**
316      * Sets address by copying from input address data. Street fields will be normalized in the
317      * process. I.e., after copy, there will not be any empty street lines in front of non-empty
318      * ones. For example, if input data's street line 1 is null but street line 2 has a value,
319      * this method will copy street line 2's value and set it to street line 1.
320      */
321     public Builder set(AddressData data) {
322       values.clear();
323       for (AddressField addressField : AddressField.values()) {
324         if (addressField == AddressField.STREET_ADDRESS) {
325             continue;  // Do nothing.
326         } else {
327           set(addressField, data.getFieldValue(addressField));
328         }
329       }
330       normalizeAddresses();
331       setLanguageCode(data.getLanguageCode());
332       return this;
333     }
334
335     public Builder setAddressLine1(String value) {
336       return set(AddressField.ADDRESS_LINE_1, value);
337     }
338
339     public Builder setAddressLine2(String value) {
340       return set(AddressField.ADDRESS_LINE_2, value);
341     }
342
343     public Builder setOrganization(String value) {
344       return set(AddressField.ORGANIZATION, value);
345     }
346
347     public Builder setRecipient(String value) {
348       return set(AddressField.RECIPIENT, value);
349     }
350
351     /**
352      * Sets an address field with the specified value. If the value is empty (a null string,
353      * empty string, or a string that contains only spaces), the original value associated with
354      * the field will be removed.
355      */
356     public Builder set(AddressField field, String value) {
357       if (value == null || value.length() == 0) {
358         values.remove(field);
359       } else {
360         values.put(field, value.trim());
361       }
362       normalizeAddresses();
363       return this;
364     }
365
366     public AddressData build() {
367       return new AddressData(this);
368     }
369
370     /**
371      * Parses content of address line fields.
372      * If address_line_1 is empty, address_line_2 will be used to populate address_line_1 if
373      * possible. If address_line_1 contains a new line, content after the new line will be
374      * saved in address_line_2.
375      */
376     private void normalizeAddresses() {
377       String address1 = values.get(AddressField.ADDRESS_LINE_1);
378       String address2 = values.get(AddressField.ADDRESS_LINE_2);
379       if (address1 == null || address1.trim().length() == 0) {
380         address1 = address2;
381         address2 = null;
382       }
383       if (address1 != null) {
384         String[] addressLines = address1.split("\n");
385         if (addressLines.length > 1) {
386           address1 = addressLines[0];
387           address2 = addressLines[1];
388         }
389       }
390       values.put(AddressField.ADDRESS_LINE_1, address1);
391       values.put(AddressField.ADDRESS_LINE_2, address2);
392     }
393   }
394 }