com.google.gwt.storage.client.Storage.java Source code

Java tutorial

Introduction

Here is the source code for com.google.gwt.storage.client.Storage.java

Source

/*
 * Copyright 2011 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.google.gwt.storage.client;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.PartialSupport;
import com.google.gwt.event.shared.HandlerRegistration;

/**
 * Implements the HTML5 Storage interface.
 *
 * <p>
 * You can obtain a Storage by either invoking
 * {@link #getLocalStorageIfSupported()} or
 * {@link #getSessionStorageIfSupported()}.
 * </p>
 *
 * <p>
 * <span style="color:red">Experimental API: This API is still under development
 * and is subject to change. </span>
 * </p>
 *
 * <p>
 * If Web Storage is NOT supported in the browser, these methods return <code>
 * null</code>.
 * </p>
 * 
 * <p>
 * Note: Storage events into other windows are not supported.
 * </p>
 *
 *
 * <p>
 * This may not be supported on all browsers.
 * </p>
 *
 * @see <a href="http://www.w3.org/TR/webstorage/#storage-0">W3C Web Storage -
 *      Storage</a>
 * @see <a
 *      href="http://devworld.apple.com/safari/library/documentation/iPhone/Conceptual/SafariJSDatabaseGuide/Name-ValueStorage/Name-ValueStorage.html">Safari
 *      Client-Side Storage and Offline Applications Programming Guide -
 *      Key-Value Storage</a>
 * @see <a href="http://quirksmode.org/dom/html5.html#t00">Quirksmode.org -
 *      HTML5 Compatibility - Storage</a>
 * @see <a href="http://code.google.com/p/gwt-mobile-webkit/wiki/StorageApi">Wiki - Quickstart Guide</a>
 */
// TODO(pdr): Add support for Object values, instead of just Strings. The
// Storage API spec specifies this, but browser support poor at the moment.
// TODO(pdr): Add support for native events once browsers correctly implement
// storage events.
@PartialSupport
public final class Storage {
    /**
     * Detector for browser support of Storage.
     */
    private static class StorageSupportDetector {
        private final boolean isLocalStorageSupported = detectLocalStorageSupport();
        private final boolean isSessionStorageSupported = detectSessionStorageSupport();

        public boolean isLocalStorageSupported() {
            return isLocalStorageSupported;
        }

        public boolean isSessionStorageSupported() {
            return isSessionStorageSupported;
        }

        private native boolean detectLocalStorageSupport() /*-{
                                                           return typeof $wnd.localStorage != "undefined";
                                                           }-*/;

        private native boolean detectSessionStorageSupport() /*-{
                                                             return typeof $wnd.sessionStorage != "undefined";
                                                             }-*/;
    }

    /**
     * Detector for browsers that do not support Storage.
     */
    @SuppressWarnings("unused")
    private static class StorageSupportDetectorNo extends StorageSupportDetector {
        @Override
        public boolean isLocalStorageSupported() {
            return false;
        }

        @Override
        public boolean isSessionStorageSupported() {
            return false;
        }
    }

    static final StorageImpl impl = GWT.create(StorageImpl.class);

    private static Storage localStorage;

    private static Storage sessionStorage;

    /**
     * Singleton for Support detector.
     */
    private static StorageSupportDetector supportDetectorImpl;

    /**
     * Registers an event handler for StorageEvents.
     *
     * @see <a href="http://www.w3.org/TR/webstorage/#the-storage-event">W3C Web
     *      Storage - the storage event</a>
     * @param handler
     * @return {@link HandlerRegistration} used to remove this handler
     */
    public static HandlerRegistration addStorageEventHandler(StorageEvent.Handler handler) {
        return impl.addStorageEventHandler(handler);
    }

    /**
     * Returns a Local Storage.
     *
     * <p>
     * The returned storage is associated with the <a
     * href="http://www.w3.org/TR/html5/browsers.html#origin">origin</a> of the
     * Document.
     * </p>
     *
     * @see <a href="http://www.w3.org/TR/webstorage/#dom-localstorage">W3C Web
     *      Storage - localStorage</a>
     * @return the localStorage instance, or <code>null</code> if Web Storage is
     *         NOT supported.
     */
    public static Storage getLocalStorageIfSupported() {
        if (isLocalStorageSupported()) {
            if (localStorage == null) {
                localStorage = new Storage(StorageImpl.LOCAL_STORAGE);
            }
            return localStorage;
        }
        return null;
    }

