10d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.com/*
20d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.com * Copyright (C) 2010 Google Inc.
30d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.com *
40d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.com * Licensed under the Apache License, Version 2.0 (the "License");
50d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.com * you may not use this file except in compliance with the License.
60d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.com * You may obtain a copy of the License at
70d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.com *
80d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.com * http://www.apache.org/licenses/LICENSE-2.0
90d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.com *
100d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.com * Unless required by applicable law or agreed to in writing, software
110d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.com * distributed under the License is distributed on an "AS IS" BASIS,
120d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.com * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.com * See the License for the specific language governing permissions and
140d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.com * limitations under the License.
150d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.com */
160d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.com
170d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.compackage com.android.i18n.addressinput;
180d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.com
190d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.comimport static com.android.i18n.addressinput.AddressField.ADMIN_AREA;
200d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.comimport static com.android.i18n.addressinput.AddressField.COUNTRY;
210d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.comimport static com.android.i18n.addressinput.AddressField.DEPENDENT_LOCALITY;
220d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.comimport static com.android.i18n.addressinput.AddressField.LOCALITY;
230d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.comimport static com.android.i18n.addressinput.AddressField.ORGANIZATION;
240d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.comimport static com.android.i18n.addressinput.AddressField.POSTAL_CODE;
250d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.comimport static com.android.i18n.addressinput.AddressField.RECIPIENT;
260d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.comimport static com.android.i18n.addressinput.AddressField.SORTING_CODE;
270d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.comimport static com.android.i18n.addressinput.AddressField.STREET_ADDRESS;
280d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.com
290d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.comimport com.android.i18n.addressinput.LookupKey.ScriptType;
300d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.com
310d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.comimport java.util.Collections;
320d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.comimport java.util.Iterator;
330d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.comimport java.util.List;
340d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.comimport java.util.Map;
350d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.com
360d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.com/**
372c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com * Performs various consistency checks on an AddressData. This uses a {@link FieldVerifier} to check
382c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com * each field in the address.
390d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.com */
400d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.compublic class StandardAddressVerifier {
412c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com
4237ea1c8bb9bf0ee18a9ce7412ace03885098e348lararennie@google.com    protected final FieldVerifier mRootVerifier;
432c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com
4437ea1c8bb9bf0ee18a9ce7412ace03885098e348lararennie@google.com    protected final VerifierRefiner mRefiner;
452c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com
4637ea1c8bb9bf0ee18a9ce7412ace03885098e348lararennie@google.com    protected final Map<AddressField, List<AddressProblemType>> mProblemMap;
472c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com
482c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com    /**
492c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     * Uses the rootVerifier and {@link #DEFAULT_REFINER} to perform the standard checks on the
502c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     * address fields, as defined in {@link StandardChecks}.
512c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     */
522c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com    public StandardAddressVerifier(FieldVerifier rootVerifier) {
532c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        this(rootVerifier, DEFAULT_REFINER, StandardChecks.PROBLEM_MAP);
540d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.com    }
550d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.com
562c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com    /**
572c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     * Uses the rootVerifier and the refiner to perform the standard checks on the address fields,
582c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     * as defined in {@link StandardChecks}.
592c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     */
602c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com    public StandardAddressVerifier(FieldVerifier rootVerifier, VerifierRefiner refiner) {
612c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        this(rootVerifier, refiner, StandardChecks.PROBLEM_MAP);
629be65349790706e3e5d5914587ce8c8e0ac21fbfjeanine@google.com    }
630d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.com
642c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com    /**
652c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     * Uses the rootVerifier and {@link #DEFAULT_REFINER} to perform the given checks on the address
662c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     * fields. A reference to problemMap is maintained. It is not modified by this class, and should
672c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     * not be modified subsequent to this call.
682c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     */
692c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com    public StandardAddressVerifier(FieldVerifier rootVerifier,
702c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com            Map<AddressField, List<AddressProblemType>> problemMap) {
712c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        this(rootVerifier, DEFAULT_REFINER, problemMap);
720d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.com    }
732c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com
742c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com    /**
752c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     * Uses the rootVerifier and the refiner to perform the given checks on the address fields. A
762c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     * reference to problemMap is maintained. It is not modified by this class, and should not be
772c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     * modified subsequent to this call.
782c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     */
792c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com    public StandardAddressVerifier(FieldVerifier rootVerifier, VerifierRefiner refiner,
802c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com            Map<AddressField, List<AddressProblemType>> problemMap) {
81ff01be390a0c4cbc5eb51ea8e2aceabfd1cbe2a3lararennie@google.com        mRootVerifier = rootVerifier;
82ff01be390a0c4cbc5eb51ea8e2aceabfd1cbe2a3lararennie@google.com        mRefiner = refiner;
83ff01be390a0c4cbc5eb51ea8e2aceabfd1cbe2a3lararennie@google.com        mProblemMap = StandardChecks.PROBLEM_MAP;
840d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.com    }
852c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com
862c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com    public void verify(AddressData address, AddressProblems problems) {
874b8b52272c4c5aaac932c0ee9d2d64e3db1fad2droubert@google.com        NotifyingListener listener = new NotifyingListener(this);
884b8b52272c4c5aaac932c0ee9d2d64e3db1fad2droubert@google.com        verifyAsync(address, problems, listener);
894b8b52272c4c5aaac932c0ee9d2d64e3db1fad2droubert@google.com        try {
904b8b52272c4c5aaac932c0ee9d2d64e3db1fad2droubert@google.com            listener.waitLoadingEnd();
914b8b52272c4c5aaac932c0ee9d2d64e3db1fad2droubert@google.com        } catch (InterruptedException e) {
924b8b52272c4c5aaac932c0ee9d2d64e3db1fad2droubert@google.com            throw new RuntimeException(e);
934b8b52272c4c5aaac932c0ee9d2d64e3db1fad2droubert@google.com        }
944b8b52272c4c5aaac932c0ee9d2d64e3db1fad2droubert@google.com    }
954b8b52272c4c5aaac932c0ee9d2d64e3db1fad2droubert@google.com
964b8b52272c4c5aaac932c0ee9d2d64e3db1fad2droubert@google.com    public void verifyAsync(AddressData address, AddressProblems problems,
974b8b52272c4c5aaac932c0ee9d2d64e3db1fad2droubert@google.com            DataLoadListener listener) {
984b8b52272c4c5aaac932c0ee9d2d64e3db1fad2droubert@google.com        Thread verifier = new Thread(new Verifier(address, problems, listener));
994b8b52272c4c5aaac932c0ee9d2d64e3db1fad2droubert@google.com        verifier.start();
1004b8b52272c4c5aaac932c0ee9d2d64e3db1fad2droubert@google.com    }
1014b8b52272c4c5aaac932c0ee9d2d64e3db1fad2droubert@google.com
1024b8b52272c4c5aaac932c0ee9d2d64e3db1fad2droubert@google.com    private class Verifier implements Runnable {
103ff01be390a0c4cbc5eb51ea8e2aceabfd1cbe2a3lararennie@google.com        private AddressData mAddress;
104ff01be390a0c4cbc5eb51ea8e2aceabfd1cbe2a3lararennie@google.com        private AddressProblems mProblems;
105ff01be390a0c4cbc5eb51ea8e2aceabfd1cbe2a3lararennie@google.com        private DataLoadListener mListener;
1064b8b52272c4c5aaac932c0ee9d2d64e3db1fad2droubert@google.com
1074b8b52272c4c5aaac932c0ee9d2d64e3db1fad2droubert@google.com        Verifier(AddressData address, AddressProblems problems, DataLoadListener listener) {
108ff01be390a0c4cbc5eb51ea8e2aceabfd1cbe2a3lararennie@google.com            mAddress = address;
109ff01be390a0c4cbc5eb51ea8e2aceabfd1cbe2a3lararennie@google.com            mProblems = problems;
110ff01be390a0c4cbc5eb51ea8e2aceabfd1cbe2a3lararennie@google.com            mListener = listener;
1112c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        }
1122c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com
1131e17a681ee8e5566384ead1588f6e6c4c8aa333aroubert@google.com        @Override
1144b8b52272c4c5aaac932c0ee9d2d64e3db1fad2droubert@google.com        public void run() {
115ff01be390a0c4cbc5eb51ea8e2aceabfd1cbe2a3lararennie@google.com            mListener.dataLoadingBegin();
1164b8b52272c4c5aaac932c0ee9d2d64e3db1fad2droubert@google.com
1174b8b52272c4c5aaac932c0ee9d2d64e3db1fad2droubert@google.com            FieldVerifier v = mRootVerifier;
1184b8b52272c4c5aaac932c0ee9d2d64e3db1fad2droubert@google.com
1194b8b52272c4c5aaac932c0ee9d2d64e3db1fad2droubert@google.com            ScriptType script = null;
120ff01be390a0c4cbc5eb51ea8e2aceabfd1cbe2a3lararennie@google.com            if (mAddress.getLanguageCode() != null) {
121ff01be390a0c4cbc5eb51ea8e2aceabfd1cbe2a3lararennie@google.com                if (Util.isExplicitLatinScript(mAddress.getLanguageCode())) {
1224b8b52272c4c5aaac932c0ee9d2d64e3db1fad2droubert@google.com                    script = ScriptType.LATIN;
1234b8b52272c4c5aaac932c0ee9d2d64e3db1fad2droubert@google.com                } else {
1244b8b52272c4c5aaac932c0ee9d2d64e3db1fad2droubert@google.com                    script = ScriptType.LOCAL;
1254b8b52272c4c5aaac932c0ee9d2d64e3db1fad2droubert@google.com                }
1264b8b52272c4c5aaac932c0ee9d2d64e3db1fad2droubert@google.com            }
1274b8b52272c4c5aaac932c0ee9d2d64e3db1fad2droubert@google.com
1284b8b52272c4c5aaac932c0ee9d2d64e3db1fad2droubert@google.com            // The first four calls refine the verifier, so must come first, and in this
1294b8b52272c4c5aaac932c0ee9d2d64e3db1fad2droubert@google.com            // order.
130ff01be390a0c4cbc5eb51ea8e2aceabfd1cbe2a3lararennie@google.com            verifyField(script, v, COUNTRY, mAddress.getPostalCountry(), mProblems);
131ff01be390a0c4cbc5eb51ea8e2aceabfd1cbe2a3lararennie@google.com            if (mProblems.isEmpty()) {
132ff01be390a0c4cbc5eb51ea8e2aceabfd1cbe2a3lararennie@google.com                v = v.refineVerifier(mAddress.getPostalCountry());
133ff01be390a0c4cbc5eb51ea8e2aceabfd1cbe2a3lararennie@google.com                verifyField(script, v, ADMIN_AREA, mAddress.getAdministrativeArea(), mProblems);
134ff01be390a0c4cbc5eb51ea8e2aceabfd1cbe2a3lararennie@google.com                if (mProblems.isEmpty()) {
135ff01be390a0c4cbc5eb51ea8e2aceabfd1cbe2a3lararennie@google.com                    v = v.refineVerifier(mAddress.getAdministrativeArea());
136ff01be390a0c4cbc5eb51ea8e2aceabfd1cbe2a3lararennie@google.com                    verifyField(script, v, LOCALITY, mAddress.getLocality(), mProblems);
137ff01be390a0c4cbc5eb51ea8e2aceabfd1cbe2a3lararennie@google.com                    if (mProblems.isEmpty()) {
138ff01be390a0c4cbc5eb51ea8e2aceabfd1cbe2a3lararennie@google.com                        v = v.refineVerifier(mAddress.getLocality());
1394b8b52272c4c5aaac932c0ee9d2d64e3db1fad2droubert@google.com                        verifyField(script, v, DEPENDENT_LOCALITY,
140ff01be390a0c4cbc5eb51ea8e2aceabfd1cbe2a3lararennie@google.com                                mAddress.getDependentLocality(), mProblems);
141ff01be390a0c4cbc5eb51ea8e2aceabfd1cbe2a3lararennie@google.com                        if (mProblems.isEmpty()) {
142ff01be390a0c4cbc5eb51ea8e2aceabfd1cbe2a3lararennie@google.com                            v = v.refineVerifier(mAddress.getDependentLocality());
1434b8b52272c4c5aaac932c0ee9d2d64e3db1fad2droubert@google.com                        }
144e804e26aadcdaa5bff50de31586db0847050a4fflararennie@google.com                    }
145e804e26aadcdaa5bff50de31586db0847050a4fflararennie@google.com                }
146e804e26aadcdaa5bff50de31586db0847050a4fflararennie@google.com            }
1472c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com
148ff01be390a0c4cbc5eb51ea8e2aceabfd1cbe2a3lararennie@google.com            String street = Util.joinAndSkipNulls("\n", mAddress.getAddressLine1(),
149ff01be390a0c4cbc5eb51ea8e2aceabfd1cbe2a3lararennie@google.com                    mAddress.getAddressLine2());
1502c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com
1514b8b52272c4c5aaac932c0ee9d2d64e3db1fad2droubert@google.com            // remaining calls don't change the field verifier
152ff01be390a0c4cbc5eb51ea8e2aceabfd1cbe2a3lararennie@google.com            verifyField(script, v, POSTAL_CODE, mAddress.getPostalCode(), mProblems);
153ff01be390a0c4cbc5eb51ea8e2aceabfd1cbe2a3lararennie@google.com            verifyField(script, v, STREET_ADDRESS, street, mProblems);
154ff01be390a0c4cbc5eb51ea8e2aceabfd1cbe2a3lararennie@google.com            verifyField(script, v, SORTING_CODE, mAddress.getSortingCode(), mProblems);
155ff01be390a0c4cbc5eb51ea8e2aceabfd1cbe2a3lararennie@google.com            verifyField(script, v, ORGANIZATION, mAddress.getOrganization(), mProblems);
156ff01be390a0c4cbc5eb51ea8e2aceabfd1cbe2a3lararennie@google.com            verifyField(script, v, RECIPIENT, mAddress.getRecipient(), mProblems);
1572c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com
158ff01be390a0c4cbc5eb51ea8e2aceabfd1cbe2a3lararennie@google.com            postVerify(v, mAddress, mProblems);
1594b8b52272c4c5aaac932c0ee9d2d64e3db1fad2droubert@google.com
160ff01be390a0c4cbc5eb51ea8e2aceabfd1cbe2a3lararennie@google.com            mListener.dataLoadingEnd();
1614b8b52272c4c5aaac932c0ee9d2d64e3db1fad2droubert@google.com        }
1622c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com    }
1632c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com
1642c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com    /**
1652c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     * Hook to perform any final processing using the final verifier.  Default does no additional
1662c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     * verification.
1672c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     */
1682c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com    protected void postVerify(FieldVerifier verifier, AddressData address,
1692c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com            AddressProblems problems) {
1702c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com    }
1712c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com
1722c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com    /**
1732c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     * Hook called by verify with each verifiable field, in order.  Override to provide pre- or
1742c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     * post-checks for all fields.
1752c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     */
1762c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com    protected boolean verifyField(LookupKey.ScriptType script,
1772c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com            FieldVerifier verifier, AddressField field, String value,
1782c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com            AddressProblems problems) {
1792c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        Iterator<AddressProblemType> iter = getProblemIterator(field);
1802c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        while (iter.hasNext()) {
1812c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com            AddressProblemType prob = iter.next();
1822c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com            if (!verifyProblemField(script, verifier, prob, field, value, problems)) {
1832c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com                return false;
1842c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com            }
1852c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        }
1862c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        return true;
1872c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com    }
1882c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com
1892c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com    /**
1902c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     * Hook for on-the-fly modification of the problem list.  Override to change the problems to
1912c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     * check for a particular field.  Generally, changing the problemMap passed to the constructor
1922c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     * is a better approach.
1932c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     */
1942c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com    protected Iterator<AddressProblemType> getProblemIterator(AddressField field) {
19537ea1c8bb9bf0ee18a9ce7412ace03885098e348lararennie@google.com        List<AddressProblemType> list = mProblemMap.get(field);
1962c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        if (list == null) {
1972c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com            list = Collections.emptyList();
1982c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        }
1992c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        return list.iterator();
2002c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com    }
2012c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com
2020d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.com    /**
2032c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     * Hook for adding special checks for particular problems and/or fields.
2040d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.com     */
2052c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com    protected boolean verifyProblemField(LookupKey.ScriptType script,
2062c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com            FieldVerifier verifier, AddressProblemType problem, AddressField field,
2072c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com            String datum, AddressProblems problems) {
2082c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        return verifier.check(script, problem, field, datum, problems);
2090d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.com    }
2100d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.com
2110d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.com    /**
2122c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     * This gets called with the hierarchical fields COUNTRY, ADMIN_AREA, LOCALITY,
2132c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     * DEPENDENT_LOCALITY in order, returning the refined verifier at each step.
2142c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     *
2152c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     * <p>The default implementation is stateless, and delegates to the verifier to do the
2162c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     * refinement.
2170d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.com     */
2182c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com    public static class VerifierRefiner {
2192c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com
2202c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        /**
2212c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com         * Refines the verifier.  This delegates to the verifier to perform the refinement.
2222c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com         */
2232c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        public FieldVerifier refineVerifier(FieldVerifier v, AddressField field,
2242c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com                String subkey) {
2252c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com            return v.refineVerifier(subkey);
2262c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        }
2272c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com
2282c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        /**
2292c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com         * Returns a clean version of the refiner.  Since this implementation is stateless, returns
2302c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com         * this.
2312c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com         */
2322c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        public VerifierRefiner newInstance() {
2332c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com            return this;
2342c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        }
2350d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.com    }
2360d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.com
2372c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com    private static final VerifierRefiner DEFAULT_REFINER = new VerifierRefiner();
2380d882db3bd1d570723e00d5c0d793544ae0ea258lararennie@google.com}
239