package org.sigmah.offline.dispatch; /* * #%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.HashMap; import java.util.Map; import org.sigmah.client.security.AuthenticationProvider; import org.sigmah.client.security.SecureDispatchAsync; import org.sigmah.client.security.SecureDispatchServiceAsync; import org.sigmah.shared.command.base.Command; import org.sigmah.shared.command.result.Authentication; import org.sigmah.shared.command.result.Result; import com.allen_sauer.gwt.log.client.Log; import com.google.gwt.storage.client.Storage; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.inject.Singleton; /** * Dispatches commands to local handlers. Primarily used when offline but can * be used to cache ressources. * * @author Raphaƫl Calabro (raphael.calabro@netapsys.fr) */ @Singleton public class LocalDispatchServiceAsync implements SecureDispatchServiceAsync { public static final String LAST_USER_ITEM = "sigmah.last-user"; /** * Map associating a command type to its offline handler. */ private final Map<Class, AsyncCommandHandler> registry; /** * Provides information about the current user. */ private final AuthenticationProvider authenticationProvider; public LocalDispatchServiceAsync(AuthenticationProvider authenticationProvider) { this.authenticationProvider = authenticationProvider; this.registry = new HashMap<Class, AsyncCommandHandler>(); } public <C extends Command<R>, R extends Result> void registerHandler(Class<C> commandClass, AsyncCommandHandler<C,R> handler) { registry.put(commandClass, handler); } /** * {@inheritDoc} */ @Override public <C extends Command<R>, R extends Result> void execute(SecureDispatchAsync.CommandExecution<C, R> commandExecution, AsyncCallback<Result> callback) { final C command = commandExecution.getCommand(); Log.info("Local " + command.getClass().getName() + " is pending..."); final AsyncCommandHandler handler = getHandler(command); if(handler == null) { callback.onFailure(new UnavailableCommandException("No handler is registered for command '" + command.getClass().getName() + "'.")); } else { final OfflineExecutionContext executionContext = new OfflineExecutionContext(getAuthentication()); handler.execute(command, executionContext, callback); } } /** * Executes the given {@code commandExecution} corresponding {@link Command} and executes the given {@code callback} * once command has been processed. * * This method is thought to be executable online. * * @param <C> Command type. * @param <R> Result type. * @param command * The {@link Command} to execute. * @param callback * The callback executed once command has been processed. */ public <C extends Command<R>, R extends Result> void execute(final C command, final AsyncCallback<R> callback) { getHandler(command).execute(command, new OfflineExecutionContext(getAuthentication()), callback); } /** * Retrieves the handler associated with the given command. * * @param <C> Command type. * @param <R> Result type. * @param c Command to execute. * @return The associated handler or <code>null</code> if not found. */ private <C extends Command<R>, R extends Result> AsyncCommandHandler<C, R> getHandler(C c) { final AsyncCommandHandler<C, R> handler = registry.get(c.getClass()); return handler; } /** * Retrieves the current authentication. * * @return The current authentication. */ private Authentication getAuthentication() { final Authentication authentication = authenticationProvider.get(); if (authentication.getUserEmail() == null) { // Search the last logged user in the users database final Storage storage = Storage.getLocalStorageIfSupported(); final String email = storage.getItem(LAST_USER_ITEM); authentication.setUserEmail(email); } return authentication; } }