Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added customization methods for global Query and Header parameters #428

Merged
merged 8 commits into from
Feb 7, 2014
Merged
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 {
}