package org.sigmah.offline.indexeddb; /* * #%L * Sigmah * %% * Copyright (C) 2010 - 2016 URD * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ import java.util.ArrayList; import java.util.List; import org.sigmah.offline.event.JavaScriptEvent; import com.allen_sauer.gwt.log.client.Log; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.user.client.rpc.AsyncCallback; /** * Request to open an IndexedDB database. * * @author Raphaƫl Calabro (rcalabro@ideia.fr) * @param <S> Type defining the schema of the database. */ public class NativeOpenDatabaseRequest<S extends Enum<S> & Schema> extends Request implements OpenDatabaseRequest<S> { private final List<JavaScriptEvent<IDBVersionChangeEvent>> upgradeNeededHandlers = new ArrayList<JavaScriptEvent<IDBVersionChangeEvent>>(); private final List<JavaScriptEvent<JavaScriptObject>> blockedHandlers = new ArrayList<JavaScriptEvent<JavaScriptObject>>(); private final Class<S> stores; private boolean openFailed; NativeOpenDatabaseRequest(IDBOpenDBRequest request, Class<S> stores) { super(request); this.stores = stores; registerEvents(request); } /** * Register the listeners for the native events. * * @param request * Request to listen. */ private native void registerEvents(IDBOpenDBRequest request) /*-{ if(typeof $wnd.Object.getPrototypeOf != 'undefined') { $wnd.Object.getPrototypeOf(this).handleEvent = function(event) { switch(event.type) { case 'success': this.@org.sigmah.offline.indexeddb.NativeOpenDatabaseRequest::fireSuccess(Lcom/google/gwt/core/client/JavaScriptObject;)(event); break; case 'error': this.@org.sigmah.offline.indexeddb.NativeOpenDatabaseRequest::fireError(Lcom/google/gwt/core/client/JavaScriptObject;)(event); break; case 'upgradeneeded': this.@org.sigmah.offline.indexeddb.NativeOpenDatabaseRequest::fireUpgradeNeeded(Lorg/sigmah/offline/indexeddb/IDBVersionChangeEvent;)(event); break; case 'blocked': this.@org.sigmah.offline.indexeddb.NativeOpenDatabaseRequest::fireBlocked(Lcom/google/gwt/core/client/JavaScriptObject;)(event); break; default: break; } }; request.addEventListener('upgradeneeded', this); request.addEventListener('blocked', this); } }-*/; /** * {@inheritDoc} */ @Override public Database<S> getResult() { if (!openFailed) { return new Database<S>((IDBDatabase) super.getResult(), stores); } else { return null; } } /** * {@inheritDoc} */ @Override public void addSuccessHandler(final JavaScriptEvent<?> successHandler) { addCallback(new AsyncCallback<Request>() { @Override public void onFailure(Throwable caught) { Log.error("Error while opening an IndexedDB database.", caught); openFailed = true; successHandler.onEvent(null); } @Override public void onSuccess(Request result) { successHandler.onEvent(null); } }); } /** * Adds the given handler to the list of handlers called when an upgrade is * needed. * * @param handler * Handler to add. */ public void addUpgradeNeededHandler(final JavaScriptEvent<IDBVersionChangeEvent> handler) { upgradeNeededHandlers.add(handler); } /** * Fire the given <code>upgrade</code> event. * * @param event * Event to fire. */ protected void fireUpgradeNeeded(final IDBVersionChangeEvent event) { for(int index = upgradeNeededHandlers.size() - 1; index >= 0; index--) { upgradeNeededHandlers.get(index).onEvent(event); } } /** * Adds the given handler to the list of handlers called when a * <code>blocked</code> event occurs. * * @param handler * Handler to add. */ public void addBlockedHandler(final JavaScriptEvent<JavaScriptObject> handler) { blockedHandlers.add(handler); } /** * Fire the given <code>blocked</code> event. * * @param event * Event to fire. */ protected void fireBlocked(final JavaScriptObject event) { for(int index = blockedHandlers.size() - 1; index >= 0; index--) { blockedHandlers.get(index).onEvent(event); } } }