Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / libaddressinput / src / java / src / com / android / i18n / addressinput / CacheData.java
index 4f98e6f..39942c9 100644 (file)
@@ -34,385 +34,385 @@ import java.util.HashSet;
  */
 public final class CacheData {
 
-    /**
-     * Used to identify the source of a log message.
-     */
-    private static final String TAG = "CacheData";
-
-    /**
-     * Time out value for the server to respond in millisecond.
-     */
-    private static final int TIMEOUT = 5000;
-
-    /**
-     * URL to get address data. You can also reset it by calling {@link #setUrl(String)}.
-     */
-    private String mServiceUrl;
-
-    /**
-     * Storage for all dynamically retrieved data.
-     */
-    private final JsoMap mCache;
-
-    /**
-     * CacheManager that handles caching that is needed by the client of the Address Widget.
-     */
-    private final ClientCacheManager mClientCacheManager;
-
-    /**
-     * All requests that have been sent.
-     */
-    private final HashSet<String> mRequestedKeys = new HashSet<String>();
-
-    /**
-     * All invalid requested keys. For example, if we request a random string "asdfsdf9o", and the
-     * server responds by saying this key is invalid, it will be stored here.
-     */
-    private final HashSet<String> mBadKeys = new HashSet<String>();
-
-    /**
-     * Temporary store for {@code CacheListener}s. When a key is requested and still waiting for
-     * server's response, the listeners for the same key will be temporary stored here. When the
-     * server responded, these listeners will be triggered and then removed.
-     */
-    private final HashMap<LookupKey, HashSet<CacheListener>> mTemporaryListenerStore =
-            new HashMap<LookupKey, HashSet<CacheListener>>();
-
-    /**
-     * Creates an instance of CacheData with an empty cache, and uses no caching that is external
-     * to the AddressWidget.
-     */
-    public CacheData() {
-        this(new SimpleClientCacheManager());
+  /**
+   * Used to identify the source of a log message.
+   */
+  private static final String TAG = "CacheData";
+
+  /**
+   * Time out value for the server to respond in millisecond.
+   */
+  private static final int TIMEOUT = 5000;
+
+  /**
+   * URL to get address data. You can also reset it by calling {@link #setUrl(String)}.
+   */
+  private String serviceUrl;
+
+  /**
+   * Storage for all dynamically retrieved data.
+   */
+  private final JsoMap cache;
+
+  /**
+   * CacheManager that handles caching that is needed by the client of the Address Widget.
+   */
+  private final ClientCacheManager clientCacheManager;
+
+  /**
+   * All requests that have been sent.
+   */
+  private final HashSet<String> requestedKeys = new HashSet<String>();
+
+  /**
+   * All invalid requested keys. For example, if we request a random string "asdfsdf9o", and the
+   * server responds by saying this key is invalid, it will be stored here.
+   */
+  private final HashSet<String> badKeys = new HashSet<String>();
+
+  /**
+   * Temporary store for {@code CacheListener}s. When a key is requested and still waiting for
+   * server's response, the listeners for the same key will be temporary stored here. When the
+   * server responded, these listeners will be triggered and then removed.
+   */
+  private final HashMap<LookupKey, HashSet<CacheListener>> temporaryListenerStore =
+      new HashMap<LookupKey, HashSet<CacheListener>>();
+
+  /**
+   * Creates an instance of CacheData with an empty cache, and uses no caching that is external
+   * to the AddressWidget.
+   */
+  public CacheData() {
+    this(new SimpleClientCacheManager());
+  }
+
+  /**
+   * Creates an instance of CacheData with an empty cache, and uses additional caching (external
+   * to the AddressWidget) specified by clientCacheManager.
+   */
+  public CacheData(ClientCacheManager clientCacheManager) {
+    this.clientCacheManager = clientCacheManager;
+    setUrl(clientCacheManager.getAddressServerUrl());
+    cache = JsoMap.createEmptyJsoMap();
+  }
+
+  /**
+   * This constructor is meant to be used together with external caching.
+   *
+   * Use case:
+   *
+   * After having finished using the address widget:
+   * String allCachedData = getJsonString();
+   * Cache (save) allCachedData wherever makes sense for your service / activity
+   *
+   * Before using it next time:
+   * Get the saved allCachedData string
+   * new ClientData(new CacheData(allCachedData))
+   *
+   * If you don't have any saved data you can either just pass an empty string to
+   * this constructor or use the other constructor.
+   *
+   * @param jsonString cached data from last time the class was used
+   */
+  public CacheData(String jsonString) {
+    clientCacheManager = new SimpleClientCacheManager();
+    setUrl(clientCacheManager.getAddressServerUrl());
+    JsoMap tempMap = null;
+    try {
+      tempMap = JsoMap.buildJsoMap(jsonString);
+    } catch (JSONException jsonE) {
+      // If parsing the JSON string throws an exception, default to
+      // starting with an empty cache.
+      Log.w(TAG, "Could not parse json string, creating empty cache instead.");
+      tempMap = JsoMap.createEmptyJsoMap();
+    } finally {
+      cache = tempMap;
     }
+  }
 
-    /**
-     * Creates an instance of CacheData with an empty cache, and uses additional caching (external
-     * to the AddressWidget) specified by clientCacheManager.
-     */
-    public CacheData(ClientCacheManager clientCacheManager) {
-        mClientCacheManager = clientCacheManager;
-        setUrl(mClientCacheManager.getAddressServerUrl());
-        mCache = JsoMap.createEmptyJsoMap();
-    }
+  /**
+   * Interface for all listeners to {@link CacheData} change. This is only used when multiple
+   * requests of the same key is dispatched and server has not responded yet.
+   */
+  private static interface CacheListener extends EventListener {
 
     /**
-     * This constructor is meant to be used together with external caching.
-     *
-     * Use case:
-     *
-     * After having finished using the address widget:
-     * String allCachedData = getJsonString();
-     * Cache (save) allCachedData wherever makes sense for your service / activity
-     *
-     * Before using it next time:
-     * Get the saved allCachedData string
-     * new ClientData(new CacheData(allCachedData))
-     *
-     * If you don't have any saved data you can either just pass an empty string to
-     * this constructor or use the other constructor.
+     * The function that will be called when valid data is about to be put in the cache.
      *
-     * @param jsonString cached data from last time the class was used
+     * @param key the key for newly arrived data.
      */
-    public CacheData(String jsonString) {
-        mClientCacheManager = new SimpleClientCacheManager();
-        setUrl(mClientCacheManager.getAddressServerUrl());
-        JsoMap tempMap = null;
-        try {
-            tempMap = JsoMap.buildJsoMap(jsonString);
-        } catch (JSONException jsonE) {
-            // If parsing the JSON string throws an exception, default to
-            // starting with an empty cache.
-            Log.w(TAG, "Could not parse json string, creating empty cache instead.");
-            tempMap = JsoMap.createEmptyJsoMap();
-        } finally {
-            mCache = tempMap;
-        }
-    }
+    void onAdd(String key);
+  }
 
-    /**
-     * Interface for all listeners to {@link CacheData} change. This is only used when multiple
-     * requests of the same key is dispatched and server has not responded yet.
-     */
-    private static interface CacheListener extends EventListener {
-
-        /**
-         * The function that will be called when valid data is about to be put in the cache.
-         *
-         * @param key the key for newly arrived data.
-         */
-        void onAdd(String key);
-    }
+  /**
+   * Class to handle JSON response.
+   */
+  private class JsonHandler {
 
     /**
-     * Class to handle JSON response.
+     * Key for the requested data.
      */
-    private class JsonHandler {
-
-        /**
-         * Key for the requested data.
-         */
-        private final String mKey;
-
-        /**
-         * Pre-existing data for the requested key. Null is allowed.
-         */
-        private final JSONObject mExistingJso;
-
-        private final DataLoadListener mListener;
-
-        /**
-         * Constructs a JsonHandler instance.
-         *
-         * @param key    The key for requested data.
-         * @param oldJso Pre-existing data for this key or null.
-         */
-        private JsonHandler(String key, JSONObject oldJso, DataLoadListener listener) {
-            checkNotNull(key);
-            mKey = key;
-            mExistingJso = oldJso;
-            mListener = listener;
-        }
-
-        /**
-         * Saves valid responded data to the cache once data arrives, or if the key is invalid,
-         * saves it in the invalid cache. If there is pre-existing data for the key, it will merge
-         * the new data will the old one. It also triggers {@link DataLoadListener#dataLoadingEnd()}
-         * method before it returns (even when the key is invalid, or input jso is null). This is
-         * called from a background thread.
-         *
-         * @param map The received JSON data as a map.
-         */
-        private void handleJson(JsoMap map) {
-            // Can this ever happen?
-            if (map == null) {
-                Log.w(TAG, "server returns null for key:" + mKey);
-                mBadKeys.add(mKey);
-                notifyListenersAfterJobDone(mKey);
-                triggerDataLoadingEndIfNotNull(mListener);
-                return;
-            }
-
-            JSONObject json = map;
-            String idKey = AddressDataKey.ID.name().toLowerCase();
-            if (!json.has(idKey)) {
-                Log.w(TAG, "invalid or empty data returned for key: " + mKey);
-                mBadKeys.add(mKey);
-                notifyListenersAfterJobDone(mKey);
-                triggerDataLoadingEndIfNotNull(mListener);
-                return;
-            }
-
-            if (mExistingJso != null) {
-                map.mergeData((JsoMap) mExistingJso);
-            }
-
-            mCache.putObj(mKey, map);
-            notifyListenersAfterJobDone(mKey);
-            triggerDataLoadingEndIfNotNull(mListener);
-        }
-    }
+    private final String key;
 
     /**
-     * Sets address data server URL. Input URL cannot be null.
-     *
-     * @param url The service URL.
+     * Pre-existing data for the requested key. Null is allowed.
      */
-    public void setUrl(String url) {
-        checkNotNull(url, "Cannot set URL of address data server to null.");
-        mServiceUrl = url;
-    }
+    private final JSONObject existingJso;
 
-    /**
-     * Gets address data server URL.
-     */
-    public String getUrl() {
-        return mServiceUrl;
-    }
+    private final DataLoadListener listener;
 
     /**
-     * Returns a JSON string representing the data currently stored in this cache. It can be used
-     * to later create a new CacheData object containing the same cached data.
+     * Constructs a JsonHandler instance.
      *
-     * @return a JSON string representing the data stored in this cache
+     * @param key    The key for requested data.
+     * @param oldJso Pre-existing data for this key or null.
      */
-    public String getJsonString() {
-        return mCache.toString();
-    }
-
-    /**
-     * Checks if key and its value is cached (Note that only valid ones are cached).
-     */
-    public boolean containsKey(String key) {
-        return mCache.containsKey(key);
-    }
-
-    // This method is called from a background thread.
-    private void triggerDataLoadingEndIfNotNull(DataLoadListener listener) {
-        if (listener != null) {
-            listener.dataLoadingEnd();
-        }
+    private JsonHandler(String key, JSONObject oldJso, DataLoadListener listener) {
+      checkNotNull(key);
+      this.key = key;
+      this.existingJso = oldJso;
+      this.listener = listener;
     }
 
     /**
-     * Fetches data from server, or returns if the data is already cached. If the fetched data is
-     * valid, it will be added to the cache. This method also triggers {@link
-     * DataLoadListener#dataLoadingEnd()} method before it returns.
+     * Saves valid responded data to the cache once data arrives, or if the key is invalid,
+     * saves it in the invalid cache. If there is pre-existing data for the key, it will merge
+     * the new data will the old one. It also triggers {@link DataLoadListener#dataLoadingEnd()}
+     * method before it returns (even when the key is invalid, or input jso is null). This is
+     * called from a background thread.
      *
-     * @param existingJso Pre-existing data for this key or null if none.
-     * @param listener    An optional listener to call when done.
+     * @param map The received JSON data as a map.
      */
-    void fetchDynamicData(final LookupKey key, JSONObject existingJso,
-            final DataLoadListener listener) {
-        checkNotNull(key, "null key not allowed.");
-
-        if (listener != null) {
-            listener.dataLoadingBegin();
-        }
-
-        // Key is valid and cached.
-        if (mCache.containsKey(key.toString())) {
-            triggerDataLoadingEndIfNotNull(listener);
-            return;
-        }
-
-        // Key is invalid and cached.
-        if (mBadKeys.contains(key.toString())) {
-            triggerDataLoadingEndIfNotNull(listener);
-            return;
-        }
-
-        // Already requested the key, and is still waiting for server's response.
-        if (!mRequestedKeys.add(key.toString())) {
-            Log.d(TAG, "data for key " + key + " requested but not cached yet");
-            addListenerToTempStore(key, new CacheListener() {
-                @Override
-                public void onAdd(String myKey) {
-                    triggerDataLoadingEndIfNotNull(listener);
-                }
-            });
-            return;
-        }
-
-        // Key is in the cache maintained by the client of the AddressWidget.
-        String dataFromClientCache = mClientCacheManager.get(key.toString());
-        if (dataFromClientCache != null && dataFromClientCache.length() > 0) {
-            final JsonHandler handler = new JsonHandler(key.toString(),
-                existingJso, listener);
-            try {
-                handler.handleJson(JsoMap.buildJsoMap(dataFromClientCache));
-                return;
-            } catch (JSONException e) {
-                Log.w(TAG, "Data from client's cache is in the wrong format: "
-                        + dataFromClientCache);
-            }
-        }
-
-        // Key is not cached yet, now sending the request to the server.
-        JsonpRequestBuilder jsonp = new JsonpRequestBuilder();
-        jsonp.setTimeout(TIMEOUT);
-        final JsonHandler handler = new JsonHandler(key.toString(),
-                existingJso, listener);
-        jsonp.requestObject(mServiceUrl + "/" + key.toString(),
-                new AsyncCallback<JsoMap>() {
-                    @Override
-                    public void onFailure(Throwable caught) {
-                        Log.w(TAG, "Request for key " + key + " failed");
-                        mRequestedKeys.remove(key.toString());
-                        notifyListenersAfterJobDone(key.toString());
-                        triggerDataLoadingEndIfNotNull(listener);
-                    }
-
-                    @Override
-                    public void onSuccess(JsoMap result) {
-                        handler.handleJson(result);
-                        // Put metadata into the cache maintained by the client of the
-                        // AddressWidget.
-                        String dataRetrieved = result.toString();
-                        mClientCacheManager.put(key.toString(), dataRetrieved);
-                    }
-                });
+    private void handleJson(JsoMap map) {
+      // Can this ever happen?
+      if (map == null) {
+        Log.w(TAG, "server returns null for key:" + key);
+        badKeys.add(key);
+        notifyListenersAfterJobDone(key);
+        triggerDataLoadingEndIfNotNull(listener);
+        return;
+      }
+
+      JSONObject json = map;
+      String idKey = AddressDataKey.ID.name().toLowerCase();
+      if (!json.has(idKey)) {
+        Log.w(TAG, "invalid or empty data returned for key: " + key);
+        badKeys.add(key);
+        notifyListenersAfterJobDone(key);
+        triggerDataLoadingEndIfNotNull(listener);
+        return;
+      }
+
+      if (existingJso != null) {
+        map.mergeData((JsoMap) existingJso);
+      }
+
+      cache.putObj(key, map);
+      notifyListenersAfterJobDone(key);
+      triggerDataLoadingEndIfNotNull(listener);
     }
-
-    /**
-     * Gets region data from our compiled-in java file and stores it in the
-     * cache. This is only called when data cannot be obtained from the server,
-     * so there will be no pre-existing data for this key.
-     */
-    void getFromRegionDataConstants(final LookupKey key) {
-        checkNotNull(key, "null key not allowed.");
-        String data = RegionDataConstants.getCountryFormatMap().get(
-                key.getValueForUpperLevelField(AddressField.COUNTRY));
-        if (data != null) {
-            try {
-                mCache.putObj(key.toString(), JsoMap.buildJsoMap(data));
-            } catch (JSONException e) {
-                Log.w(TAG, "Failed to parse data for key " + key +
-                      " from RegionDataConstants");
-            }
-        }
+  }
+
+  /**
+   * Sets address data server URL. Input URL cannot be null.
+   *
+   * @param url The service URL.
+   */
+  public void setUrl(String url) {
+    checkNotNull(url, "Cannot set URL of address data server to null.");
+    serviceUrl = url;
+  }
+
+  /**
+   * Gets address data server URL.
+   */
+  public String getUrl() {
+    return serviceUrl;
+  }
+
+  /**
+   * Returns a JSON string representing the data currently stored in this cache. It can be used
+   * to later create a new CacheData object containing the same cached data.
+   *
+   * @return a JSON string representing the data stored in this cache
+   */
+  public String getJsonString() {
+    return cache.toString();
+  }
+
+  /**
+   * Checks if key and its value is cached (Note that only valid ones are cached).
+   */
+  public boolean containsKey(String key) {
+    return cache.containsKey(key);
+  }
+
+  // This method is called from a background thread.
+  private void triggerDataLoadingEndIfNotNull(DataLoadListener listener) {
+    if (listener != null) {
+      listener.dataLoadingEnd();
     }
-
-    /**
-     * Retrieves string data identified by key.
-     *
-     * @param key Non-null key. E.g., "data/US/CA".
-     * @return String value for specified key.
-     */
-    public String get(String key) {
-        checkNotNull(key, "null key not allowed");
-        return mCache.get(key);
+  }
+
+  /**
+   * Fetches data from server, or returns if the data is already cached. If the fetched data is
+   * valid, it will be added to the cache. This method also triggers {@link
+   * DataLoadListener#dataLoadingEnd()} method before it returns.
+   *
+   * @param existingJso Pre-existing data for this key or null if none.
+   * @param listener    An optional listener to call when done.
+   */
+  void fetchDynamicData(final LookupKey key, JSONObject existingJso,
+      final DataLoadListener listener) {
+    checkNotNull(key, "null key not allowed.");
+
+    if (listener != null) {
+      listener.dataLoadingBegin();
     }
 
-    /**
-     * Retrieves JsoMap data identified by key.
-     *
-     * @param key Non-null key. E.g., "data/US/CA".
-     * @return String value for specified key.
-     */
-    public JsoMap getObj(String key) {
-        checkNotNull(key, "null key not allowed");
-        return mCache.getObj(key);
+    // Key is valid and cached.
+    if (cache.containsKey(key.toString())) {
+      triggerDataLoadingEndIfNotNull(listener);
+      return;
     }
 
-    private void notifyListenersAfterJobDone(String key) {
-        LookupKey lookupKey = new LookupKey.Builder(key).build();
-        HashSet<CacheListener> listeners = mTemporaryListenerStore.get(lookupKey);
-        if (listeners != null) {
-            for (CacheListener listener : listeners) {
-                listener.onAdd(key.toString());
-            }
-            listeners.clear();
-        }
+    // Key is invalid and cached.
+    if (badKeys.contains(key.toString())) {
+      triggerDataLoadingEndIfNotNull(listener);
+      return;
     }
 
-    private void addListenerToTempStore(LookupKey key, CacheListener listener) {
-        checkNotNull(key);
-        checkNotNull(listener);
-        HashSet<CacheListener> listeners = mTemporaryListenerStore.get(key);
-        if (listeners == null) {
-            listeners = new HashSet<CacheListener>();
-            mTemporaryListenerStore.put(key, listeners);
+    // Already requested the key, and is still waiting for server's response.
+    if (!requestedKeys.add(key.toString())) {
+      Log.d(TAG, "data for key " + key + " requested but not cached yet");
+      addListenerToTempStore(key, new CacheListener() {
+        @Override
+        public void onAdd(String myKey) {
+          triggerDataLoadingEndIfNotNull(listener);
         }
-        listeners.add(listener);
+      });
+      return;
     }
 
-    /**
-     * Added for testing purposes.
-     * Adds a new object into the cache.
-     * @param id string of the format "data/country/.." ie. "data/US/CA"
-     * @param object The JSONObject to be put into cache.
-     */
-    void addToJsoMap(String id, JSONObject object) {
-        mCache.putObj(id, object);
+    // Key is in the cache maintained by the client of the AddressWidget.
+    String dataFromClientCache = clientCacheManager.get(key.toString());
+    if (dataFromClientCache != null && dataFromClientCache.length() > 0) {
+      final JsonHandler handler = new JsonHandler(key.toString(),
+          existingJso, listener);
+      try {
+        handler.handleJson(JsoMap.buildJsoMap(dataFromClientCache));
+        return;
+      } catch (JSONException e) {
+        Log.w(TAG, "Data from client's cache is in the wrong format: "
+            + dataFromClientCache);
+      }
     }
 
-    /**
-     * Added for testing purposes.
-     * Checks to see if the cache is empty,
-     * @return true if the internal cache is empty
-     */
-    boolean isEmpty() {
-        return mCache.length() == 0;
+    // Key is not cached yet, now sending the request to the server.
+    JsonpRequestBuilder jsonp = new JsonpRequestBuilder();
+    jsonp.setTimeout(TIMEOUT);
+    final JsonHandler handler = new JsonHandler(key.toString(),
+        existingJso, listener);
+    jsonp.requestObject(serviceUrl + "/" + key.toString(),
+        new AsyncCallback<JsoMap>() {
+          @Override
+          public void onFailure(Throwable caught) {
+            Log.w(TAG, "Request for key " + key + " failed");
+            requestedKeys.remove(key.toString());
+            notifyListenersAfterJobDone(key.toString());
+            triggerDataLoadingEndIfNotNull(listener);
+          }
+
+          @Override
+          public void onSuccess(JsoMap result) {
+            handler.handleJson(result);
+            // Put metadata into the cache maintained by the client of the
+            // AddressWidget.
+            String dataRetrieved = result.toString();
+            clientCacheManager.put(key.toString(), dataRetrieved);
+          }
+        });
+  }
+
+  /**
+   * Gets region data from our compiled-in java file and stores it in the
+   * cache. This is only called when data cannot be obtained from the server,
+   * so there will be no pre-existing data for this key.
+   */
+  void getFromRegionDataConstants(final LookupKey key) {
+    checkNotNull(key, "null key not allowed.");
+    String data = RegionDataConstants.getCountryFormatMap().get(
+        key.getValueForUpperLevelField(AddressField.COUNTRY));
+    if (data != null) {
+      try {
+        cache.putObj(key.toString(), JsoMap.buildJsoMap(data));
+      } catch (JSONException e) {
+        Log.w(TAG, "Failed to parse data for key " + key +
+            " from RegionDataConstants");
+      }
+    }
+  }
+
+  /**
+   * Retrieves string data identified by key.
+   *
+   * @param key Non-null key. E.g., "data/US/CA".
+   * @return String value for specified key.
+   */
+  public String get(String key) {
+    checkNotNull(key, "null key not allowed");
+    return cache.get(key);
+  }
+
+  /**
+   * Retrieves JsoMap data identified by key.
+   *
+   * @param key Non-null key. E.g., "data/US/CA".
+   * @return String value for specified key.
+   */
+  public JsoMap getObj(String key) {
+    checkNotNull(key, "null key not allowed");
+    return cache.getObj(key);
+  }
+
+  private void notifyListenersAfterJobDone(String key) {
+    LookupKey lookupKey = new LookupKey.Builder(key).build();
+    HashSet<CacheListener> listeners = temporaryListenerStore.get(lookupKey);
+    if (listeners != null) {
+      for (CacheListener listener : listeners) {
+        listener.onAdd(key.toString());
+      }
+      listeners.clear();
+    }
+  }
+
+  private void addListenerToTempStore(LookupKey key, CacheListener listener) {
+    checkNotNull(key);
+    checkNotNull(listener);
+    HashSet<CacheListener> listeners = temporaryListenerStore.get(key);
+    if (listeners == null) {
+      listeners = new HashSet<CacheListener>();
+      temporaryListenerStore.put(key, listeners);
     }
+    listeners.add(listener);
+  }
+
+  /**
+   * Added for testing purposes.
+   * Adds a new object into the cache.
+   * @param id string of the format "data/country/.." ie. "data/US/CA"
+   * @param object The JSONObject to be put into cache.
+   */
+  void addToJsoMap(String id, JSONObject object) {
+    cache.putObj(id, object);
+  }
+
+  /**
+   * Added for testing purposes.
+   * Checks to see if the cache is empty,
+   * @return true if the internal cache is empty
+   */
+  boolean isEmpty() {
+    return cache.length() == 0;
+  }
 }