/******************************************************************************* * * Copyright 2011-2014 Spiffy UI Team * * 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 org.spiffyui.client.rest; import java.util.HashMap; import java.util.Map; import com.google.gwt.json.client.JSONParser; import com.google.gwt.json.client.JSONValue; /** * <p> * This Java Bean provides options for making REST calls. * </p> * * <p> * All of the <code>set</code> methods in this bean support chaining so * it is possible to call <code>new RESTOptions().setURL("/api/foo").setCallback(this)</code>. * </p> */ public final class RESTOptions { /* the properly encoded REST url to call */ private String m_url; /* the data to pass to the URL */ private String m_data; /* the HTTP method, defaults to GET */ private RESTility.HTTPMethod m_method = RESTility.GET; /* the callback object for handling the request results */ private RESTCallback m_callback; /* true if this is a request to login and false otherwise */ private boolean m_isLoginRequest = false; /* true if this request should repeat after a login request if this request returns a 401 */ private boolean m_shouldReplay = true; /* the option etag for this request; */ private String m_etag; /* * the content type for this request */ private String m_contentType = "application/json"; /* a map containing the headers to the HTTP request. Any item in this map will override the default headers. */ private Map<String, String> m_headers = new HashMap<String, String>(); /** * Get the URL for this REST request. * * @return the full URL for this REST request including all parameters */ public String getURL() { return m_url; } /** * Set the URL for this REST request. * * @param url the full URL for the request including all parameters * * @return the RESTOptions bean for method chaining */ public RESTOptions setURL(String url) { m_url = url; return this; } /** * <p> * Get the JSON data sent to the server during the REST request. * </p> * * <p> * JSON data can only be passed for POST and PUT requests and will be ignored for all * other request methods. * </p> * * @return the JSON data for this request */ public JSONValue getData() { if (m_data == null) { return null; } else { return JSONParser.parseStrict(m_data); } } /** * <p> * Get the JSON data sent to the server during the REST request as a string. * </p> * * @return the JSON data for this request as a string */ public String getDataString() { if (m_data != null) { return m_data.toString(); } else { return ""; } } /** * <p> * Set the data for this REST request. * </p> * * <p> * JSON data can only be passed for POST and PUT requests and will be ignored for all * other request methods. * </p> * * @param data the data to send to the server with this request * * @return the RESTOptions bean for method chaining */ public RESTOptions setData(JSONValue data) { if (data != null) { m_data = data.toString(); } else { m_data = null; } return this; } /** * <p> * Set the data for this REST request as a string. * </p> * * <p> * Data can only be passed for POST and PUT requests and will be ignored for all * other request methods. If this data isn't JSON you must call setContentType * to set the correct content type for your data. * </p> * * @param data the data to send to the server with this request * * @return the RESTOptions bean for method chaining */ public RESTOptions setDataString(String data) { m_data = data; return this; } /** * Get the content type for this REST request. The default is application/json * * @return the content type */ public String getContentType() { return m_contentType; } /** * Set the content type for this request. * * @param contentType * the content type to use * * @return the RESTOptions bean for method chaining */ public RESTOptions setContentType(String contentType) { m_contentType = contentType; return this; } /** * Get the method of this REST request. * * @return the REST request method */ public RESTility.HTTPMethod getMethod() { return m_method; } /** * Set the REST request method. * * @param method the HTTP method for this REST request * * @return the RESTOptions bean for method chaining */ public RESTOptions setMethod(RESTility.HTTPMethod method) { m_method = method; return this; } /** * Get the callback for when this request is completed. * * @return the callback for this REST request */ public RESTCallback getCallback() { return m_callback; } /** * Set the callback for this REST request. * * @param callback the REST request callback * * @return the RESTOptions bean for method chaining */ public RESTOptions setCallback(RESTCallback callback) { m_callback = callback; return this; } /** * <p> * Set if this request is a login request or not. * </p> * * <p> * When the server returns a 401 as the response to a REST request and the application * is following the Spiffy UI authentication recommendations then RESTility will handle * the authentication and part of that authentication includes making further REST requests * for the login. Those requests are handled specially since they are part of the * authentication exchange. * </p> * * <p> * By default this value is false. This value should only be true if this request is * part of the login for a custom authentication handler. * </p> * * @return true if this is a login request and false otherwise */ public boolean isLoginRequest() { return m_isLoginRequest; } /** * Set this REST request as a login request. The default is false. * * @param isLoginRequest * true if this is a login request and false otherwise * * @return the RESTOptions bean for method chaining */ public RESTOptions setIsLoginRequest(boolean isLoginRequest) { m_isLoginRequest = isLoginRequest; return this; } /** * <p> * Set if this REST request should be replayed. * </p> * * <p> * When the client makes a REST request which results in a 401 RESTility must perform * authentication and get a token before it can continue with the request. After the * authentication completes successfully RESTility replays the original request and any * requests which have come in during the authentication process so they can complete * for the calling code transparent of any authentication requirements. * </p> * * <p> * This value controls if the request should replay in that case. The default is true. * </p> * * @return the RESTOptions bean for method chaining */ public boolean shouldReplay() { return m_shouldReplay; } /** * <p> * Set if this REST request should be replayed. * </p> * * <p> * When the client makes a REST request which results in a 401 RESTility must perform * authentication and get a token before it can continue with the request. After the * authentication completes successfully RESTility replays the original request and any * requests which have come in during the authentication process so they can complete * for the calling code transparent of any authentication requirements. * </p> * * <p> * This value controls if the request should replay in that case. The default is true. * </p> * * @param shouldReplay * true if the request should replay and false otherwise * * @return the RESTOptions bean for method chaining */ public RESTOptions setShouldReplay(boolean shouldReplay) { m_shouldReplay = shouldReplay; return this; } /** * Get the etag for this REST request. * * @return the etag for this request */ public String getEtag() { return m_etag; } /** * <p> * Set the etag for this REST request. * </p> * * <p> * Etags are a common mechanism for handling concurrency checking and RESTility handles * them specially since they are part of the built in Spiffy UI optimistic concurrency * mechanism. * </p> * * <p> * The ETag set in this method will override the <code>If-Match</code> set in the headers * map if it is present. * </p> * * <p> * For more information see * <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.19">HTTP 1.1 header field definitions sections 14.19</a>. * </p> * * @param etag the etag for this request * * @return the RESTOptions bean for method chaining * @see ConcurrentRESTCallback */ public RESTOptions setEtag(String etag) { m_etag = etag; return this; } /** * <p> * Set the HTTP headers map for this request. * </p> * * @return the map of HTTP headers * @see setEtag * @see getEtag */ public Map<String, String> getHeaders() { return m_headers; } /** * <p> * Set the HTTP headers for this REST request. * </p> * * <p> * This method gives a client the option to specify defined and custom HTTP headers * for the request request. These headers will override all values except for the * following headers: * </p> * * <ul> * <li><code>Accept-Language</code> - always set to the preferred language from GWT</li> * <li><code>Authorization</code> - set with the authentication token from the * authentication provider</li> * <li><code>TS-URL</code> - this custom token is set to the token server URL from * the authenciation provider.</li> * <li><code>If-Match</code> - set with the value from the ETag</li> * <li><code>Content-Type</code> - always sets the content type to the value from the * setContentType method. * </ul> * * @param headers the HTTP headers for this REST request * * @return the RESTOptions bean for method chaining */ public RESTOptions setHeaders(Map<String, String> headers) { if (headers != null) { m_headers.putAll(headers); } return this; } }