    /**
     * Returns a Session Storage.
     *
     * <p>
     * The returned storage is associated with the current <a href=
     * "http://www.w3.org/TR/html5/browsers.html#top-level-browsing-context"
     * >top-level browsing context</a>.
     * </p>
     *
     * @see <a href="http://www.w3.org/TR/webstorage/#dom-sessionstorage">W3C Web
     *      Storage - sessionStorage</a>
     * @return the sessionStorage instance, or <code>null</code> if Web Storage is
     *         NOT supported.
     */
    public static Storage getSessionStorageIfSupported() {
        if (isSessionStorageSupported()) {
            if (sessionStorage == null) {
                sessionStorage = new Storage(StorageImpl.SESSION_STORAGE);
            }
            return sessionStorage;
        }
        return null;
    }

    /**
     * Returns <code>true</code> if the <code>localStorage</code> part of the
     * Storage API is supported on the running platform.
     */
    public static boolean isLocalStorageSupported() {
        return getStorageSupportDetector().isLocalStorageSupported();
    }

    /**
     * Returns <code>true</code> if the <code>sessionStorage</code> part of the
     * Storage API is supported on the running platform.
     */
    public static boolean isSessionStorageSupported() {
        return getStorageSupportDetector().isSessionStorageSupported();
    }

    /**
     * Returns <code>true</code> if the Storage API (both localStorage and
     * sessionStorage) is supported on the running platform.
     */
    public static boolean isSupported() {
        return isLocalStorageSupported() && isSessionStorageSupported();
    }

    /**
     * De-registers an event handler for StorageEvents.
     *
     * @see <a href="http://www.w3.org/TR/webstorage/#the-storage-event">W3C Web
     *      Storage - the storage event</a>
     * @param handler
     */
    public static void removeStorageEventHandler(StorageEvent.Handler handler) {
        impl.removeStorageEventHandler(handler);
    }

    private static StorageSupportDetector getStorageSupportDetector() {
        if (supportDetectorImpl == null) {
            supportDetectorImpl = GWT.create(StorageSupportDetector.class);
        }
        return supportDetectorImpl;
    }

    // Contains either "localStorage" or "sessionStorage":
    private final String storage;

    /**
     * This class can never be instantiated externally. Use
     * {@link #getLocalStorageIfSupported()} or
     * {@link #getSessionStorageIfSupported()} instead.
     */
    private Storage(String storage) {
        this.storage = storage;
    }

    /**
     * Removes all items in the Storage.
     *
     * @see <a href="http://www.w3.org/TR/webstorage/#dom-storage-clear">W3C Web
     *      Storage - Storage.clear()</a>
     */
    public void clear() {
        impl.clear(storage);
    }

    /**
     * Returns the item in the Storage associated with the specified key.
     *
     * @param key the key to a value in the Storage
     * @return the value associated with the given key
     * @see <a href="http://www.w3.org/TR/webstorage/#dom-storage-getitem">W3C Web
     *      Storage - Storage.getItem(k)</a>
     */
    public String getItem(String key) {
        return impl.getItem(storage, key);
    }

    /**
     * Returns the number of items in this Storage.
     *
     * @return number of items in this Storage
     * @see <a href="http://www.w3.org/TR/webstorage/#dom-storage-l">W3C Web
     *      Storage - Storage.length()</a>
     */
    public int getLength() {
        return impl.getLength(storage);
    }

    /**
     * Returns the key at the specified index.
     *
     * @param index the index of the key
     * @return the key at the specified index in this Storage
     * @see <a href="http://www.w3.org/TR/webstorage/#dom-storage-key">W3C Web
     *      Storage - Storage.key(n)</a>
     */
    public String key(int index) {
        return impl.key(storage, index);
    }

    /**
     * Removes the item in the Storage associated with the specified key.
     *
     * @param key the key to a value in the Storage
     * @see <a href="http://www.w3.org/TR/webstorage/#dom-storage-removeitem">W3C
     *      Web Storage - Storage.removeItem(k)</a>
     */
    public void removeItem(String key) {
        impl.removeItem(storage, key);
    }

    /**
     * Sets the value in the Storage associated with the specified key to the
     * specified data.
     *
     * Note: The empty string may not be used as a key.
     *
     * @param key the key to a value in the Storage
     * @param data the value associated with the key
     * @see <a href="http://www.w3.org/TR/webstorage/#dom-storage-setitem">W3C Web
     *      Storage - Storage.setItem(k,v)</a>
     */
    public void setItem(String key, String data) {
        // prevent the empty string due to a Firefox bug:
        // bugzilla.mozilla.org/show_bug.cgi?id=510849
        assert key.length() > 0;
        impl.setItem(storage, key, data);
    }
}