/* * Copyright (c) 2008 TouK.pl * 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 pl.touk.wonderfulsecurity.gwt.client.rpc; import com.google.gwt.core.client.RunAsyncCallback; import com.google.gwt.http.client.Request; import com.google.gwt.http.client.RequestBuilder; import com.google.gwt.http.client.RequestCallback; import com.google.gwt.http.client.RequestException; import com.google.gwt.http.client.Response; import com.google.gwt.core.client.GWT; import java.util.AbstractQueue; import java.util.ArrayList; import java.util.Iterator; import com.google.gwt.user.client.Window; import pl.touk.wonderfulsecurity.gwt.client.ui.ServerCommunicationInfo; /** * * @author Michał Zalewski mzl@touk.pl */ public class RpcExecutor { private static ServerCommunicationQueue messageQueue = new ServerCommunicationQueue(); private static final String message = "Proszę czekać..."; private static IRpcErrorHandler errorHandler; public static void execute(RequestBuilder rb, final boolean displayCommunicationStatus) { final RequestCallback originalCallback = rb.getCallback(); /** * Using default message */ if (displayCommunicationStatus) { showServerCommunication(message); messageQueue.add(message); } /** * Replacing callback, to be able to get login page location from HTTP header */ rb.setCallback(new RequestCallback() { public void onResponseReceived(Request request, Response response) { String header = response.getHeader("loginPage"); if (header != null && header.length() > 0) { Redirect.redirect(header); } if (displayCommunicationStatus) { refreshUserMessage(); } originalCallback.onResponseReceived(request, response); } public void onError(Request request, Throwable exception) { if (displayCommunicationStatus) { refreshUserMessage(); } if (errorHandler != null) { errorHandler.handleError(request, exception); } originalCallback.onError(request, exception); } }); try { rb.send(); } catch (RequestException ex) { if (errorHandler != null) { errorHandler.handleError(ex); } } } protected static void showServerCommunication(final String message) { changeServerCommunicationStatusAsync(message, true); } protected static void hideServerCommunication() { changeServerCommunicationStatusAsync(null, false); } private static void changeServerCommunicationStatusAsync(final String message, final boolean show) { GWT.runAsync(new RunAsyncCallback() { public void onFailure(Throwable throwable) { Window.alert("Nie można załadować modułu runasync dla CommunitactionInfo"); } public void onSuccess() { if (show) { ServerCommunicationInfo.show(message); } else { ServerCommunicationInfo.hide(); } } }); } public static void execute(RequestBuilder rb) { execute(rb,true); } /** * Sets rpc exception handler for handling exceptions from failed request * sending and thrown during RPC call. * @param handler * @see RequestBuilder#send() * @see RequestCallback#onError(com.google.gwt.http.client.Request, java.lang.Throwable) */ public static void setErrorHandler(IRpcErrorHandler handler) { errorHandler = handler; } static void refreshUserMessage() { String message = (String) messageQueue.poll(); if (!messageQueue.isEmpty()) { showServerCommunication(message); } else { hideServerCommunication(); } } } class ServerCommunicationQueue extends AbstractQueue { protected ArrayList content = new ArrayList(); public Iterator iterator() { return content.iterator(); } public int size() { return content.size(); } public boolean offer(Object o) { content.add(0, o); return true; } public Object poll() { return content.remove(0); } public Object peek() { return content.get(0); } }