paramsSpec) {
+ super(paramsSpec);
+ }
+}
diff --git a/wsf/src/main/java/com/google/gson/wsf/ResponseSpec.java b/wsf/src/main/java/com/google/gson/wsf/ResponseSpec.java
new file mode 100644
index 00000000..2dbe5032
--- /dev/null
+++ b/wsf/src/main/java/com/google/gson/wsf/ResponseSpec.java
@@ -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();
+ }
+}
diff --git a/wsf/src/main/java/com/google/gson/wsf/TypeUtils.java b/wsf/src/main/java/com/google/gson/wsf/TypeUtils.java
new file mode 100644
index 00000000..86660f87
--- /dev/null
+++ b/wsf/src/main/java/com/google/gson/wsf/TypeUtils.java
@@ -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:
+ *
+ * class Foo {
+ * }
+ * Type fooType = new TypeToken>() {}.getType();
+ *
+ * TypeUtils.getActualTypeForFirstTypeVariable(fooType)
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
+ }
+}
diff --git a/wsf/src/main/java/com/google/gson/wsf/Util.java b/wsf/src/main/java/com/google/gson/wsf/Util.java
new file mode 100755
index 00000000..ac88bc40
--- /dev/null
+++ b/wsf/src/main/java/com/google/gson/wsf/Util.java
@@ -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 map) {
+ StringBuilder sb = new StringBuilder("[");
+ boolean first = true;
+ for (Map.Entry entry : map.entrySet()) {
+ if (first) {
+ first = false;
+ } else {
+ sb.append(",");
+ }
+ sb.append(entry.getKey());
+ }
+ sb.append("]");
+ return sb.toString();
+ }
+
+ public static String toStringMapOfTypes(Map map) {
+ StringBuilder sb = new StringBuilder("[");
+ boolean first = true;
+ for (Map.Entry 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 map) {
+ StringBuilder sb = new StringBuilder("[");
+ boolean first = true;
+ for (Map.Entry entry : map.entrySet()) {
+ if (first) {
+ first = false;
+ } else {
+ sb.append(",");
+ }
+ sb.append(entry.getKey()).append(":").append(entry.getValue());
+ }
+ sb.append("]");
+ return sb.toString();
+ }
+
+}
diff --git a/wsf/src/main/java/com/google/gson/wsf/WebServiceAppException.java b/wsf/src/main/java/com/google/gson/wsf/WebServiceAppException.java
new file mode 100644
index 00000000..44d8d5a8
--- /dev/null
+++ b/wsf/src/main/java/com/google/gson/wsf/WebServiceAppException.java
@@ -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);
+ }
+}
diff --git a/wsf/src/main/java/com/google/gson/wsf/WebServiceCall.java b/wsf/src/main/java/com/google/gson/wsf/WebServiceCall.java
new file mode 100755
index 00000000..8f258a9f
--- /dev/null
+++ b/wsf/src/main/java/com/google/gson/wsf/WebServiceCall.java
@@ -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;
+ }
+}
diff --git a/wsf/src/main/java/com/google/gson/wsf/WebServiceCallSpec.java b/wsf/src/main/java/com/google/gson/wsf/WebServiceCallSpec.java
new file mode 100755
index 00000000..bb6e8ac4
--- /dev/null
+++ b/wsf/src/main/java/com/google/gson/wsf/WebServiceCallSpec.java
@@ -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 supportedHttpMethods = new LinkedHashSet();
+ 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 supportedHttpMethods;
+ private final CallPath path;
+ private final ResponseSpec responseSpec;
+ private final RequestSpec requestSpec;
+
+ private WebServiceCallSpec(Set 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 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();
+ }
+}
diff --git a/wsf/src/main/java/com/google/gson/wsf/WebServiceRequest.java b/wsf/src/main/java/com/google/gson/wsf/WebServiceRequest.java
new file mode 100644
index 00000000..358ec7ed
--- /dev/null
+++ b/wsf/src/main/java/com/google/gson/wsf/WebServiceRequest.java
@@ -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 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();
+ }
+}
diff --git a/wsf/src/main/java/com/google/gson/wsf/WebServiceResponse.java b/wsf/src/main/java/com/google/gson/wsf/WebServiceResponse.java
new file mode 100644
index 00000000..5a47d1ed
--- /dev/null
+++ b/wsf/src/main/java/com/google/gson/wsf/WebServiceResponse.java
@@ -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 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();
+ }
+}
diff --git a/wsf/src/main/java/com/google/gson/wsf/WebServiceSpec.java b/wsf/src/main/java/com/google/gson/wsf/WebServiceSpec.java
new file mode 100755
index 00000000..414312b8
--- /dev/null
+++ b/wsf/src/main/java/com/google/gson/wsf/WebServiceSpec.java
@@ -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 getCalls();
+}
diff --git a/wsf/src/main/java/com/google/gson/wsf/WebServiceSystemException.java b/wsf/src/main/java/com/google/gson/wsf/WebServiceSystemException.java
new file mode 100755
index 00000000..d02125a3
--- /dev/null
+++ b/wsf/src/main/java/com/google/gson/wsf/WebServiceSystemException.java
@@ -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);
+ }
+}
diff --git a/wsf/src/main/java/com/google/gson/wsf/client/RequestSender.java b/wsf/src/main/java/com/google/gson/wsf/client/RequestSender.java
new file mode 100644
index 00000000..6f91d685
--- /dev/null
+++ b/wsf/src/main/java/com/google/gson/wsf/client/RequestSender.java
@@ -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 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();
+ }
+}
diff --git a/wsf/src/main/java/com/google/gson/wsf/client/ResponseReceiver.java b/wsf/src/main/java/com/google/gson/wsf/client/ResponseReceiver.java
new file mode 100644
index 00000000..1fe15104
--- /dev/null
+++ b/wsf/src/main/java/com/google/gson/wsf/client/ResponseReceiver.java
@@ -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 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;
+ }
+}
diff --git a/wsf/src/main/java/com/google/gson/wsf/client/WebServiceClient.java b/wsf/src/main/java/com/google/gson/wsf/client/WebServiceClient.java
new file mode 100644
index 00000000..a8c7f6d6
--- /dev/null
+++ b/wsf/src/main/java/com/google/gson/wsf/client/WebServiceClient.java
@@ -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);
+ }
+ }
+}
diff --git a/wsf/src/main/java/com/google/gson/wsf/client/WebServiceConfig.java b/wsf/src/main/java/com/google/gson/wsf/client/WebServiceConfig.java
new file mode 100644
index 00000000..72dc46db
--- /dev/null
+++ b/wsf/src/main/java/com/google/gson/wsf/client/WebServiceConfig.java
@@ -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;
+ }
+}
diff --git a/wsf/src/main/java/com/google/gson/wsf/inject/CallPathProvider.java b/wsf/src/main/java/com/google/gson/wsf/inject/CallPathProvider.java
new file mode 100644
index 00000000..b0173e0b
--- /dev/null
+++ b/wsf/src/main/java/com/google/gson/wsf/inject/CallPathProvider.java
@@ -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 {
+ 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);
+ }
+}
diff --git a/wsf/src/main/java/com/google/gson/wsf/inject/RequestBodySpecProvider.java b/wsf/src/main/java/com/google/gson/wsf/inject/RequestBodySpecProvider.java
new file mode 100644
index 00000000..bef5219c
--- /dev/null
+++ b/wsf/src/main/java/com/google/gson/wsf/inject/RequestBodySpecProvider.java
@@ -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 {
+
+ private final RequestSpec requestSpec;
+
+ @Inject
+ public RequestBodySpecProvider(RequestSpec requestSpec) {
+ this.requestSpec = requestSpec;
+ }
+
+ @Override
+ public RequestBodySpec get() {
+ return requestSpec.getBodySpec();
+ }
+}
diff --git a/wsf/src/main/java/com/google/gson/wsf/inject/RequestSpecProvider.java b/wsf/src/main/java/com/google/gson/wsf/inject/RequestSpecProvider.java
new file mode 100644
index 00000000..f21c9cd3
--- /dev/null
+++ b/wsf/src/main/java/com/google/gson/wsf/inject/RequestSpecProvider.java
@@ -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 {
+
+ private final WebServiceCallSpec webServiceCallSpec;
+
+ @Inject
+ public RequestSpecProvider(WebServiceCallSpec webServiceCallSpec) {
+ this.webServiceCallSpec = webServiceCallSpec;
+ }
+
+ @Override
+ public RequestSpec get() {
+ return webServiceCallSpec.getRequestSpec();
+ }
+}
diff --git a/wsf/src/main/java/com/google/gson/wsf/inject/WebServiceCallProvider.java b/wsf/src/main/java/com/google/gson/wsf/inject/WebServiceCallProvider.java
new file mode 100755
index 00000000..f3ce7dab
--- /dev/null
+++ b/wsf/src/main/java/com/google/gson/wsf/inject/WebServiceCallProvider.java
@@ -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 {
+ 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);
+ }
+}
\ No newline at end of file
diff --git a/wsf/src/main/java/com/google/gson/wsf/inject/WebServiceCallSpecProvider.java b/wsf/src/main/java/com/google/gson/wsf/inject/WebServiceCallSpecProvider.java
new file mode 100755
index 00000000..b7a18c2d
--- /dev/null
+++ b/wsf/src/main/java/com/google/gson/wsf/inject/WebServiceCallSpecProvider.java
@@ -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 {
+ 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);
+ }
+}
\ No newline at end of file
diff --git a/wsf/src/main/java/com/google/gson/wsf/server/RequestReceiver.java b/wsf/src/main/java/com/google/gson/wsf/server/RequestReceiver.java
new file mode 100644
index 00000000..36ad88f5
--- /dev/null
+++ b/wsf/src/main/java/com/google/gson/wsf/server/RequestReceiver.java
@@ -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 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());
+ }
+}
diff --git a/wsf/src/main/java/com/google/gson/wsf/server/ResponseSender.java b/wsf/src/main/java/com/google/gson/wsf/server/ResponseSender.java
new file mode 100644
index 00000000..92c481a9
--- /dev/null
+++ b/wsf/src/main/java/com/google/gson/wsf/server/ResponseSender.java
@@ -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 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);
+ }
+}
diff --git a/wsf/src/main/java/com/google/gson/wsf/typeadapters/RequestBodyGsonConverter.java b/wsf/src/main/java/com/google/gson/wsf/typeadapters/RequestBodyGsonConverter.java
new file mode 100644
index 00000000..22c90dfa
--- /dev/null
+++ b/wsf/src/main/java/com/google/gson/wsf/typeadapters/RequestBodyGsonConverter.java
@@ -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,
+ JsonDeserializer, InstanceCreator {
+
+ 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 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 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());
+ }
+}
diff --git a/wsf/src/main/java/com/google/gson/wsf/typeadapters/ResponseBodyGsonConverter.java b/wsf/src/main/java/com/google/gson/wsf/typeadapters/ResponseBodyGsonConverter.java
new file mode 100644
index 00000000..64f64fd3
--- /dev/null
+++ b/wsf/src/main/java/com/google/gson/wsf/typeadapters/ResponseBodyGsonConverter.java
@@ -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,
+ JsonDeserializer, InstanceCreator {
+
+ 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 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 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);
+ }
+}
\ No newline at end of file