initial creation of the wsf project.

This commit is contained in:
Inderjeet Singh 2008-09-01 13:37:34 +00:00
parent 1e5f1740cd
commit 849612c50f
37 changed files with 2447 additions and 0 deletions

190
wsf/pom.xml Executable file
View File

@ -0,0 +1,190 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.google.code.gson</groupId>
<artifactId>wsf</artifactId>
<packaging>jar</packaging>
<version>0.1</version>
<name>Gson Web Service Framework</name>
<description>A Framework for JSON based Web-services</description>
<distributionManagement>
<repository>
<id>local.repo</id>
<name>file repository to svn</name>
<url>file://${basedir}/../../mavenrepo</url>
</repository>
</distributionManagement>
<repositories>
<repository>
<id>gson</id>
<url>http://google-gson.googlecode.com/svn/mavenrepo</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<scm>
<connection>scm:svn:http://google-gson.googlecode.com/svn/trunk/wsf</connection>
<developerConnection>scm:svn:https://google-gson.googlecode.com/svn/trunk/wsf</developerConnection>
<url>http://google-gson.codegoogle.com/svn/trunk/wsf</url>
</scm>
<issueManagement>
<system>Google Code Issue Tracking</system>
<url>http://code.google.com/p/google-gson/issues/list</url>
</issueManagement>
<dependencies>
<!-- Google collections -->
<dependency>
<groupId>com.google.code.google-collections</groupId>
<artifactId>google-collect</artifactId>
<version>snapshot-20080530</version>
<scope>compile</scope>
</dependency>
<!-- Gson: Java to Json conversion -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>1.2</version>
<scope>compile</scope>
</dependency>
<!-- Guice: Dependency injection -->
<dependency>
<groupId>com.google.code.guice</groupId>
<artifactId>guice</artifactId>
<version>1.0</version>
<scope>compile</scope>
</dependency>
<!-- Servlet & Jsp -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>wsf</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<downloadSources>true</downloadSources>
<downloadJavadocs>true</downloadJavadocs>
<workspace>../eclipse-ws</workspace>
<workspaceCodeStylesURL>file:///${basedir}/../lib/gson-formatting-styles.xml</workspaceCodeStylesURL>
<wtpversion>1.5</wtpversion>
</configuration>
</plugin>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.0.1</version>
<configuration>
<scanIntervalSeconds>10</scanIntervalSeconds>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jxr-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<links>
<link>http://java.sun.com/j2se/1.5.0/docs/api/</link>
</links>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<configuration>
<targetJdk>1.5</targetJdk>
<rulesets>
<ruleset>/rulesets/basic.xml</ruleset>
<ruleset>/rulesets/imports.xml</ruleset>
<ruleset>/rulesets/unusedcode.xml</ruleset>
<ruleset>/rulesets/finalizers.xml</ruleset>
</rulesets>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<configuration>
<!-- configLocation>config/sun_checks.xml</configLocation -->
<configLocation>config/maven_checks.xml</configLocation>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>taglist-maven-plugin</artifactId>
<configuration>
<tags>
<tag>TODO</tag>
<tag>@todo</tag>
<tag>FIXME</tag>
<tag>XXX</tag>
</tags>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<executions>
<execution>
<id>clean</id>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<configuration>
<arguments>-DenableCiProfile=true</arguments>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,64 @@
/*
* Copyright (C) 2008 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.gson.wsf;
/**
* Encapsulation of a Web service path that is sent by the client.
*
* @author inder
*/
public final class CallPath {
private final String path;
public CallPath(String path) {
this.path = path;
}
public String get() {
return path;
}
@Override
public int hashCode() {
return path.hashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
CallPath other = (CallPath) obj;
if (path == null && other.path != null) {
return false;
} else if (!path.equals(other.path)) {
return false;
}
return true;
}
@Override
public String toString() {
return path;
}
}

View File

@ -0,0 +1,78 @@
/*
* Copyright (C) 2008 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.gson.wsf;
import java.util.Map;
import com.google.common.collect.Maps;
/**
* A generic Map of calls with relative path where the call is available as the key.
*
* @author inder
*
* @param <T> The target of the call path.
*/
public final class CallPathMap<T> {
public static class Builder<T> {
private final Map<CallPath, T> contents = Maps.newHashMap();
private final T nullValue;
public Builder(T nullValue) {
this.nullValue = nullValue;
}
public <R extends T> Builder<T> put(CallPath path, R content) {
contents.put(path, content);
return this;
}
public CallPathMap<T> create() {
return new CallPathMap<T>(contents, nullValue);
}
}
private final Map<CallPath, T> contents;
private final T nullValue;
private CallPathMap(Map<CallPath, T> contents, T nullValue) {
this.contents = contents;
this.nullValue = nullValue;
}
public T get(CallPath path) {
T content = contents.get(path);
return content == null ? nullValue : content;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("{");
boolean first = true;
for (Map.Entry<CallPath, T> entry : contents.entrySet()) {
if (first) {
first = false;
} else {
sb.append(",");
}
CallPath path = entry.getKey();
sb.append(path.get()).append(":");
sb.append(entry.getValue().toString());
}
sb.append("}");
return sb.toString();
}
}

View File

@ -0,0 +1,83 @@
/*
* Copyright (C) 2008 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.gson.wsf;
import java.lang.reflect.Type;
import java.util.Map;
import java.util.Set;
import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;
/**
* Body of a request or response. The body contains a map of name-value pairs.
* There is a {@link ContentBodySpec} associated with the body as well and only the name-value
* pairs consistent with the specification are permitted.
*
* @author inder
*/
class ContentBody {
protected final ContentBodySpec spec;
protected final Map<String, Object> contents;
ContentBody(ContentBodySpec spec) {
this.spec = spec;
this.contents = Maps.newLinkedHashMap();
}
ContentBody(ContentBodySpec spec, Map<String, Object> contents) {
this.spec = spec;
this.contents = contents;
}
public ContentBodySpec getSpec() {
return spec;
}
@SuppressWarnings("unchecked")
public <T> T get(String key, Class<T> classOfValue) {
Preconditions.checkArgument(spec.isCompatible(key, classOfValue));
return (T) contents.get(key);
}
@SuppressWarnings("unchecked")
public <T> T get(String key, Type typeOfValue) {
Preconditions.checkArgument(spec.isCompatible(key, typeOfValue));
return (T) contents.get(key);
}
public Set<Map.Entry<String, Object>> entrySet() {
return contents.entrySet();
}
public int size() {
return contents.size();
}
public String getContentType() {
return spec.getContentType();
}
public String getCharacterEncoding() {
return spec.getCharacterEncoding();
}
@Override
public String toString() {
return Util.toStringMap(contents);
}
}

