2 * Copyright (C) 2010 Google Inc.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.i18n.addressinput;
19 import java.util.EnumMap;
20 import java.util.EnumSet;
21 import java.util.HashMap;
22 import java.util.HashSet;
26 * Configuration Options that can be used by Address Display components for things like show/hide
27 * fields or make them readonly. By default, all the fields are visible and editable.
29 * <p>Also, provides the ability to add additional required fields, for e.g. {@link
30 * AddressField#RECIPIENT}.
32 public class FormOptions {
34 private final String baseId;
36 private final EnumSet<AddressField> hiddenFields;
38 private final EnumSet<AddressField> readonlyFields;
40 private final EnumSet<AddressField> requiredFields;
42 private final EnumMap<AddressField, String> customLabels =
43 new EnumMap<AddressField, String>(AddressField.class);
45 private final Map<String, AddressField[]> overrideFieldOrder =
46 new HashMap<String, AddressField[]>();
48 private final EnumMap<AddressField, Integer> maxLengths =
49 new EnumMap<AddressField, Integer>(AddressField.class);
51 private final String serverUrl;
53 private FormOptions(Builder builder) {
54 // copy values from builder
55 baseId = builder.baseId;
56 hiddenFields = EnumSet.copyOf(builder.hiddenFields);
57 readonlyFields = EnumSet.copyOf(builder.readonlyFields);
58 requiredFields = EnumSet.copyOf(builder.requiredFields);
59 customLabels.putAll(builder.customLabels);
60 overrideFieldOrder.putAll(builder.overrideFieldOrder);
61 maxLengths.putAll(builder.maxLengths);
62 serverUrl = builder.serverUrl;
66 * Gets base ID of the address form. Default is "addressform".
72 boolean isHidden(AddressField field) {
73 return hiddenFields.contains(field);
76 boolean isReadonly(AddressField field) {
77 return readonlyFields.contains(field);
80 boolean isRequired(AddressField field) {
81 return requiredFields.contains(field);
84 EnumSet<AddressField> getRequiredFields() {
85 return requiredFields;
89 * Gets the customized label for the {@code field}, or returns null if none.
91 String getCustomLabel(AddressField field) {
92 return customLabels.get(field);
96 * Gets the URL of the Address Data Server.
103 * Gets the overridden field orders with their corresponding region code. Returns null if field
104 * orders for {@code regionCode} is not specified.
106 AddressField[] getCustomFieldOrder(String regionCode) {
107 if (regionCode == null) {
108 throw new RuntimeException("regionCode cannot be null.");
110 return overrideFieldOrder.get(regionCode);
114 * Gets the customized max length for the {@code field}, or null if none.
116 Integer getCustomMaxLength(AddressField field) {
117 return maxLengths.get(field);
121 * Class to build the form, specifying the attributes for each field.
123 public static class Builder {
125 private String baseId = "addressform";
127 private final EnumSet<AddressField> requiredFields =
128 EnumSet.noneOf(AddressField.class);
130 private final EnumSet<AddressField> hiddenFields =
131 EnumSet.noneOf(AddressField.class);
133 private final EnumSet<AddressField> readonlyFields =
134 EnumSet.noneOf(AddressField.class);
136 private final EnumMap<AddressField, String> customLabels =
137 new EnumMap<AddressField, String>(AddressField.class);
139 private final Map<String, AddressField[]> overrideFieldOrder =
140 new HashMap<String, AddressField[]>();
142 private final EnumMap<AddressField, Integer> maxLengths =
143 new EnumMap<AddressField, Integer>(AddressField.class);
146 * Uses the default server URL from CacheData.
148 private String serverUrl = new CacheData().getUrl();
151 * Sets the base ID of the address form.
153 public Builder baseId(String baseId) {
154 if (baseId == null) {
155 throw new RuntimeException("baseId cannot be null.");
157 this.baseId = baseId;
161 public Builder hide(AddressField field) {
163 throw new RuntimeException("AddressField field cannot be null.");
165 hiddenFields.add(field);
170 * Make a field read-only.
172 public Builder readonly(AddressField field) {
174 throw new RuntimeException("AddressField field cannot be null.");
176 readonlyFields.add(field);
181 * Make a field required.
183 public Builder required(AddressField field) {
185 throw new RuntimeException("AddressField field cannot be null.");
187 requiredFields.add(field);
192 * Customizes label for an {@code AddressField}.
194 public Builder customizeLabel(AddressField field, String label) {
196 throw new RuntimeException("AddressField field cannot be null.");
199 throw new RuntimeException("Label cannot be null.");
201 customLabels.put(field, label);
206 * Sets the field order for a region code. The order you set here will override the
207 * predefined one. For example, you can set field order for US to be first {@code
208 * AddressField#ORGANIZATION} then {@code AddressField#RECIPIENT}. Repeated address fields
209 * in {@code fields} are not allowed. Size of {@code fields} has to be larger than one.
210 * Input {@code fields} can be partial or even contain field not needed in the specified
211 * {@code regionCode}. For example, German addresses contain the following fields
213 {@link AddressField#RECIPIENT}, {@link AddressField#ORGANIZATION}, {@link
214 * AddressField#STREET_ADDRESS}, {@link AddressField#POSTAL_CODE}, {@link
215 * AddressField#LOCALITY}. <br/>
217 * <p>With the following call: <br/>
219 * customizeFieldOrder("DE", AddressField.ORGANIZATION, AddressField.RECIPIENT,
220 * AddressField.ADMIN_AREA);
222 * <p>Field order for Germany will become: <br/> {@link AddressField#ORGANIZATION}, {@link
223 * AddressField#RECIPIENT}, {@link AddressField#STREET_ADDRESS}, {@link
224 * AddressField#POSTAL_CODE}, {@link AddressField#LOCALITY}. </p>
226 * <p>Notice that:<br/> <ol> <li>{@link AddressField#ORGANIZATION} comes before {@link
227 * AddressField#RECIPIENT} after reordering.</li>
228 * <li>Fields not specified stays the same.</li>
229 * <li>{@link AddressField#ADMIN_AREA} is specified but since it is not in German address
230 * format, it is simpled neglected.</li> </ol>
232 * @param fields the overridden field order.
234 public Builder customizeFieldOrder(String regionCode, AddressField... fields) {
235 if (regionCode == null) {
236 throw new RuntimeException("regionCode cannot be null.");
238 if (fields == null) {
239 throw new RuntimeException("Fields cannot be null.");
241 if (fields.length <= 1) {
242 throw new RuntimeException("There must be more than one field.");
244 HashSet<AddressField> checkList = new HashSet<AddressField>();
245 AddressField[] f = new AddressField[fields.length];
247 for (AddressField field : fields) {
248 // Can't contain repeated address fields.
249 if (checkList.contains(field)) {
250 throw new RuntimeException("Address fields cannot be repeated.");
252 checkList.add(field);
256 overrideFieldOrder.put(regionCode, f);
261 * Sets the URL of address data server. {@code url} cannot be null. This url will override
262 * the default address server url.
264 public Builder setUrl(String url) {
266 throw new RuntimeException("Can't set address server URL to null.");
273 * Customizes max length for a {@code AddressField}.
275 public Builder customizeMaxLength(AddressField field, int maxLength) {
277 throw new RuntimeException("AddressField field cannot be null.");
279 maxLengths.put(field, maxLength);
283 public FormOptions build() {
284 return new FormOptions(this);