Package edu.stanford.bmir.protege.web.client.dispatch

Source Code of edu.stanford.bmir.protege.web.client.dispatch.DispatchServiceManager$AsyncCallbackProxy

package edu.stanford.bmir.protege.web.client.dispatch;

import com.google.common.base.Optional;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException;
import com.google.gwt.user.client.rpc.InvocationException;
import com.google.web.bindery.event.shared.Event;
import com.google.web.bindery.event.shared.UmbrellaException;
import edu.stanford.bmir.protege.web.client.dispatch.cache.ResultCache;
import edu.stanford.bmir.protege.web.client.rpc.RenderingServiceManager;
import edu.stanford.bmir.protege.web.client.ui.library.msgbox.MessageBox;
import edu.stanford.bmir.protege.web.shared.BrowserTextMap;
import edu.stanford.bmir.protege.web.shared.HasBrowserTextMap;
import edu.stanford.bmir.protege.web.shared.HasProjectId;
import edu.stanford.bmir.protege.web.shared.dispatch.Action;
import edu.stanford.bmir.protege.web.shared.dispatch.DispatchServiceResultContainer;
import edu.stanford.bmir.protege.web.shared.dispatch.InvocationExceptionTolerantAction;
import edu.stanford.bmir.protege.web.shared.dispatch.Result;
import edu.stanford.bmir.protege.web.shared.event.EventBusManager;
import edu.stanford.bmir.protege.web.shared.event.HasEventList;
import edu.stanford.bmir.protege.web.shared.event.SerializableEvent;
import edu.stanford.bmir.protege.web.shared.events.EventList;
import edu.stanford.bmir.protege.web.shared.permissions.PermissionDeniedException;
import edu.stanford.bmir.protege.web.shared.project.ProjectId;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* Author: Matthew Horridge<br>
* Stanford University<br>
* Bio-Medical Informatics Research Group<br>
* Date: 20/01/2013
*/
public class DispatchServiceManager {

    private static DispatchServiceManager instance;


    private DispatchServiceAsync async;


    private DispatchServiceManager() {
        async = GWT.create(DispatchService.class);
    }


    public static DispatchServiceManager get() {
        if(instance == null) {
            instance = new DispatchServiceManager();
        }
        return instance;
    }

    private int requestCount;

    private Map<ProjectId, ResultCache> resultCacheMap = new HashMap<ProjectId, ResultCache>();

    private ResultCache getResultCache(ProjectId projectId) {
        ResultCache resultCache = resultCacheMap.get(projectId);
        if(resultCache == null) {
            resultCache = new ResultCache(projectId);
            resultCacheMap.put(projectId, resultCache);
        }
        return resultCache;
    }

    @SuppressWarnings("unchecked")
    public <A extends Action<R>, R extends Result> void execute(A action, final AsyncCallback<R> callback) {
        if(action instanceof HasProjectId) {
            ProjectId projectId = ((HasProjectId) action).getProjectId();
            ResultCache resultCache = getResultCache(projectId);
            Optional<R> result = resultCache.getCachedResult(action);
            if(result.isPresent()) {
                GWT.log("[DISPATCH] Using cached result (" + action + ")");
                callback.onSuccess(result.get());
                return;
            }
        }

        GWT.log("[DISPATCH] Making request to server.  Request " + requestCount + ". (" + action + ")");
        requestCount++;
        async.executeAction(action, new AsyncCallbackProxy(action, callback));
    }


    private class AsyncCallbackProxy<R extends Result> implements AsyncCallback<DispatchServiceResultContainer> {

        private Action<?> action;

        private AsyncCallback<Result> delegate;

        public AsyncCallbackProxy(Action<?> action, AsyncCallback<Result> delegate) {
            this.delegate = delegate;
            this.action = action;
        }

        @Override
        public void onFailure(Throwable caught) {
            Optional<Throwable> passOn = handleError(caught, action);
            if (passOn.isPresent()) {
                delegate.onFailure(passOn.get());
            }
        }

        @Override
        public void onSuccess(DispatchServiceResultContainer result) {
            // TODO: Fix
            if(action instanceof HasProjectId) {
                ResultCache resultCache = getResultCache(((HasProjectId) action).getProjectId());
                resultCache.cacheResult((Action<R>) action, (R) result.getResult());
            }
            cacheRenderables(result.getResult());
            dispatchEvents(result.getResult());
            delegate.onSuccess(result.getResult());

        }

    }


    private void cacheRenderables(Object result) {
        if (result instanceof HasBrowserTextMap) {
            BrowserTextMap browserTextMap = ((HasBrowserTextMap) result).getBrowserTextMap();
            RenderingServiceManager.getManager().registerEntityData(browserTextMap.getOWLEntityData());
        }
    }

    private void dispatchEvents(Object result) {
        if(result instanceof HasEventList<?>) {
            EventList<? extends SerializableEvent<?>> eventList = ((HasEventList<? extends SerializableEvent<?>>) result).getEventList();

            List<? extends SerializableEvent<?>> events = eventList.getEvents();
            // TODO: FIX - Should be dispatched by the project event manager otherwise we will get events from the
            // TODO: more than once!

            for(Event<?> event : events) {
                GWT.log("[DISPATCH] Dispatching event (" + event.toDebugString() + ")");
            }
            EventBusManager.getManager().postEvents(events);
        }
    }

    private Optional<Throwable> handleError(Throwable throwable, Action<?> action) {
        if(throwable instanceof IncompatibleRemoteServiceException) {
            displayAlert("WebProtege has been upgraded.  Please refresh your browser.");
            GWT.log("Incompatible remote service exception", throwable);
            return Optional.absent();
        }
        else if(throwable instanceof InvocationException) {
            if(action instanceof InvocationExceptionTolerantAction) {
                Optional<String> errorMessage = ((InvocationExceptionTolerantAction) action).handleInvocationException((InvocationException) throwable);
                if(errorMessage.isPresent()) {
                    displayAlert(errorMessage.get());
                }
            }
            else {
                displayAlert("There was a problem communicating with the server and the operation could not be completed.  Please check your network connection and try again.");
            }
            return Optional.absent();
        }
        else if(throwable instanceof UmbrellaException) {
            for(Throwable cause : ((UmbrellaException) throwable).getCauses()) {
                if(cause instanceof PermissionDeniedException) {
                    displayAlert("You do not have permission to perform the requested operation.");
                    return Optional.absent();
                }
            }
            displayAlert("An unexpected problem occurred and your actions could not be completed.  Please try again.");
            return Optional.absent();
        }
        else if(throwable instanceof PermissionDeniedException) {
            displayAlert("You do not have permission to carry out the specified action");
            return Optional.of(throwable);
        }
        else {
            return Optional.of(throwable);
        }

    }

    private void displayAlert(String alert) {
        MessageBox.showAlert(alert);
    }
}
TOP

Related Classes of edu.stanford.bmir.protege.web.client.dispatch.DispatchServiceManager$AsyncCallbackProxy

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.