Skip to content

Commit

Permalink
Merge pull request #428 from ArcBees/cv_rest_global_header_params
Browse files Browse the repository at this point in the history
Added customization methods for global Query and Header parameters
  • Loading branch information
Chris-V committed Feb 7, 2014
2 parents b6c8b9e + 588f7f2 commit eb631d8
Show file tree
Hide file tree
Showing 12 changed files with 526 additions and 114 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public class SharedModule extends AbstractPresenterModule {
protected void configure() {
install(new DefaultModule());
install(new SecurityModule());
install(new RestDispatchAsyncModule.Builder().build());
install(new RestDispatchAsyncModule());

// DefaultPlaceManager Places
bindConstant().annotatedWith(DefaultPlace.class).to(NameTokens.login);
Expand Down
12 changes: 12 additions & 0 deletions gwtp-core/gwtp-all/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@
<artifactId>gwtp-dispatch-rpc-server-spring</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>gwtp-mvp-shared</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>gwtp-mvp-client</artifactId>
Expand Down Expand Up @@ -202,6 +207,13 @@
<classifier>sources</classifier>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>gwtp-mvp-shared</artifactId>
<version>${project.version}</version>
<classifier>sources</classifier>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>gwtp-mvp-client</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.gwtplatform.dispatch.rest.client;

import java.util.Collection;
import java.util.List;
import java.util.Map;

Expand All @@ -25,7 +26,9 @@

import com.github.nmorel.gwtjackson.client.exception.JsonMappingException;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestBuilder.Method;
import com.gwtplatform.common.shared.UrlUtils;
Expand Down Expand Up @@ -57,6 +60,8 @@ public class DefaultRestRequestBuilderFactory implements RestRequestBuilderFacto
private final Serialization serialization;
private final HttpRequestBuilderFactory httpRequestBuilderFactory;
private final UrlUtils urlUtils;
private final Multimap<HttpMethod, RestParameter> globalHeaderParams;
private final Multimap<HttpMethod, RestParameter> globalQueryParams;
private final String baseUrl;
private final String securityHeaderName;
private final Integer requestTimeoutMs;
Expand All @@ -66,13 +71,17 @@ public class DefaultRestRequestBuilderFactory implements RestRequestBuilderFacto
Serialization serialization,
HttpRequestBuilderFactory httpRequestBuilderFactory,
UrlUtils urlUtils,
@GlobalHeaderParams Multimap<HttpMethod, RestParameter> globalHeaderParams,
@GlobalQueryParams Multimap<HttpMethod, RestParameter> globalQueryParams,
@RestApplicationPath String baseUrl,
@XsrfHeaderName String securityHeaderName,
@RequestTimeout Integer requestTimeoutMs) {
this.metadataProvider = metadataProvider;
this.serialization = serialization;
this.httpRequestBuilderFactory = httpRequestBuilderFactory;
this.urlUtils = urlUtils;
this.globalHeaderParams = globalHeaderParams;
this.globalQueryParams = globalQueryParams;
this.baseUrl = baseUrl;
this.securityHeaderName = securityHeaderName;
this.requestTimeoutMs = requestTimeoutMs;
Expand All @@ -87,7 +96,7 @@ public <A extends RestAction<?>> RequestBuilder build(A action, String securityT
RequestBuilder requestBuilder = httpRequestBuilderFactory.create(httpMethod, url);
requestBuilder.setTimeoutMillis(requestTimeoutMs);

buildHeaders(requestBuilder, xsrfToken, action.getPath(), action.getHeaderParams());
buildHeaders(requestBuilder, xsrfToken, action);
buildBody(requestBuilder, action);

return requestBuilder;
Expand All @@ -97,38 +106,26 @@ public <A extends RestAction<?>> RequestBuilder build(A action, String securityT
* Encodes the given {@link RestParameter} as a path parameter. The default implementation delegates to
* {@link UrlUtils#encodePathSegment(String)}.
*
* @param value a {@link RestParameter} to encode.
* @param value the value to encode.
* @return the encoded path parameter.
* @throws ActionException if an exception occurred while encoding the path parameter.
* @see #encode(com.gwtplatform.dispatch.rest.shared.RestParameter)
*/
protected String encodePathParam(RestParameter value) throws ActionException {
return urlUtils.encodePathSegment(value.getStringValue());
protected String encodePathParam(String value) throws ActionException {
return urlUtils.encodePathSegment(value);
}

/**
* Encodes the given {@link RestParameter} as a query parameter. The default implementation delegates to
* {@link UrlUtils#encodeQueryString(String)}.
*
* @param value a {@link RestParameter} to encode.
* @param value the value to encode.
* @return the encoded query parameter.
* @throws ActionException if an exception occurred while encoding the query parameter.
* @see #encode(com.gwtplatform.dispatch.rest.shared.RestParameter)
*/
protected String encodeQueryParam(RestParameter value) throws ActionException {
return urlUtils.encodeQueryString(value.getStringValue());
}

/**
* Encodes the given {@link RestParameter} as a header parameter. The default implementation returns the string
* value directly without any encoding.
*
* @param value a {@link RestParameter} to encode.
* @return the encoded header parameter.
* @throws ActionException if an exception occurred while encoding the header parameter.
*/
protected String encodeHeaderParam(RestParameter value) throws ActionException {
return value.getStringValue();
protected String encodeQueryParam(String value) throws ActionException {
return urlUtils.encodeQueryString(value);
}

/**
Expand All @@ -153,9 +150,15 @@ protected String serialize(Object object, String bodyType) {
return serialization.serialize(object, bodyType);
}

private void buildHeaders(RequestBuilder requestBuilder, String xsrfToken, String path,
List<RestParameter> customHeaders) throws ActionException {
private void buildHeaders(RequestBuilder requestBuilder, String xsrfToken, RestAction<?> action)
throws ActionException {
String path = action.getPath();
List<RestParameter> actionParams = action.getHeaderParams();
Collection<RestParameter> applicableGlobalParams = globalHeaderParams.get(action.getHttpMethod());

// By setting the most generic headers first, we make sure they can be overridden by more specific ones
requestBuilder.setHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON);
requestBuilder.setHeader(HttpHeaders.CONTENT_TYPE, JSON_UTF8);

if (!isAbsoluteUrl(path)) {
requestBuilder.setHeader(MODULE_BASE_HEADER, baseUrl);
Expand All @@ -165,12 +168,16 @@ private void buildHeaders(RequestBuilder requestBuilder, String xsrfToken, Strin
requestBuilder.setHeader(securityHeaderName, xsrfToken);
}

for (RestParameter param : customHeaders) {
requestBuilder.setHeader(param.getName(), encodeHeaderParam(param));
for (RestParameter parameter : applicableGlobalParams) {
String value = parameter.getStringValue();

if (value != null) {
requestBuilder.setHeader(parameter.getName(), value);
}
}

if (requestBuilder.getHeader(HttpHeaders.CONTENT_TYPE) == null) {
requestBuilder.setHeader(HttpHeaders.CONTENT_TYPE, JSON_UTF8);
for (RestParameter param : actionParams) {
requestBuilder.setHeader(param.getName(), param.getStringValue());
}
}

Expand All @@ -182,20 +189,37 @@ private <A extends RestAction<?>> void buildBody(RequestBuilder requestBuilder,
}
}

private String buildUrl(RestAction<?> restAction) throws ActionException {
String queryString = buildQueryString(restAction.getQueryParams());
private String buildUrl(RestAction<?> action) throws ActionException {
List<RestParameter> queryParams = getGlobalQueryParamsForAction(action);
queryParams.addAll(action.getQueryParams());

String queryString = buildQueryString(queryParams);
if (!queryString.isEmpty()) {
queryString = "?" + queryString;
}

String path = buildPath(restAction.getPath(), restAction.getPathParams());
String path = buildPath(action.getPath(), action.getPathParams());

if (isAbsoluteUrl(path)) {
return path + queryString;
} else {
return baseUrl + path + queryString;
String prefix = "";
if (!isAbsoluteUrl(path)) {
prefix = baseUrl;
}

return prefix + path + queryString;
}

private List<RestParameter> getGlobalQueryParamsForAction(RestAction<?> action) {
List<RestParameter> queryParams = Lists.newArrayList();

for (RestParameter parameter : globalQueryParams.get(action.getHttpMethod())) {
String value = parameter.getStringValue();

if (value != null) {
queryParams.add(new RestParameter(parameter.getName(), value));
}
}

return queryParams;
}

private boolean isAbsoluteUrl(String path) {
Expand All @@ -206,7 +230,8 @@ private String buildPath(String rawPath, List<RestParameter> params) throws Acti
String path = rawPath;

for (RestParameter param : params) {
path = path.replace("{" + param.getName() + "}", encodePathParam(param));
String encodedParam = encodePathParam(param.getStringValue());
path = path.replace("{" + param.getName() + "}", encodedParam);
}

return path;
Expand All @@ -219,7 +244,7 @@ private String buildQueryString(List<RestParameter> params) throws ActionExcepti
queryString.append("&")
.append(param.getName())
.append("=")
.append(encodeQueryParam(param));
.append(encodeQueryParam(param.getStringValue()));
}

if (queryString.length() != 0) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* Copyright 2014 ArcBees 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.gwtplatform.dispatch.rest.client;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import com.google.inject.BindingAnnotation;

/**
* The timeout in milliseconds to use on for {@link com.google.gwt.http.client.RequestBuilder RequestBuilder}.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})
@BindingAnnotation
public @interface GlobalHeaderParams {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* Copyright 2014 ArcBees 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.gwtplatform.dispatch.rest.client;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import com.google.inject.BindingAnnotation;

/**
* The timeout in milliseconds to use on for {@link com.google.gwt.http.client.RequestBuilder RequestBuilder}.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})
@BindingAnnotation
public @interface GlobalQueryParams {
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
* The timeout in milliseconds to use on for {@link com.google.gwt.http.client.RequestBuilder RequestBuilder}.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})
@BindingAnnotation
public @interface RequestTimeout {
}

0 comments on commit eb631d8

Please sign in to comment.