View File

@ -0,0 +1,71 @@
/*
* Copyright (C) 2008 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.gson.wsf;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
/**
* Base class for the specification of a {@link ContentBody}.
*
* @author inder
*/
class ContentBodySpec implements ParamMapSpec {
public static final String JSON_CONTENT_TYPE = "application/json";
private static final String JSON_CHARACTER_ENCODING = "utf-8";
private final Map<String, Type> paramsSpec;
protected ContentBodySpec(Map<String, Type> paramsSpec) {
this.paramsSpec = Collections.unmodifiableMap(paramsSpec);
}
public Type getTypeFor(String paramName) {
return paramsSpec.get(paramName);
}
public boolean isCompatible(String paramName, Type type) {
return type.equals(getTypeFor(paramName));
}
public boolean isCompatible(String paramName, Object object) {
return isCompatible(paramName, object.getClass());
}
public Set<Map.Entry<String, Type>> entrySet() {
return paramsSpec.entrySet();
}
public int size() {
return paramsSpec.size();
}
public String getContentType() {
return JSON_CONTENT_TYPE;
}
public String getCharacterEncoding() {
return JSON_CHARACTER_ENCODING;
}
@Override
public String toString() {
return Util.toStringMapKeys(paramsSpec);
}
}

View File

@ -0,0 +1,81 @@
/*
* Copyright (C) 2008 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.gson.wsf;
import java.lang.reflect.Type;
import java.util.Map;
import java.util.Set;
import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;
/**
* Map of request or response header objects. There is a {@link HeaderMapSpec} associated with the
* map as well and only those headers are allowed that are consistent with the specification.
*
* @author inder
*/
public final class HeaderMap {
private final Map<String, Object> contents;
private final HeaderMapSpec spec;
public HeaderMap(HeaderMapSpec spec) {
this.spec = spec;
contents = Maps.newHashMap();
}
/**
* If paramValue is a generic type, use {@link #put(String, Object, Type)} instead.
*
* @param headerName
* @param headerValue
*/
public void put(String headerName, Object headerValue) {
Preconditions.checkArgument(spec.isCompatible(headerName, headerValue));
contents.put(headerName, headerValue);
}
public void put(String headerName, Object headerValue, Type typeOfHeaderValue) {
Preconditions.checkArgument(spec.isCompatible(headerName, typeOfHeaderValue));
contents.put(headerName, headerValue);
}
public HeaderMapSpec getSpec() {
return spec;
}
public Object get(String headerName) {
return contents.get(headerName);
}
public Type getSpec(String headerName) {
return spec.getTypeFor(headerName);
}
public Set<Map.Entry<String, Object>> entrySet() {
return contents.entrySet();
}
public int size() {
return contents.size();
}
@Override
public String toString() {
return Util.toStringMap(contents);
}
}

View File

@ -0,0 +1,80 @@
/*
* Copyright (C) 2008 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.gson.wsf;
import java.lang.reflect.Type;
import java.util.Map;
import java.util.Set;
import com.google.common.collect.Maps;
/**
* Specification of a header map for {@link HeaderMap}.
*
* @author inder
*/
public final class HeaderMapSpec implements ParamMapSpec {
public static class Builder {
private final Map<String, Type> map = Maps.newLinkedHashMap();
public void put(String headerName, Type headerType) {
map.put(headerName, headerType);
}
public HeaderMapSpec create() {
return new HeaderMapSpec(map);
}
}
private final Map<String, Type> map;
private HeaderMapSpec(Map<String, Type> map) {
this.map = map;
}
public Type getTypeFor(String headerName) {
return map.get(headerName);
}
public Set<Map.Entry<String, Type>> entrySet() {
return map.entrySet();
}
@Override
public boolean isCompatible(String headerName, Type targetType) {
Type typeOfHeader = getTypeFor(headerName);
if (typeOfHeader == null) {
return false;
}
Class<?> rawClassOfHeader = TypeUtils.toRawClass(typeOfHeader);
Class<?> rawClassOfTargetType = TypeUtils.toRawClass(targetType);
return rawClassOfHeader.isAssignableFrom(rawClassOfTargetType);
}
public boolean isCompatible(String headerName, Object headerValue) {
return isCompatible(headerName, headerValue.getClass());
}
@Override
public String toString() {
return Util.toStringMapKeys(map);
}
@Override
public int size() {
return map.size();
}
}

View File

@ -0,0 +1,32 @@
/*
* Copyright (C) 2008 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.gson.wsf;
/**
* An enum of Http methods to provide strongly-typed versions instead of strings.
*
* @author inder
*/
public enum HttpMethod {
GET,
POST,
PUT,
DELETE;
public static HttpMethod getMethod(String method) {
return valueOf(method.trim().toUpperCase());
}
}

View File

@ -0,0 +1,40 @@
/*
* Copyright (C) 2008 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.gson.wsf;
import java.lang.reflect.Type;
import java.util.Map;
import java.util.Set;
/**
* Specification of a parameter map. Both {@link ContentBody} and {@link HeaderMap} are
* parameter maps.
*
* @author inder
*/
interface ParamMapSpec {
Type getTypeFor(String paramName);
boolean isCompatible(String paramName, Type type);
boolean isCompatible(String paramName, Object object);
public Set<Map.Entry<String, Type>> entrySet();
public int size();
}

View File

