Revision: 7762
Author: [email protected]
Date: Mon Mar 22 16:05:18 2010
Log: 1. Updates all requests to use POST instead of GET.
2. Use JSON to encode requests instead of a custom solution.
Patch by: amitmanjhi
Review by: rjrjr (desk review and TBR)
http://code.google.com/p/google-web-toolkit/source/detail?r=7762
Added:
/trunk/bikeshed/src/com/google/gwt/requestfactory/client/gen
/trunk/bikeshed/src/com/google/gwt/requestfactory/client/gen/ClientRequestObject.java
/trunk/bikeshed/src/com/google/gwt/requestfactory/shared/impl/RequestDataManager.java
Deleted:
/trunk/bikeshed/src/com/google/gwt/requestfactory/shared/impl/UrlParameterManager.java
Modified:
/trunk/bikeshed/src/com/google/gwt/requestfactory/client/impl/RequestFactoryJsonImpl.java
/trunk/bikeshed/src/com/google/gwt/requestfactory/shared/RequestFactory.java
/trunk/bikeshed/src/com/google/gwt/sample/expenses/gen/EmployeeRequestImpl.java
/trunk/bikeshed/src/com/google/gwt/sample/expenses/gen/ReportRequestImpl.java
/trunk/bikeshed/src/com/google/gwt/sample/expenses/server/ExpensesDataServlet.java
=======================================
--- /dev/null
+++
/trunk/bikeshed/src/com/google/gwt/requestfactory/client/gen/ClientRequestObject.java
Mon Mar 22 16:05:18 2010
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2010 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.gwt.requestfactory.client.gen;
+
+import com.google.gwt.core.client.JavaScriptObject;
+
+import java.util.Map;
+
+/**
+ * A convenience class to convert a Map<String, String> to a Json string
on the
+ * client side.
+ */
+public class ClientRequestObject {
+
+ public static String getRequestString(Map<String, String> requestData) {
+ ClientRequestObject requestObject = new ClientRequestObject();
+ requestObject.init();
+ for (String key : requestData.keySet()) {
+ requestObject.put(key, requestData.get(key));
+ }
+ return requestObject.toJsonString();
+ }
+
+ private JavaScriptObject map;
+
+ ClientRequestObject() {
+ init();
+ }
+
+ private native void init()/*-{
+
th...@com.google.gwt.requestfactory.client.gen.clientrequestobject::map =
{};
+ }-*/;
+
+ private native void put(String key, String value)/*-{
+
th...@com.google.gwt.requestfactory.client.gen.clientrequestobject::map[key]
= value;
+ }-*/;
+
+ private native String toJsonString()/*-{
+ return
JSON.stringify(th...@com.google.gwt.requestfactory.client.gen.clientrequestobject::map);
+ }-*/;
+}
=======================================
--- /dev/null
+++
/trunk/bikeshed/src/com/google/gwt/requestfactory/shared/impl/RequestDataManager.java
Mon Mar 22 16:05:18 2010
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2010 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.gwt.requestfactory.shared.impl;
+
+import com.google.gwt.sample.expenses.gen.MethodName;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * An utitlity class to manage the encoding and decoding of parameters and
+ * methodNames.
+ *
+ * TODO: add appropriate unit tests.
+ */
+public class RequestDataManager {
+
+ public static final String CONTENT_TOKEN = "contentData";
+ public static final String METHOD_TOKEN = "methodName";
+ public static final String PARAM_TOKEN = "param";
+
+ public static Object[] getObjectsFromParameterMap(
+ Map<String, String> parameterMap, Class<?> parameterClasses[]) {
+ assert parameterClasses != null;
+ Object args[] = new Object[parameterClasses.length];
+ for (int i = 0; i < parameterClasses.length; i++) {
+ args[i] = encodeParameterValue(parameterClasses[i].getName(),
+ parameterMap.get("param" + i));
+ }
+ return args;
+ }
+
+ /**
+ * Returns the string that encodes the request data.
+ *
+ */
+ public static Map<String, String> getRequestMap(MethodName methodName,
+ Object values[], String content) {
+ Map<String, String> requestMap = new HashMap<String, String>();
+ requestMap.put(METHOD_TOKEN, methodName.name());
+ if (values != null) {
+ for (int i = 0; i < values.length; i++) {
+ Object value = values[i];
+ requestMap.put(PARAM_TOKEN + i, value.toString());
+ }
+ }
+ if (content != null) {
+ requestMap.put(CONTENT_TOKEN, content);
+ }
+ return requestMap;
+ }
+
+ /**
+ * Encodes parameter value.
+ *
+ */
+ private static Object encodeParameterValue(String parameterType,
+ String parameterValue) {
+ if ("java.lang.String".equals(parameterType)) {
+ return parameterValue;
+ }
+ if ("java.lang.Integer".equals(parameterType)
+ || "int".equals(parameterType)) {
+ return new Integer(parameterValue);
+ }
+ if ("java.lang.Long".equals(parameterType) |
| "long".equals(parameterType)) {
+ return new Long(parameterValue);
+ }
+ throw new IllegalArgumentException("Unknown parameter type: "
+ + parameterType);
+ }
+}
=======================================
---
/trunk/bikeshed/src/com/google/gwt/requestfactory/shared/impl/UrlParameterManager.java
Mon Mar 22 07:44:56 2010
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright 2010 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.gwt.requestfactory.shared.impl;
-
-import java.util.Map;
-
-/**
- * An utitlity class to manage the encoding and decoding of parameters.
- *
- * TODO: add appropriate unit tests.
- */
-public class UrlParameterManager {
-
- private static final String TOKEN = "param";
-
- public static Object[] getObjectsFromFragment(
- Map<String, String[]> parameterMap, Class<?> parameterClasses[]) {
- assert parameterClasses != null;
- Object args[] = new Object[parameterClasses.length];
- for (int i = 0; i < parameterClasses.length; i++) {
- args[i] = encodeParameterValue(parameterClasses[i].getName(),
- parameterMap.get("param" + i));
- }
- return args;
- }
-
- /**
- * Returns the string that encodes the values. The string has a leading
&.
- *
- * @param values
- * @return
- */
- public static String getUrlFragment(Object values[]) {
- assert values != null;
- StringBuffer fragment = new StringBuffer();
- for (int i = 0; i < values.length; i++) {
- Object value = values[i];
- fragment.append("&");
- fragment.append(TOKEN);
- fragment.append(i);
- fragment.append("=");
- fragment.append(value.toString());
- }
- return fragment.toString();
- }
-
- /**
- * Encodes parameter value.
- *
- */
- private static Object encodeParameterValue(String parameterType,
- String parameterValues[]) {
- assert parameterValues != null;
- assert parameterValues.length == 1;
- String parameterValue = parameterValues[0];
- if ("java.lang.String".equals(parameterType)) {
- return parameterValue;
- }
- if ("java.lang.Integer".equals(parameterType)
- || "int".equals(parameterType)) {
- return new Integer(parameterValue);
- }
- if ("java.lang.Long".equals(parameterType) |
| "long".equals(parameterType)) {
- return new Long(parameterValue);
- }
- throw new IllegalArgumentException("Unknown parameter type: "
- + parameterType);
- }
-}
=======================================
---
/trunk/bikeshed/src/com/google/gwt/requestfactory/client/impl/RequestFactoryJsonImpl.java
Mon Mar 22 07:44:56 2010
+++
/trunk/bikeshed/src/com/google/gwt/requestfactory/client/impl/RequestFactoryJsonImpl.java
Mon Mar 22 16:05:18 2010
@@ -20,8 +20,10 @@
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
+import com.google.gwt.requestfactory.client.gen.ClientRequestObject;
import com.google.gwt.requestfactory.shared.RequestFactory;
import com.google.gwt.requestfactory.shared.SyncRequest;
+import com.google.gwt.requestfactory.shared.impl.RequestDataManager;
import com.google.gwt.sample.expenses.gen.MethodName;
import com.google.gwt.user.client.ui.HasValue;
import com.google.gwt.user.client.ui.HasValueList;
@@ -39,7 +41,7 @@
*/
public class RequestFactoryJsonImpl implements RequestFactory,
RequestFactory.Service {
-
+
private final ValueStore valueStore = new ValueStore() {
public void addValidation() {
@@ -59,13 +61,13 @@
T propertyOwner, Set<Property<T, ?>> properties) {
throw new UnsupportedOperationException();
}
-
+
};
- @SuppressWarnings("deprecation")
public void fire(final RequestObject requestObject) {
- RequestBuilder builder = new RequestBuilder(RequestBuilder.GET,
- requestObject.getRequestUrl());
+ RequestBuilder builder = new RequestBuilder(RequestBuilder.POST,
+ RequestFactory.URL);
+ builder.setRequestData(requestObject.getRequestData());
builder.setCallback(new RequestCallback() {
public void onError(Request request, Throwable exception) {
@@ -106,7 +108,7 @@
public void fire() {
RequestBuilder builder = new RequestBuilder(RequestBuilder.POST,
- "/expenses/data?methodName=" + MethodName.SYNC.name());
+ "/expenses/data");
StringBuilder requestData = new StringBuilder("[");
boolean first = true;
@@ -121,7 +123,8 @@
}
requestData.append("]");
- builder.setRequestData(requestData.toString());
+
builder.setRequestData(ClientRequestObject.getRequestString(RequestDataManager.getRequestMap(
+ MethodName.SYNC, null, requestData.toString())));
builder.setCallback(new RequestCallback() {
public void onError(Request request, Throwable exception) {
=======================================
---
/trunk/bikeshed/src/com/google/gwt/requestfactory/shared/RequestFactory.java
Mon Mar 22 07:44:56 2010
+++
/trunk/bikeshed/src/com/google/gwt/requestfactory/shared/RequestFactory.java
Mon Mar 22 16:05:18 2010
@@ -25,18 +25,15 @@
*/
public interface RequestFactory {
+ String URL = "/expenses/data";
+
/**
* Implemented by the request objects created by this factory.
*/
interface RequestObject {
void fire();
- String getRequestData(String data);
-
- /**
- * @deprecated Here only until we can move everything into the post
data
- */
- String getRequestUrl();
+ String getRequestData();
void handleResponseText(String responseText);
}
=======================================
---
/trunk/bikeshed/src/com/google/gwt/sample/expenses/gen/EmployeeRequestImpl.java
Mon Mar 22 07:44:56 2010
+++
/trunk/bikeshed/src/com/google/gwt/sample/expenses/gen/EmployeeRequestImpl.java
Mon Mar 22 16:05:18 2010
@@ -15,9 +15,11 @@
*/
package com.google.gwt.sample.expenses.gen;
+import com.google.gwt.requestfactory.client.gen.ClientRequestObject;
import
com.google.gwt.requestfactory.client.impl.AbstractListJsonRequestObject;
import com.google.gwt.requestfactory.shared.EntityListRequest;
import com.google.gwt.requestfactory.shared.RequestFactory.Service;
+import com.google.gwt.requestfactory.shared.impl.RequestDataManager;
import com.google.gwt.sample.expenses.shared.EmployeeKey;
import com.google.gwt.sample.expenses.shared.ExpenseRequestFactory;
import com.google.gwt.valuestore.shared.ValueStore;
@@ -55,15 +57,9 @@
public EntityListRequest<EmployeeKey> findAllEmployees() {
return new Request() {
- public String getRequestData(String data) {
- // TODO Dear Amit: your code here
- throw new UnsupportedOperationException();
- }
-
- @SuppressWarnings("deprecation")
- public String getRequestUrl() {
- return "/expenses/data?methodName="
- + MethodName.FIND_ALL_EMPLOYEES.name();
+ public String getRequestData() {
+ return
ClientRequestObject.getRequestString(RequestDataManager.getRequestMap(MethodName.FIND_ALL_EMPLOYEES,
+ null, null));
}
};
}
=======================================
---
/trunk/bikeshed/src/com/google/gwt/sample/expenses/gen/ReportRequestImpl.java
Mon Mar 22 07:44:56 2010
+++
/trunk/bikeshed/src/com/google/gwt/sample/expenses/gen/ReportRequestImpl.java
Mon Mar 22 16:05:18 2010
@@ -15,10 +15,11 @@
*/
package com.google.gwt.sample.expenses.gen;
+import com.google.gwt.requestfactory.client.gen.ClientRequestObject;
import
com.google.gwt.requestfactory.client.impl.AbstractListJsonRequestObject;
import com.google.gwt.requestfactory.shared.EntityListRequest;
import com.google.gwt.requestfactory.shared.RequestFactory.Service;
-import com.google.gwt.requestfactory.shared.impl.UrlParameterManager;
+import com.google.gwt.requestfactory.shared.impl.RequestDataManager;
import com.google.gwt.sample.expenses.shared.EmployeeKey;
import com.google.gwt.sample.expenses.shared.ExpenseRequestFactory;
import com.google.gwt.sample.expenses.shared.ReportKey;
@@ -57,32 +58,20 @@
public EntityListRequest<ReportKey> findAllReports() {
return new Request() {
- public String getRequestData(String data) {
- // TODO Dear Amit: your code here
- throw new UnsupportedOperationException();
+ public String getRequestData() {
+ return
ClientRequestObject.getRequestString(RequestDataManager.getRequestMap(
+ MethodName.FIND_ALL_REPORTS, null, null));
}
- @SuppressWarnings("deprecation")
- public String getRequestUrl() {
- return "/expenses/data?methodName="
- + MethodName.FIND_ALL_REPORTS.name();
- }
};
};
public EntityListRequest<ReportKey> findReportsByEmployee(
final ValueRef<EmployeeKey, String> id) {
return new Request() {
- public String getRequestData(String data) {
- // TODO Dear Amit: your code here
- throw new UnsupportedOperationException();
- }
-
- @SuppressWarnings("deprecation")
- public String getRequestUrl() {
- return "/expenses/data?methodName="
- + MethodName.FIND_REPORTS_BY_EMPLOYEE.name()
- + UrlParameterManager.getUrlFragment(new Object[] {id.get()});
+ public String getRequestData() {
+ return
ClientRequestObject.getRequestString(RequestDataManager.getRequestMap(
+ MethodName.FIND_REPORTS_BY_EMPLOYEE, new Object[] {id.get()},
null));
}
};
}
=======================================
---
/trunk/bikeshed/src/com/google/gwt/sample/expenses/server/ExpensesDataServlet.java
Mon Mar 22 07:44:56 2010
+++
/trunk/bikeshed/src/com/google/gwt/sample/expenses/server/ExpensesDataServlet.java
Mon Mar 22 16:05:18 2010
@@ -16,7 +16,7 @@
package com.google.gwt.sample.expenses.server;
import com.google.gwt.requestfactory.shared.EntityKey;
-import com.google.gwt.requestfactory.shared.impl.UrlParameterManager;
+import com.google.gwt.requestfactory.shared.impl.RequestDataManager;
import com.google.gwt.sample.expenses.gen.MethodName;
import com.google.gwt.sample.expenses.server.domain.Report;
import com.google.gwt.sample.expenses.server.domain.Storage;
@@ -33,7 +33,9 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
+import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -56,48 +58,61 @@
}
}
- @SuppressWarnings("unchecked")
@Override
- protected void doGet(HttpServletRequest request, HttpServletResponse
response)
+ protected void doPost(HttpServletRequest request, HttpServletResponse
response)
throws IOException {
- response.setStatus(HttpServletResponse.SC_OK);
- PrintWriter writer = response.getWriter();
- MethodName operation =
getMethodName(request.getParameter("methodName"));
+ MethodName methodName = null;
try {
- Class<?> classOperation =
Class.forName("com.google.gwt.sample.expenses.server.domain."
- + operation.getClassName());
- Method methodOperation = null;
- // TODO: check if method names must be unique in a class.
- for (Method method : classOperation.getDeclaredMethods()) {
- if (method.getName().equals(operation.getMethodName())) {
- methodOperation = method;
+ response.setStatus(HttpServletResponse.SC_OK);
+ JSONObject topLevelJsonObject = new JSONObject(getContent(request));
+ methodName =
getMethodName(topLevelJsonObject.getString(RequestDataManager.METHOD_TOKEN));
+ PrintWriter writer = response.getWriter();
+ switch (methodName) {
+ case FIND_ALL_EMPLOYEES:
+ case FIND_ALL_REPORTS:
+ case FIND_EMPLOYEE:
+ case FIND_REPORTS_BY_EMPLOYEE:
+ Class<?> classOperation =
Class.forName("com.google.gwt.sample.expenses.server.domain."
+ + methodName.getClassName());
+ Method methodOperation = null;
+ // TODO: check if method names must be unique in a class.
+ for (Method method : classOperation.getDeclaredMethods()) {
+ if (method.getName().equals(methodName.getMethodName())) {
+ methodOperation = method;
+ break;
+ }
+ }
+ if (methodOperation == null) {
+ throw new IllegalArgumentException("unable to find "
+ + methodName.getMethodName() + " in " + classOperation);
+ }
+ if (!Modifier.isStatic(methodOperation.getModifiers())) {
+ throw new IllegalArgumentException("the "
+ + methodOperation.getName() + " is not static");
+ }
+ Object args[] = RequestDataManager.getObjectsFromParameterMap(
+ getParameterMap(topLevelJsonObject),
methodOperation.getParameterTypes());
+ Object resultList = methodOperation.invoke(null, args);
+ if (!(resultList instanceof List)) {
+ throw new IllegalArgumentException("return value not a list "
+ + resultList);
+ }
+ JSONArray jsonArray = getJsonArray((List<?>) resultList);
+ writer.print(jsonArray.toString());
break;
- }
- }
- if (methodOperation == null) {
- throw new IllegalArgumentException("unable to find "
- + operation.getMethodName() + " in " + classOperation);
- }
- if (!Modifier.isStatic(methodOperation.getModifiers())) {
- throw new IllegalArgumentException("the " +
methodOperation.getName()
- + " is not static");
- }
- Map<String, String[]> parameterMap = request.getParameterMap();
- Object args[] =
UrlParameterManager.getObjectsFromFragment(parameterMap,
- methodOperation.getParameterTypes());
- Object resultList = methodOperation.invoke(null, args);
- if (!(resultList instanceof List)) {
- throw new IllegalArgumentException("return value not a list "
- + resultList);
- }
- JSONArray jsonArray = getJsonArray((List<?>) resultList);
- writer.print(jsonArray.toString());
+ case SYNC:
+
sync(topLevelJsonObject.getString(RequestDataManager.CONTENT_TOKEN),
writer);
+ break;
+ default:
+ System.err.println("POST: unknown method " + methodName);
+ break;
+ }
writer.flush();
// TODO: clean exception handling code below.
} catch (ClassNotFoundException e) {
throw new IllegalArgumentException("unable to load the class: "
- + operation);
+ + methodName);
} catch (IllegalAccessException e) {
throw new IllegalArgumentException(e);
} catch (InvocationTargetException e) {
@@ -108,25 +123,19 @@
throw new IllegalArgumentException(e);
} catch (NoSuchMethodException e) {
throw new IllegalArgumentException(e);
- }
+ }
}
- @Override
- protected void doPost(HttpServletRequest request, HttpServletResponse
response)
- throws IOException {
-
- response.setStatus(HttpServletResponse.SC_OK);
- MethodName methodName =
getMethodName(request.getParameter("methodName"));
- PrintWriter writer = response.getWriter();
- switch (methodName) {
- case SYNC:
- sync(request, writer);
- break;
- default:
- System.err.println("POST: unknown method " + methodName);
- break;
- }
- writer.flush();
+ private String getContent(HttpServletRequest request) throws IOException
{
+ int contentLength = request.getContentLength();
+ byte contentBytes[] = new byte[contentLength];
+ BufferedInputStream bis = new
BufferedInputStream(request.getInputStream());
+ int readBytes = 0;
+ while (bis.read(contentBytes, readBytes, contentLength - readBytes) >
0) {
+ // read the contents
+ }
+ // TODO: encoding issues?
+ return new String(contentBytes);
}
/**
@@ -196,6 +205,23 @@
methodName.append(propertyName.substring(1));
return methodName.toString();
}
+
+ /**
+ * @param jsonObject
+ * @return
+ * @throws JSONException
+ */
+ private Map<String, String> getParameterMap(JSONObject jsonObject)
throws JSONException {
+ Map<String, String> parameterMap = new HashMap<String, String>();
+ Iterator keys = jsonObject.keys();
+ while (keys.hasNext()) {
+ String key = keys.next().toString();
+ if (key.startsWith(RequestDataManager.PARAM_TOKEN)) {
+ parameterMap.put(key, jsonObject.getString(key));
+ }
+ }
+ return parameterMap;
+ }
/**
* @param entityElement
@@ -232,21 +258,10 @@
}
/**
- * @param request
- * @param writer
* @throws IOException
*/
- private void sync(HttpServletRequest request, PrintWriter writer)
- throws IOException {
- int contentLength = request.getContentLength();
- byte contentBytes[] = new byte[contentLength];
- BufferedInputStream bis = new
BufferedInputStream(request.getInputStream());
- int readBytes = 0;
- while (bis.read(contentBytes, readBytes, contentLength - readBytes) >
0) {
- // read the contents
- }
- // TODO: encoding issues?
- String content = new String(contentBytes);
+ private void sync(String content, PrintWriter writer) throws IOException
{
+
try {
JSONArray reportArray = new JSONArray(content);
int length = reportArray.length();
--
http://groups.google.com/group/Google-Web-Toolkit-Contributors
To unsubscribe from this group, send email to
google-web-toolkit-contributors+unsubscribegooglegroups.com or reply to this email with
the words "REMOVE ME" as the subject.