| /* |
| * Copyright 2010 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.requestfactory.client; |
| |
| import static com.google.gwt.user.client.rpc.RpcRequestBuilder.STRONG_NAME_HEADER; |
| |
| import com.google.gwt.core.client.GWT; |
| import com.google.gwt.event.shared.EventBus; |
| 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.requestfactory.shared.RequestEvent; |
| import com.google.gwt.requestfactory.shared.RequestFactory; |
| import com.google.gwt.requestfactory.shared.RequestTransport; |
| import com.google.gwt.requestfactory.shared.RequestEvent.State; |
| import com.google.gwt.user.client.Window.Location; |
| |
| import java.util.logging.Level; |
| import java.util.logging.Logger; |
| |
| /** |
| * An implementation of {@link RequestTransport} that uses a |
| * {@link RequestBuilder}. |
| */ |
| public class DefaultRequestTransport implements RequestTransport { |
| |
| /** |
| * The default URL for a DefaultRequestTransport is |
| * <code>{@link GWT#getHostPageBaseURL()} + {@value #URL}</code> which may be |
| * overridden by calling {@link #setRequestUrl(String)}. |
| */ |
| public static final String URL = "gwtRequest"; |
| |
| /* |
| * A separate logger for wire activity, which does not get logged by the |
| * remote log handler, so we avoid infinite loops. All log messages that could |
| * happen every time a request is made from the server should be logged to |
| * this logger. |
| */ |
| private static Logger wireLogger = Logger.getLogger("WireActivityLogger"); |
| private static final String SERVER_ERROR = "Server Error"; |
| |
| private final EventBus eventBus; |
| private String requestUrl = GWT.getHostPageBaseURL() + URL; |
| |
| /** |
| * Construct a DefaultRequestTransport. |
| * |
| * @param eventBus the same EventBus passed into {@link RequestFactory#init}. |
| */ |
| public DefaultRequestTransport(EventBus eventBus) { |
| if (eventBus == null) { |
| throw new IllegalArgumentException("eventBus must not be null"); |
| } |
| this.eventBus = eventBus; |
| } |
| |
| /** |
| * Returns the current URL used by this transport. |
| */ |
| public String getRequestUrl() { |
| return requestUrl; |
| } |
| |
| public void send(String payload, TransportReceiver receiver) { |
| RequestBuilder builder = createRequestBuilder(); |
| configureRequestBuilder(builder); |
| |
| builder.setRequestData(payload); |
| builder.setCallback(createRequestCallback(receiver)); |
| |
| try { |
| wireLogger.finest("Sending fire request"); |
| builder.send(); |
| postRequestEvent(State.SENT, null); |
| } catch (RequestException e) { |
| wireLogger.log(Level.SEVERE, SERVER_ERROR + " (" + e.getMessage() + ")", |
| e); |
| } |
| } |
| |
| /** |
| * Override the default URL used by this transport. |
| */ |
| public void setRequestUrl(String url) { |
| this.requestUrl = url; |
| } |
| |
| /** |
| * Override to change the headers sent in the HTTP request. |
| */ |
| protected void configureRequestBuilder(RequestBuilder builder) { |
| builder.setHeader("Content-Type", RequestFactory.JSON_CONTENT_TYPE_UTF8); |
| builder.setHeader("pageurl", Location.getHref()); |
| builder.setHeader(STRONG_NAME_HEADER, GWT.getPermutationStrongName()); |
| } |
| |
| /** |
| * Constructs a RequestBuilder using the {@link RequestBuilder#POST} method |
| * sent to the URL returned from {@link #getRequestUrl()}. |
| */ |
| protected RequestBuilder createRequestBuilder() { |
| return new RequestBuilder(RequestBuilder.POST, getRequestUrl()); |
| } |
| |
| /** |
| * Creates a RequestCallback that maps the HTTP response onto the |
| * {@link TransportReceiver} interface. |
| */ |
| protected RequestCallback createRequestCallback( |
| final TransportReceiver receiver) { |
| return new RequestCallback() { |
| |
| public void onError(Request request, Throwable exception) { |
| postRequestEvent(State.RECEIVED, null); |
| wireLogger.log(Level.SEVERE, SERVER_ERROR, exception); |
| receiver.onTransportFailure(exception.getMessage()); |
| } |
| |
| public void onResponseReceived(Request request, Response response) { |
| wireLogger.finest("Response received"); |
| try { |
| if (200 == response.getStatusCode()) { |
| String text = response.getText(); |
| receiver.onTransportSuccess(text); |
| } else if (Response.SC_UNAUTHORIZED == response.getStatusCode()) { |
| String message = "Need to log in"; |
| wireLogger.finest(message); |
| receiver.onTransportFailure(message); |
| } else if (response.getStatusCode() > 0) { |
| /* |
| * During the redirection for logging in, we get a response with no |
| * status code, but it's not an error, so we only log errors with |
| * bad status codes here. |
| */ |
| String message = SERVER_ERROR + " " + response.getStatusCode() |
| + " " + response.getText(); |
| wireLogger.severe(message); |
| receiver.onTransportFailure(message); |
| } |
| } finally { |
| postRequestEvent(State.RECEIVED, response); |
| } |
| } |
| }; |
| } |
| |
| private void postRequestEvent(State received, Response response) { |
| eventBus.fireEvent(new RequestEvent(received, response)); |
| } |
| } |