@ -0,0 +1,67 @@
/*
* Copyright (C) 2008 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.gson.wsf;
import java.lang.reflect.Type;
import java.util.Map;
import com.google.common.collect.Maps;
import com.google.inject.Inject;
/**
* Definition of the request body of a {@link WebServiceCall}. The request body is what is sent out
* in the output stream of the request (for example, with
* {@link java.net.HttpURLConnection#getOutputStream()}) , and is read by the
* {@link javax.servlet.http.HttpServletRequest#getInputStream()}.
*
* @author inder
*/
public final class RequestBody extends ContentBody {
public static class Builder {
private final Map<String, Object> contents = Maps.newLinkedHashMap();
private final RequestBodySpec spec;
@Inject
public Builder(RequestBodySpec spec) {
this.spec = spec;
}
public Builder add(String paramName, Object content) {
return add(paramName, content, content.getClass());
}
public Builder add(String paramName, Object content, Type typeOfContent) {
spec.isCompatible(paramName, typeOfContent);
contents.put(paramName, content);
return this;
}
public RequestBody create() {
RequestBody requestBody = new RequestBody(spec, contents);
return requestBody;
}
}
public RequestBody(RequestBodySpec spec, Map<String, Object> contents) {
super(spec, contents);
}
@Override
public RequestBodySpec getSpec() {
return (RequestBodySpec) spec;
}
}

View File

@ -0,0 +1,46 @@
/*
* Copyright (C) 2008 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.gson.wsf;
import java.lang.reflect.Type;
import java.util.Map;
import com.google.common.collect.Maps;
/**
* Specification of a {@link RequestBody}.
*
* @author inder
*/
public final class RequestBodySpec extends ContentBodySpec {
public static class Builder {
private final Map<String, Type> paramsSpec = Maps.newLinkedHashMap();
public Builder add(String paramName, Type type) {
paramsSpec.put(paramName, type);
return this;
}
public RequestBodySpec create() {
RequestBodySpec spec = new RequestBodySpec(paramsSpec);
return spec;
}
}
public RequestBodySpec(Map<String, Type> paramsSpec) {
super(paramsSpec);
}
}

View File

@ -0,0 +1,53 @@
/*
* Copyright (C) 2008 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.gson.wsf;
import com.google.common.base.Preconditions;
/**
* Specification for a {@link WebServiceRequest}.
*
* @author inder
*/
public final class RequestSpec {
private final HeaderMapSpec headersSpec;
private final RequestBodySpec bodySpec;
public RequestSpec(HeaderMapSpec headersSpec, RequestBodySpec bodySpec) {
Preconditions.checkNotNull(headersSpec);
Preconditions.checkNotNull(bodySpec);
this.headersSpec = headersSpec;
this.bodySpec = bodySpec;
}
public HeaderMapSpec getHeadersSpec() {
return headersSpec;
}
public RequestBodySpec getBodySpec() {
return bodySpec;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("{headersSpec:");
sb.append(headersSpec).append(",bodySpec:");
sb.append(bodySpec).append("}");
return sb.toString();
}
}

View File

@ -0,0 +1,53 @@
/*
* Copyright (C) 2008 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.gson.wsf;
import java.lang.reflect.Type;
import com.google.common.base.Preconditions;
/**
* body of the response. This is written out as JSON to be sent out to the client.
*
* @author inder
*/
public final class ResponseBody extends ContentBody {
public ResponseBody(ResponseBodySpec spec) {
super(spec);
}
@Override
public ResponseBodySpec getSpec() {
return (ResponseBodySpec) spec;
}
/**
* If value is a generic type, use {@link #put(String, Object, Type)} instead.
*
* @param key
* @param value
*/
public void put(String key, Object value) {
put(key, value, value.getClass());
}
public void put(String key, Object value, Type typeOfValue) {
Type expectedType = spec.getTypeFor(key);
Preconditions.checkArgument(Util.isAssignableFrom(typeOfValue, expectedType));
contents.put(key, value);
}
}

View File

@ -0,0 +1,46 @@
/*
* Copyright (C) 2008 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.gson.wsf;
import java.lang.reflect.Type;
import java.util.Map;
import com.google.common.collect.Maps;
/**
* Specification of a {@link ResponseBody}.
*
* @author inder
*/
public final class ResponseBodySpec extends ContentBodySpec {
public static class Builder {
private final Map<String, Type> paramsSpec = Maps.newLinkedHashMap();
public Builder add(String paramName, Type type) {
paramsSpec.put(paramName, type);
return this;
}
public ResponseBodySpec create() {
ResponseBodySpec spec = new ResponseBodySpec(paramsSpec);
return spec;
}
}
public ResponseBodySpec(Map<String, Type> paramsSpec) {
super(paramsSpec);
}
}

View File

@ -0,0 +1,52 @@
/*
* Copyright (C) 2008 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.gson.wsf;
import com.google.common.base.Preconditions;
/**
* Specification for a {@link WebServiceResponse}.
*
* @author inder
*/
public final class ResponseSpec {
private final HeaderMapSpec headersSpec;
private final ResponseBodySpec bodySpec;
public ResponseSpec(HeaderMapSpec headersSpec, ResponseBodySpec bodySpec) {
Preconditions.checkNotNull(headersSpec);
Preconditions.checkNotNull(bodySpec);
this.headersSpec = headersSpec;
this.bodySpec = bodySpec;
}
public ResponseBodySpec getBodySpec() {
return bodySpec;
}
public HeaderMapSpec getHeadersSpec() {
return headersSpec;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("{headersSpec:");
sb.append(headersSpec).append(",bodySpec:");
sb.append(bodySpec).append("}");
return sb.toString();
}
}

View File

