| /* |
| * Copyright 2009 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.user.client.rpc; |
| |
| import com.google.gwt.core.client.GWT; |
| import com.google.gwt.http.client.RequestBuilder; |
| import com.google.gwt.http.client.RequestCallback; |
| |
| /** |
| * This class encapsulates the logic necessary to configure a RequestBuilder for |
| * use with an RPC proxy object. Users who wish to alter the specifics of the |
| * HTTP requests issued by RPC proxy objects may override the protected |
| * <code>doXyz</code> methods and pass an instance of the subclass to |
| * {@link ServiceDefTarget#setRpcRequestBuilder}. |
| */ |
| public class RpcRequestBuilder { |
| /** |
| * Used by {@link #doSetContentType}. |
| */ |
| public static final String CONTENT_TYPE_HEADER = "Content-Type"; |
| |
| /** |
| * Used by {@link #doFinish}. |
| */ |
| /* |
| * NB: Also used by RpcServlet. |
| */ |
| public static final String MODULE_BASE_HEADER = "X-GWT-Module-Base"; |
| |
| /** |
| * Used by {@link #doFinish}. |
| */ |
| /* |
| * NB: Also used by AbstractRemoteServiceServlet. |
| */ |
| public static final String STRONG_NAME_HEADER = "X-GWT-Permutation"; |
| |
| /** |
| * Not exposed directly to the subclass. |
| */ |
| private RequestBuilder builder; |
| |
| /** |
| * Initialize the RpcRequestBuilder. This method must be called before any of |
| * the other methods in this class may be called. Calling <code>create</code> |
| * before calling {@link #finish()} will reset the state of the |
| * RpcRequestBuilder. |
| * <p> |
| * This method delegates to {@link #doCreate} to instantiate the |
| * RequestBuilder. |
| * |
| * @param serviceEntryPoint The URL entry point |
| * @return <code>this</code> |
| * @see ServiceDefTarget#setServiceEntryPoint(String) |
| */ |
| public final RpcRequestBuilder create(String serviceEntryPoint) { |
| builder = doCreate(serviceEntryPoint); |
| assert builder != null : "doCreate failed to return a RequestBuilder"; |
| return this; |
| } |
| |
| /** |
| * This method must be called to return the RequestBuilder that the RPC |
| * request will be made with. |
| * <p> |
| * This method will call {@link #doFinish} before returning the current |
| * RequestBuilder. |
| */ |
| public final RequestBuilder finish() { |
| try { |
| assert builder != null : "Call create() first"; |
| doFinish(builder); |
| return builder; |
| } finally { |
| builder = null; |
| } |
| } |
| |
| /** |
| * Sets the RequestCallback to be used by the RequestBuilder. Delegates to |
| * {@link #doSetCallback}. |
| * |
| * @param callback the RequestCallback to be used by the RequestBuilder |
| * @return <code>this</code> |
| */ |
| public final RpcRequestBuilder setCallback(RequestCallback callback) { |
| assert builder != null : "Call create() first"; |
| doSetCallback(builder, callback); |
| return this; |
| } |
| |
| /** |
| * Sets the MIME content type to be used by the RequestBuilder. Delegates to |
| * {@link #doSetContentType}. |
| * |
| * @param contentType the MIME content type to be used in the request |
| * @return <code>this</code> |
| */ |
| public final RpcRequestBuilder setContentType(String contentType) { |
| assert builder != null : "Call create() first"; |
| doSetContentType(builder, contentType); |
| return this; |
| } |
| |
| /** |
| * Sets the request data to be sent in the request. Delegates to |
| * {@link #doSetRequestData}. |
| * |
| * @param data the data to send |
| * @return <code>this</code> |
| */ |
| public final RpcRequestBuilder setRequestData(String data) { |
| assert builder != null : "Call create() first"; |
| doSetRequestData(builder, data); |
| return this; |
| } |
| |
| /** |
| * Sets the request id of the request. Delegates to {@link #doSetRequestId}. |
| * |
| * @param id the issue number of the request |
| * @return <code>this</code> |
| */ |
| public final RpcRequestBuilder setRequestId(int id) { |
| assert builder != null : "Call create() first"; |
| doSetRequestId(builder, id); |
| return this; |
| } |
| |
| /** |
| * Called by {@link #create} to instantiate the RequestBuilder object. |
| * <p> |
| * The default implementation creates a <code>POST</code> RequestBuilder with |
| * the given entry point. |
| * |
| * @param serviceEntryPoint the URL to which the request should be issued |
| * @return the RequestBuilder that should be ultimately passed to the |
| * RpcRequestBuilder's caller. |
| */ |
| protected RequestBuilder doCreate(String serviceEntryPoint) { |
| return new RequestBuilder(RequestBuilder.POST, serviceEntryPoint); |
| } |
| |
| /** |
| * Called by {@link #finish()} prior to returning the RequestBuilder to the |
| * caller. |
| * <p> |
| * The default implementation sets the {@value #STRONG_NAME_HEADER} header to |
| * the value returned by {@link GWT#getPermutationStrongName()}. |
| * |
| * @param rb The RequestBuilder that is currently being configured |
| */ |
| protected void doFinish(RequestBuilder rb) { |
| rb.setHeader(STRONG_NAME_HEADER, GWT.getPermutationStrongName()); |
| rb.setHeader(MODULE_BASE_HEADER, GWT.getModuleBaseURL()); |
| } |
| |
| /** |
| * Called by {@link #setCallback}. |
| * <p> |
| * The default implementation calls |
| * {@link RequestBuilder#setCallback(RequestCallback)}. |
| * |
| * @param rb the RequestBuilder that is currently being configured |
| * @param callback the user-provided callback |
| */ |
| protected void doSetCallback(RequestBuilder rb, RequestCallback callback) { |
| rb.setCallback(callback); |
| } |
| |
| /** |
| * Called by {@link #setContentType}. |
| * <p> |
| * The default implementation sets the {@value #CONTENT_TYPE_HEADER} header to |
| * the value specified by <code>contentType</code> by calling |
| * {@link RequestBuilder#setHeader(String, String)}. |
| * |
| * @param rb the RequestBuilder that is currently being configured |
| * @param contentType the desired MIME type of the request's contents |
| */ |
| protected void doSetContentType(RequestBuilder rb, String contentType) { |
| rb.setHeader(CONTENT_TYPE_HEADER, contentType); |
| } |
| |
| /** |
| * Called by {@link #setRequestData}. |
| * <p> |
| * The default implementation invokes |
| * {@link RequestBuilder#setRequestData(String)}. |
| * |
| * @param rb the RequestBuilder that is currently being configured |
| * @param data the data to send |
| */ |
| protected void doSetRequestData(RequestBuilder rb, String data) { |
| rb.setRequestData(data); |
| } |
| |
| /** |
| * Called by {@link #setRequestId}. |
| * <p> |
| * The default implementation is a no-op. |
| * |
| * @param rb the RequestBuilder that is currently being configured |
| * @param id the request's issue id |
| */ |
| protected void doSetRequestId(RequestBuilder rb, int id) { |
| } |
| } |