/* * Copyright (C) 2010 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.i18n.addressinput; import java.util.EnumMap; import java.util.EnumSet; import java.util.HashMap; import java.util.HashSet; import java.util.Map; /** * Configuration Options that can be used by Address Display components for things like show/hide * fields or make them readonly. By default, all the fields are visible and editable. * *

Also, provides the ability to add additional required fields, for e.g. {@link * AddressField#RECIPIENT}. */ public class FormOptions { private final String baseId; private final EnumSet hiddenFields; private final EnumSet readonlyFields; private final EnumSet requiredFields; private final EnumMap customLabels = new EnumMap(AddressField.class); private final Map overrideFieldOrder = new HashMap(); private final EnumMap maxLengths = new EnumMap(AddressField.class); private final String serverUrl; private FormOptions(Builder builder) { // copy values from builder baseId = builder.baseId; hiddenFields = EnumSet.copyOf(builder.hiddenFields); readonlyFields = EnumSet.copyOf(builder.readonlyFields); requiredFields = EnumSet.copyOf(builder.requiredFields); customLabels.putAll(builder.customLabels); overrideFieldOrder.putAll(builder.overrideFieldOrder); maxLengths.putAll(builder.maxLengths); serverUrl = builder.serverUrl; } /** * Gets base ID of the address form. Default is "addressform". */ String getBaseId() { return baseId; } boolean isHidden(AddressField field) { return hiddenFields.contains(field); } boolean isReadonly(AddressField field) { return readonlyFields.contains(field); } boolean isRequired(AddressField field) { return requiredFields.contains(field); } EnumSet getRequiredFields() { return requiredFields; } /** * Gets the customized label for the {@code field}, or returns null if none. */ String getCustomLabel(AddressField field) { return customLabels.get(field); } /** * Gets the URL of the Address Data Server. */ String getUrl() { return serverUrl; } /** * Gets the overridden field orders with their corresponding region code. Returns null if field * orders for {@code regionCode} is not specified. */ AddressField[] getCustomFieldOrder(String regionCode) { if (regionCode == null) { throw new RuntimeException("regionCode cannot be null."); } return overrideFieldOrder.get(regionCode); } /** * Gets the customized max length for the {@code field}, or null if none. */ Integer getCustomMaxLength(AddressField field) { return maxLengths.get(field); } /** * Class to build the form, specifying the attributes for each field. */ public static class Builder { private String baseId = "addressform"; private final EnumSet requiredFields = EnumSet.noneOf(AddressField.class); private final EnumSet hiddenFields = EnumSet.noneOf(AddressField.class); private final EnumSet readonlyFields = EnumSet.noneOf(AddressField.class); private final EnumMap customLabels = new EnumMap(AddressField.class); private final Map overrideFieldOrder = new HashMap(); private final EnumMap maxLengths = new EnumMap(AddressField.class); /** * Uses the default server URL from CacheData. */ private String serverUrl = new CacheData().getUrl(); /** * Sets the base ID of the address form. */ public Builder baseId(String baseId) { if (baseId == null) { throw new RuntimeException("baseId cannot be null."); } this.baseId = baseId; return this; } public Builder hide(AddressField field) { if (field == null) { throw new RuntimeException("AddressField field cannot be null."); } hiddenFields.add(field); return this; } /** * Make a field read-only. */ public Builder readonly(AddressField field) { if (field == null) { throw new RuntimeException("AddressField field cannot be null."); } readonlyFields.add(field); return this; } /** * Make a field required. */ public Builder required(AddressField field) { if (field == null) { throw new RuntimeException("AddressField field cannot be null."); } requiredFields.add(field); return this; } /** * Customizes label for an {@code AddressField}. */ public Builder customizeLabel(AddressField field, String label) { if (field == null) { throw new RuntimeException("AddressField field cannot be null."); } if (label == null) { throw new RuntimeException("Label cannot be null."); } customLabels.put(field, label); return this; } /** * Sets the field order for a region code. The order you set here will override the * predefined one. For example, you can set field order for US to be first {@code * AddressField#ORGANIZATION} then {@code AddressField#RECIPIENT}. Repeated address fields * in {@code fields} are not allowed. Size of {@code fields} has to be larger than one. * Input {@code fields} can be partial or even contain field not needed in the specified * {@code regionCode}. For example, German addresses contain the following fields * (in order):
{@link AddressField#RECIPIENT}, {@link AddressField#ORGANIZATION}, {@link * AddressField#STREET_ADDRESS}, {@link AddressField#POSTAL_CODE}, {@link * AddressField#LOCALITY}.
* *

With the following call:
* * customizeFieldOrder("DE", AddressField.ORGANIZATION, AddressField.RECIPIENT, * AddressField.ADMIN_AREA); * *

Field order for Germany will become:
{@link AddressField#ORGANIZATION}, {@link * AddressField#RECIPIENT}, {@link AddressField#STREET_ADDRESS}, {@link * AddressField#POSTAL_CODE}, {@link AddressField#LOCALITY}.

* *

Notice that:

  1. {@link AddressField#ORGANIZATION} comes before {@link * AddressField#RECIPIENT} after reordering.
  2. *
  3. Fields not specified stays the same.
  4. *
  5. {@link AddressField#ADMIN_AREA} is specified but since it is not in German address * format, it is simpled neglected.
* * @param fields the overridden field order. */ public Builder customizeFieldOrder(String regionCode, AddressField... fields) { if (regionCode == null) { throw new RuntimeException("regionCode cannot be null."); } if (fields == null) { throw new RuntimeException("Fields cannot be null."); } if (fields.length <= 1) { throw new RuntimeException("There must be more than one field."); } HashSet checkList = new HashSet(); AddressField[] f = new AddressField[fields.length]; int i = 0; for (AddressField field : fields) { // Can't contain repeated address fields. if (checkList.contains(field)) { throw new RuntimeException("Address fields cannot be repeated."); } checkList.add(field); f[i] = field; i++; } overrideFieldOrder.put(regionCode, f); return this; } /** * Sets the URL of address data server. {@code url} cannot be null. This url will override * the default address server url. */ public Builder setUrl(String url) { if (url == null) { throw new RuntimeException("Can't set address server URL to null."); } serverUrl = url; return this; } /** * Customizes max length for a {@code AddressField}. */ public Builder customizeMaxLength(AddressField field, int maxLength) { if (field == null) { throw new RuntimeException("AddressField field cannot be null."); } maxLengths.put(field, maxLength); return this; } public FormOptions build() { return new FormOptions(this); } } }