@ -0,0 +1,92 @@
/*
* Copyright (C) 2008 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.
*/
// Copied from com.google.gson.TypeUtils
package com.google.gson.wsf;
import java.lang.reflect.Array;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
/**
* Utility class containing some methods for obtaining information on types.
*
* @author Inderjeet Singh
* @author Joel Leitch
*/
final class TypeUtils {
/**
* Returns the actual type matching up with the first type variable.
* So, for a {@code typeInfo} instance defined as:
* <pre>
* class Foo<A, B> {
* }
* Type fooType = new TypeToken<Foo<Integer, String>>() {}.getType();
* </pre>
* <code>TypeUtils.getActualTypeForFirstTypeVariable(fooType)</code> will return Integer.class.
*/
static Type getActualTypeForFirstTypeVariable(Type type) {
if (type instanceof Class) {
return Object.class;
} else if (type instanceof ParameterizedType) {
return ((ParameterizedType)type).getActualTypeArguments()[0];
} else if (type instanceof GenericArrayType) {
return getActualTypeForFirstTypeVariable(((GenericArrayType)type).getGenericComponentType());
} else {
throw new IllegalArgumentException("Type \'" + type + "\' is not a Class, "
+ "ParameterizedType, or GenericArrayType. Can't extract class.");
}
}
static boolean isArray(Type type) {
if (type instanceof Class) {
return ((Class<?>)type).isArray();
} else if (type instanceof GenericArrayType) {
return true;
} else {
return false;
}
}
/**
* This method returns the actual raw class associated with the specified type.
*/
static Class<?> toRawClass(Type type) {
if (type instanceof Class) {
return (Class<?>) type;
} else if (type instanceof ParameterizedType) {
ParameterizedType actualType = (ParameterizedType)type;
return toRawClass(actualType.getRawType());
} else if (type instanceof GenericArrayType) {
GenericArrayType actualType = (GenericArrayType) type;
Class<?> rawClass = toRawClass(actualType.getGenericComponentType());
return wrapWithArray(rawClass);
} else {
throw new IllegalArgumentException("Type \'" + type + "\' is not a Class, "
+ "ParameterizedType, or GenericArrayType. Can't extract class.");
}
}
static Class<?> wrapWithArray(Class<?> rawClass) {
return Array.newInstance(rawClass, 0).getClass();
}
private TypeUtils() {
// Class with just some static utility methods, should not be instantiated
}
}

View File

@ -0,0 +1,75 @@
/*
* Copyright (C) 2008 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.gson.wsf;
import java.lang.reflect.Type;
import java.util.Map;
final class Util {
private Util() { }
public static boolean isAssignableFrom(Type typeOfValue, Type expectedType) {
return typeOfValue.equals(expectedType);
}
public static String toStringMapKeys(Map<String, ?> map) {
StringBuilder sb = new StringBuilder("[");
boolean first = true;
for (Map.Entry<String, ?> entry : map.entrySet()) {
if (first) {
first = false;
} else {
sb.append(",");
}
sb.append(entry.getKey());
}
sb.append("]");
return sb.toString();
}
public static String toStringMapOfTypes(Map<String, Type> map) {
StringBuilder sb = new StringBuilder("[");
boolean first = true;
for (Map.Entry<String, ?> entry : map.entrySet()) {
if (first) {
first = false;
} else {
sb.append(",");
}
sb.append(entry.getKey()).append(":");
Class<?> clazz = (Class<?>) entry.getValue();
sb.append(clazz.getSimpleName());
}
sb.append("]");
return sb.toString();
}
public static String toStringMap(Map<String, Object> map) {
StringBuilder sb = new StringBuilder("[");
boolean first = true;
for (Map.Entry<String, ?> entry : map.entrySet()) {
if (first) {
first = false;
} else {
sb.append(",");
}
sb.append(entry.getKey()).append(":").append(entry.getValue());
}
sb.append("]");
return sb.toString();
}
}

View File

@ -0,0 +1,37 @@
/*
* Copyright (C) 2008 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.gson.wsf;
/**
* Base class for exceptions thrown to indicate a Web service external or application error
* condition. This can happen due to bad input, or illegal sequence of operations. This should
* never be thrown to indicate a System error condition. For that purpose, use
* {@link WebServiceSystemException} instead.
*
* @author inder
*/
public class WebServiceAppException extends RuntimeException {
private static final long serialVersionUID = 4422041697108937041L;
public WebServiceAppException(Exception cause) {
super(cause);
}
public WebServiceAppException(String msg, Exception cause) {
super(msg, cause);
}
}

View File

@ -0,0 +1,48 @@
/*
* Copyright (C) 2008 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.gson.wsf;
/**
* The data associated with a Web service call. This includes http request header parameters (form
* and URL parameters), {@link RequestBody}, response header parameters, and {@link ResponseBody}.
*
* @author inder
*/
public final class WebServiceCall {
private final WebServiceCallSpec callSpec;
private final WebServiceRequest request;
private final WebServiceResponse response;
public WebServiceCall(WebServiceCallSpec callSpec, WebServiceRequest request,
WebServiceResponse response) {
this.callSpec = callSpec;
this.request = request;
this.response = response;
}
public WebServiceCallSpec getSpec() {
return callSpec;
}
public WebServiceRequest getRequest() {
return request;
}
public WebServiceResponse getResponse() {
return response;
}
}

View File

@ -0,0 +1,140 @@
/*
* Copyright (C) 2008 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.gson.wsf;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;
import com.google.common.base.Preconditions;
/**
* Specification for a Json web service call. The call includes the relative path where the call
* is available, the specification of requests, and responses.
*
* @author inder
*/
public final class WebServiceCallSpec {
public static final WebServiceCallSpec NULL_SPEC = new Builder(new CallPath("")).create();
public static class Builder {
private final CallPath callPath;
private final Set<HttpMethod> supportedHttpMethods = new LinkedHashSet<HttpMethod>();
private final HeaderMapSpec.Builder reqParamsSpecBuilder = new HeaderMapSpec.Builder();
private final RequestBodySpec.Builder reqBodySpecBuilder = new RequestBodySpec.Builder();
private final HeaderMapSpec.Builder resParamsSpecBuilder = new HeaderMapSpec.Builder();
private final ResponseBodySpec.Builder resBodySpecBuilder = new ResponseBodySpec.Builder();
public Builder(CallPath callPath) {
this.callPath = callPath;
}
/**
* If this method is not invoked, then it is assumed that the WebServiceCall supports all
* methods specified in {@link HttpMethod#values()}.
*
* @param httpMethods list of methods that this call supports.
* @return self to follow the Builder pattern.
*/
public Builder supportsHttpMethod(HttpMethod... httpMethods) {
supportedHttpMethods.addAll(Arrays.asList(httpMethods));
return this;
}
public Builder addRequestParam(String paramName, Type type) {
reqParamsSpecBuilder.put(paramName, type);
return this;
}
public Builder addRequestBodyParam(String paramName, Type type) {
reqBodySpecBuilder.add(paramName, type);
return this;
}
public Builder addResponseParam(String paramName, Type type) {
resParamsSpecBuilder.put(paramName, type);
return this;
}
public Builder addResponseBodyParam(String paramName, Type type) {
resBodySpecBuilder.add(paramName, type);
return this;
}
public WebServiceCallSpec create() {
if (supportedHttpMethods.isEmpty()) {
supportedHttpMethods.addAll(Arrays.asList(HttpMethod.values()));
}
RequestSpec requestSpec =
new RequestSpec(reqParamsSpecBuilder.create(), reqBodySpecBuilder.create());
ResponseSpec responseSpec =
new ResponseSpec(resParamsSpecBuilder.create(), resBodySpecBuilder.create());
WebServiceCallSpec callSpec = new WebServiceCallSpec(supportedHttpMethods, callPath,
requestSpec, responseSpec);
return callSpec;
}
}
private final Set<HttpMethod> supportedHttpMethods;
private final CallPath path;
private final ResponseSpec responseSpec;
private final RequestSpec requestSpec;
private WebServiceCallSpec(Set<HttpMethod> supportedHttpMethods, CallPath path,
RequestSpec requestSpec, ResponseSpec responseSpec) {
Preconditions.checkArgument(!supportedHttpMethods.isEmpty());
Preconditions.checkNotNull(path);
this.supportedHttpMethods = supportedHttpMethods;
this.path = path;
this.requestSpec = requestSpec;
this.responseSpec = responseSpec;
}
public CallPath getPath() {
return path;
}
public Set<HttpMethod> getSupportedHttpMethods() {
return supportedHttpMethods;
}
public ResponseSpec getResponseSpec() {
return responseSpec;
}
public RequestSpec getRequestSpec() {
return requestSpec;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("{path:");
sb.append(path).append(",supportedHttpMethods:");
boolean first = true;
for (HttpMethod method : supportedHttpMethods) {
if (first) {
first = false;
} else {
sb.append(",");
}
sb.append(method);
}
sb.append(path).append(",requestSpec:");
sb.append(requestSpec).append(",responseSpec:");
sb.append(responseSpec).append("}");
return sb.toString();
}
}

View File

@ -0,0 +1,75 @@
/*
* Copyright (C) 2008 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.gson.wsf;
/**
* The data associated with a Web service request. This includes HTTP request header parameters
* (form and URL parameters), and {@link RequestBody}.
*
* @author inder
*/
public final class WebServiceRequest {
private final HttpMethod method;
private final HeaderMap headers;
private final RequestBody body;
private final RequestSpec spec;
public WebServiceRequest(HttpMethod method, HeaderMap requestHeaders, RequestBody requestBody) {
this.method = method;
this.body = requestBody;
this.headers = requestHeaders;
this.spec = new RequestSpec(requestHeaders.getSpec(), requestBody.getSpec());
}
public HttpMethod getMethod() {
return method;
}
public RequestSpec getSpec() {
return spec;
}
public HttpMethod getHttpMethod() {
return method;
}
public RequestBody getBody() {
return body;
}
public HeaderMap getHeaders() {
return headers;
}
public String getContentType() {
return ContentBodySpec.JSON_CONTENT_TYPE;
}
@SuppressWarnings("unchecked")
public <T> T getHeader(String headerName) {
return (T) headers.get(headerName);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("{");
sb.append(method).append(",");
sb.append(",headers:").append(headers);
sb.append(",body:").append(body);
sb.append("}");
return sb.toString();
}
}

View File

@ -0,0 +1,67 @@
/*
* Copyright (C) 2008 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.gson.wsf;
/**
* The data associated with a Web service response. This includes http response header parameters,
* and {@link ResponseBody}.
*
* @author inder
*/
public final class WebServiceResponse {
private final HeaderMap headers;
private final ResponseBody body;
private final ResponseSpec spec;
public WebServiceResponse(ResponseSpec spec) {
this.spec = spec;
headers = new HeaderMap(spec.getHeadersSpec());
body = new ResponseBody(spec.getBodySpec());
}
public WebServiceResponse(HeaderMap responseHeaders, ResponseBody responseBody) {
this.spec = new ResponseSpec(responseHeaders.getSpec(), responseBody.getSpec());
this.headers = responseHeaders;
this.body = responseBody;
}
public ResponseSpec getSpec() {
return spec;
}
public HeaderMap getHeaders() {
return headers;
}
public ResponseBody getBody() {
return body;
}
@SuppressWarnings("unchecked")
public <T> T getHeader(String headerName) {
return (T) headers.get(headerName);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("{headers:");
sb.append(headers);
sb.append(",body:").append(body);
sb.append("}");
return sb.toString();
}
}

View File

@ -0,0 +1,26 @@
/*
* Copyright (C) 2008 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.gson.wsf;
/**
* Specification of the Web service. This contains a specification of all the
* {@link WebServiceCall}s supported by this Web service.
*
* @author inder
*/
public interface WebServiceSpec {
public CallPathMap<WebServiceCallSpec> getCalls();
}

View File

@ -0,0 +1,36 @@
/*
* Copyright (C) 2008 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.gson.wsf;
/**
* Base class for all exceptions thrown by the Web service to indicate a system error condition.
* This should never be thrown to indicate bad user input. For that purpose, use
* {@link WebServiceAppException}.
*
* @author inder
*/
public class WebServiceSystemException extends RuntimeException {
private static final long serialVersionUID = -2511829073381716183L;
public WebServiceSystemException(Exception cause) {
super(cause);
}
public WebServiceSystemException(String msg, Exception cause) {
super(msg, cause);
}
}

View File

@ -0,0 +1,74 @@
/*
* Copyright (C) 2008 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.gson.wsf.client;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import java.lang.reflect.Type;
import java.net.HttpURLConnection;
import java.util.Map;
import com.google.gson.Gson;
import com.google.gson.wsf.HeaderMap;
import com.google.gson.wsf.HeaderMapSpec;
import com.google.gson.wsf.RequestBody;
import com.google.gson.wsf.WebServiceRequest;
/**
* Class to send Web service requests on a {@link HttpURLConnection}.
*
* @author inder
*/
public final class RequestSender {
private final Gson gson;
public RequestSender(Gson gson) {
this.gson = gson;
}
public void send(HttpURLConnection conn, WebServiceRequest request) {
try {
conn.setRequestMethod(request.getHttpMethod().toString());
conn.setRequestProperty("Content-Type", request.getContentType());
addRequestParams(conn, request.getHeaders());
RequestBody requestBody = request.getBody();
if (requestBody.getSpec().size() > 0) {
conn.setDoOutput(true);
addRequestBody(conn, requestBody);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private void addRequestParams(HttpURLConnection conn, HeaderMap requestParams) {
HeaderMapSpec spec = requestParams.getSpec();
for (Map.Entry<String, Object> entry : requestParams.entrySet()) {
String paramName = entry.getKey();
Type type = spec.getTypeFor(paramName);
Object value = entry.getValue();
String json = gson.toJson(value, type);
conn.addRequestProperty(paramName, json);
}
}
private void addRequestBody(HttpURLConnection conn, RequestBody body) throws IOException {
Writer writer = new PrintWriter(conn.getOutputStream());
gson.toJson(body, writer);
writer.close();
}
}

View File

@ -0,0 +1,90 @@
/*
* Copyright (C) 2008 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.gson.wsf.client;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.lang.reflect.Type;
import java.net.HttpURLConnection;
import java.util.Map;
import com.google.common.base.Preconditions;
import com.google.gson.Gson;
import com.google.gson.wsf.HeaderMap;
import com.google.gson.wsf.HeaderMapSpec;
import com.google.gson.wsf.ResponseBody;
import com.google.gson.wsf.ResponseBodySpec;
import com.google.gson.wsf.ResponseSpec;
import com.google.gson.wsf.WebServiceResponse;
/**
* Receives a response coming on an {@link HttpURLConnection}.
*
* @author inder
*/
public final class ResponseReceiver {
private final Gson gson;
private final ResponseSpec spec;
public ResponseReceiver(Gson gson, ResponseSpec spec) {
this.gson = gson;
this.spec = spec;
}
public WebServiceResponse receive(HttpURLConnection conn) {
try {
HeaderMapSpec paramSpec = spec.getHeadersSpec();
ResponseBodySpec bodySpec = spec.getBodySpec();
if (bodySpec.size() > 0) {
conn.setDoInput(true);
}
// read response
HeaderMap responseParams = readResponseHeaders(conn, paramSpec);
ResponseBody responseBody = readResponseBody(conn, bodySpec);
return new WebServiceResponse(responseParams, responseBody);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private HeaderMap readResponseHeaders(HttpURLConnection conn, HeaderMapSpec paramsSpec) {
HeaderMap params = new HeaderMap(paramsSpec);
for (Map.Entry<String, Type> entry : paramsSpec.entrySet()) {
String paramName = entry.getKey();
String json = conn.getHeaderField(paramName);
if (json != null) {
Type typeOfT = paramsSpec.getTypeFor(paramName);
Object value = gson.fromJson(json, typeOfT);
params.put(paramName, value, typeOfT);
}
}
return params;
}
private ResponseBody readResponseBody(HttpURLConnection conn, ResponseBodySpec bodySpec)
throws IOException {
if (bodySpec.size() == 0) {
return new ResponseBody(bodySpec);
}
String connContentType = conn.getContentType();
Preconditions.checkArgument(connContentType.contains(bodySpec.getContentType()));
Reader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
ResponseBody body = gson.fromJson(reader, ResponseBody.class);
return body;
}
}

View File

@ -0,0 +1,64 @@
/*
* Copyright (C) 2008 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.gson.wsf.client;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import com.google.gson.Gson;
import com.google.gson.wsf.WebServiceCallSpec;
import com.google.gson.wsf.WebServiceRequest;
import com.google.gson.wsf.WebServiceResponse;
/**
* Main class used by clients to access a Gson Web service.
*
* @author inder
*/
public final class WebServiceClient {
private final WebServiceConfig config;
private final WebServiceCallSpec callSpec;
private final Gson gson;
public WebServiceClient(Gson gson, WebServiceConfig serverConfig, WebServiceCallSpec callSpec) {
this.gson = gson;
this.config = serverConfig;
this.callSpec = callSpec;
}
private URL getWebServiceUrl() {
String url = config.getServiceBaseUrl() + callSpec.getPath().get();
try {
return new URL(url);
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
public WebServiceResponse getResponse(WebServiceRequest request) {
try {
HttpURLConnection conn = (HttpURLConnection) getWebServiceUrl().openConnection();
RequestSender requestSender = new RequestSender(gson);
requestSender.send(conn, request);
ResponseReceiver responseReceiver = new ResponseReceiver(gson, callSpec.getResponseSpec());
return responseReceiver.receive(conn);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

View File

@ -0,0 +1,33 @@
/*
* Copyright (C) 2008 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.gson.wsf.client;
/**
* Configuration needed to access a Gson web service.
*
* @author inder
*/
public final class WebServiceConfig {
private final String serviceBaseUrl;
public WebServiceConfig(String serviceBaseUrl) {
this.serviceBaseUrl = serviceBaseUrl;
}
public String getServiceBaseUrl() {
return serviceBaseUrl;
}
}

View File

@ -0,0 +1,44 @@
/*
* Copyright (C) 2008 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.gson.wsf.inject;
import javax.servlet.http.HttpServletRequest;
import com.google.gson.wsf.CallPath;
import com.google.inject.Inject;
import com.google.inject.Provider;
/**
* Guice provider for {@link CallPath} for an incoming web service request.
*
* @author inder
*/
final class CallPathProvider implements Provider<CallPath> {
private final HttpServletRequest request;
@Inject
public CallPathProvider(HttpServletRequest request) {
this.request = request;
}
@Override
public CallPath get() {
String pathInfo = request.getPathInfo();
System.out.println("Incoming request with pathInfo: " + pathInfo);
String callPath = pathInfo;
return new CallPath(callPath);
}
}

View File

@ -0,0 +1,41 @@
/*
* Copyright (C) 2008 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.gson.wsf.inject;
import com.google.gson.wsf.RequestBodySpec;
import com.google.gson.wsf.RequestSpec;
import com.google.inject.Inject;
import com.google.inject.Provider;
/**
* Guice provider for the {@link RequestBodySpec} to map to the incoming requests.
*
* @author inder
*/
final class RequestBodySpecProvider implements Provider<RequestBodySpec> {
private final RequestSpec requestSpec;
@Inject
public RequestBodySpecProvider(RequestSpec requestSpec) {
this.requestSpec = requestSpec;
}
@Override
public RequestBodySpec get() {
return requestSpec.getBodySpec();
}
}

View File

@ -0,0 +1,41 @@
/*
* Copyright (C) 2008 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.gson.wsf.inject;
import com.google.gson.wsf.RequestSpec;
import com.google.gson.wsf.WebServiceCallSpec;
import com.google.inject.Inject;
import com.google.inject.Provider;
/**
* Guice provider for the {@link RequestSpec} to map to the incoming requests.
*
* @author inder
*/
final class RequestSpecProvider implements Provider<RequestSpec> {
private final WebServiceCallSpec webServiceCallSpec;
@Inject
public RequestSpecProvider(WebServiceCallSpec webServiceCallSpec) {
this.webServiceCallSpec = webServiceCallSpec;
}
@Override
public RequestSpec get() {
return webServiceCallSpec.getRequestSpec();
}
}

View File

@ -0,0 +1,57 @@
/*
* Copyright (C) 2008 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.gson.wsf.inject;
import javax.servlet.http.HttpServletRequest;
import com.google.gson.Gson;
import com.google.gson.wsf.WebServiceCall;
import com.google.gson.wsf.WebServiceCallSpec;
import com.google.gson.wsf.WebServiceRequest;
import com.google.gson.wsf.WebServiceResponse;
import com.google.gson.wsf.server.RequestReceiver;
import com.google.inject.Inject;
import com.google.inject.Provider;
/**
* Guice provider for {@link WebServiceCall} to be used by a server-side implementation.
*
* @author inder
*/
final class WebServiceCallProvider implements Provider<WebServiceCall> {
private final Gson gson;
private final WebServiceCallSpec callSpec;
private final HttpServletRequest request;
@Inject
public WebServiceCallProvider(Gson gson, HttpServletRequest request,
WebServiceCallSpec callSpec) {
this.callSpec = callSpec;
this.gson = gson;
this.request = request;
}
@Override
public WebServiceCall get() {
RequestReceiver receiver = new RequestReceiver(gson, callSpec.getRequestSpec());
WebServiceRequest wsRequest = receiver.receive(request);
// No need to populate response headers or response body
WebServiceResponse wsResponse = new WebServiceResponse(callSpec.getResponseSpec());
return new WebServiceCall(callSpec, wsRequest, wsResponse);
}
}

View File

@ -0,0 +1,43 @@
/*
* Copyright (C) 2008 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.gson.wsf.inject;
import com.google.gson.wsf.CallPath;
import com.google.gson.wsf.WebServiceCallSpec;
import com.google.gson.wsf.WebServiceSpec;
import com.google.inject.Inject;
import com.google.inject.Provider;
/**
* Guice provider for {@link WebServiceCallSpec}.
*
* @author inder
*/
final class WebServiceCallSpecProvider implements Provider<WebServiceCallSpec> {
private final CallPath callPath;
private final WebServiceSpec webServiceSpec;
@Inject
WebServiceCallSpecProvider(CallPath callPath, WebServiceSpec webServiceSpec) {
this.callPath = callPath;
this.webServiceSpec = webServiceSpec;
}
@Override
public WebServiceCallSpec get() {
return webServiceSpec.getCalls().get(callPath);
}
}

View File

@ -0,0 +1,101 @@
/*
* Copyright (C) 2008 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.gson.wsf.server;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import com.google.gson.Gson;
import com.google.gson.JsonParseException;
import com.google.gson.wsf.HeaderMap;
import com.google.gson.wsf.HeaderMapSpec;
import com.google.gson.wsf.HttpMethod;
import com.google.gson.wsf.RequestBody;
import com.google.gson.wsf.RequestBodySpec;
import com.google.gson.wsf.RequestSpec;
import com.google.gson.wsf.WebServiceRequest;
import com.google.gson.wsf.WebServiceSystemException;
/**
* Receives and parses a request at the server side on a {@link HttpServletRequest}.
*
* @author inder
*/
public final class RequestReceiver {
private final Gson gson;
private final RequestSpec spec;
public RequestReceiver(Gson gson, RequestSpec spec) {
this.gson = gson;
this.spec = spec;
}
public WebServiceRequest receive(HttpServletRequest request) {
try {
HeaderMap requestParams = buildRequestParams(request);
RequestBody requestBody = buildRequestBody(request);
HttpMethod method = HttpMethod.getMethod(request.getMethod());
return new WebServiceRequest(method, requestParams, requestBody);
} catch (IOException e) {
throw new WebServiceSystemException(e);
} catch (JsonParseException e) {
// Not a Web service request
throw new WebServiceSystemException(e);
}
}
private HeaderMap buildRequestParams(HttpServletRequest request) {
HeaderMapSpec paramsSpec = this.spec.getHeadersSpec();
HeaderMap params = new HeaderMap(paramsSpec);
for (Map.Entry<String, Type> param : paramsSpec.entrySet()) {
String name = param.getKey();
Type type = param.getValue();
String header = request.getHeader(name);
if (header == null || header.equals("")) {
// check parameter map for the value
header = request.getParameter(name);
}
if (header != null && !header.equals("")) {
Object value = gson.fromJson(header, type);
params.put(name, value);
}
}
return params;
}
private RequestBody buildRequestBody(HttpServletRequest request) throws IOException {
RequestBodySpec bodySpec = spec.getBodySpec();
if (bodySpec.size() == 0) {
return createEmptyRequestBody(bodySpec);
}
Reader reader = new BufferedReader(new InputStreamReader(request.getInputStream()));
RequestBody requestBody = gson.fromJson(reader, RequestBody.class);
return requestBody;
}
private RequestBody createEmptyRequestBody(RequestBodySpec bodySpec) {
return new RequestBody(bodySpec, new HashMap<String, Object>());
}
}

View File

@ -0,0 +1,73 @@
/*
* Copyright (C) 2008 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.gson.wsf.server;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.Map;
import java.util.logging.Logger;
import javax.servlet.http.HttpServletResponse;
import com.google.gson.Gson;
import com.google.gson.wsf.HeaderMap;
import com.google.gson.wsf.HeaderMapSpec;
import com.google.gson.wsf.ResponseBody;
import com.google.gson.wsf.WebServiceResponse;
/**
* Sends a JSON web service response on {@link HttpServletResponse}.
*
* @author inder
*/
public final class ResponseSender {
private static final Logger logger = Logger.getLogger(ResponseSender.class.getCanonicalName());
private Gson gson;
public ResponseSender(Gson gson) {
this.gson = gson;
}
public void send(HttpServletResponse conn, WebServiceResponse response) {
try {
sendHeaders(conn, response.getHeaders());
sendBody(conn, response.getBody());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private void sendHeaders(HttpServletResponse conn, HeaderMap responseParams) {
HeaderMapSpec spec = responseParams.getSpec();
for (Map.Entry<String, Object> param : responseParams.entrySet()) {
String paramName = param.getKey();
Object paramValue = param.getValue();
Type paramType = spec.getTypeFor(paramName);
String json = gson.toJson(paramValue, paramType);
logger.fine("RESPONSE HEADER:{" + paramName + ", " + json + "}");
conn.addHeader(paramName, json);
}
}
private void sendBody(HttpServletResponse conn, ResponseBody responseBody) throws IOException {
conn.setContentType(responseBody.getContentType());
conn.setCharacterEncoding(responseBody.getCharacterEncoding());
String json = gson.toJson(responseBody);
logger.fine("RESPONSE BODY:" + json);
conn.getWriter().append(json);
}
}

View File

@ -0,0 +1,77 @@
/*
* Copyright (C) 2008 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.gson.wsf.typeadapters;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;
import com.google.gson.InstanceCreator;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.google.gson.wsf.RequestBody;
import com.google.gson.wsf.RequestBodySpec;
/**
* Gson type adapter for {@link RequestBody}.
*
* @author inder
*/
public class RequestBodyGsonConverter implements JsonSerializer<RequestBody>,
JsonDeserializer<RequestBody>, InstanceCreator<RequestBody> {
private final RequestBodySpec spec;
public RequestBodyGsonConverter(RequestBodySpec spec) {
this.spec = spec;
}
@Override
public JsonElement serialize(RequestBody src, Type typeOfSrc,
JsonSerializationContext context) {
JsonObject root = new JsonObject();
for(Map.Entry<String, Object> entry : src.entrySet()) {
String key = entry.getKey();
Type entryType = src.getSpec().getTypeFor(key);
JsonElement value = context.serialize(entry.getValue(), entryType);
root.add(key, value);
}
return root;
}
@Override
public RequestBody deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context) throws JsonParseException {
RequestBody.Builder builder = new RequestBody.Builder(spec);
for (Map.Entry<String, JsonElement> entry : json.getAsJsonObject().entrySet()) {
String key = entry.getKey();
Type entryType = spec.getTypeFor(key);
Object value = context.deserialize(entry.getValue(), entryType);
builder.add(key, value);
}
return builder.create();
}
@Override
public RequestBody createInstance(Type type) {
return new RequestBody(spec, new HashMap<String, Object>());
}
}

View File

@ -0,0 +1,77 @@
/*
* Copyright (C) 2008 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.gson.wsf.typeadapters;
import java.lang.reflect.Type;
import java.util.Map;
import com.google.gson.InstanceCreator;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.google.gson.wsf.RequestBody;
import com.google.gson.wsf.ResponseBody;
import com.google.gson.wsf.ResponseBodySpec;
/**
* Gson type adapter for {@link ResponseBody}.
*
* @author inder
*/
public final class ResponseBodyGsonConverter implements JsonSerializer<ResponseBody>,
JsonDeserializer<ResponseBody>, InstanceCreator<ResponseBody> {
private final ResponseBodySpec spec;
public ResponseBodyGsonConverter(ResponseBodySpec spec) {
this.spec = spec;
}
@Override
public JsonElement serialize(ResponseBody src, Type typeOfSrc,
JsonSerializationContext context) {
JsonObject root = new JsonObject();
for(Map.Entry<String, Object> entry : src.entrySet()) {
String key = entry.getKey();
Type entryType = src.getSpec().getTypeFor(key);
JsonElement value = context.serialize(entry.getValue(), entryType);
root.add(key, value);
}
return root;
}
@Override
public ResponseBody deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context) throws JsonParseException {
ResponseBody responseBody = new ResponseBody(spec);
for (Map.Entry<String, JsonElement> entry : json.getAsJsonObject().entrySet()) {
String key = entry.getKey();
Type entryType = spec.getTypeFor(key);
Object value = context.deserialize(entry.getValue(), entryType);
responseBody.put(key, value, entryType);
}
return responseBody;
}
@Override
public ResponseBody createInstance(Type type) {
return new ResponseBody(spec);
}
}