Initial code that uses org.json lib on the server side, passes actual request
parameters, plus integration with server side domain objects.
Review at http://gwt-code-reviews.appspot.com/160809
Review by: rjrjr@google.com
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@7687 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/bikeshed/.classpath b/bikeshed/.classpath
index 6386366..c112364 100644
--- a/bikeshed/.classpath
+++ b/bikeshed/.classpath
@@ -7,5 +7,6 @@
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="war/WEB-INF/lib/gwt-servlet.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
+ <classpathentry kind="lib" path="war/WEB-INF/lib/json.jar"/>
<classpathentry kind="output" path="war/WEB-INF/classes"/>
</classpath>
diff --git a/bikeshed/src/com/google/gwt/sample/expenses/client/Expenses.java b/bikeshed/src/com/google/gwt/sample/expenses/client/Expenses.java
index 60c8670..be3a7ba 100644
--- a/bikeshed/src/com/google/gwt/sample/expenses/client/Expenses.java
+++ b/bikeshed/src/com/google/gwt/sample/expenses/client/Expenses.java
@@ -17,17 +17,10 @@
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
-import com.google.gwt.core.client.JsArray;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
-import com.google.gwt.http.client.Request;
-import com.google.gwt.http.client.RequestBuilder;
-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.sample.expenses.shared.Employee;
import com.google.gwt.sample.expenses.shared.ExpenseRequestFactory;
-import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.ui.HasValueList;
import com.google.gwt.user.client.ui.RootLayoutPanel;
import com.google.gwt.user.client.ui.TextBox;
@@ -57,37 +50,6 @@
final Shell shell = new Shell();
root.add(shell);
- Command refresh = new Command() {
- public void execute() {
- RequestBuilder builder = new RequestBuilder(RequestBuilder.GET,
- "/expenses/data");
- builder.setCallback(new RequestCallback() {
-
- public void onError(Request request, Throwable exception) {
- shell.error.setInnerText(SERVER_ERROR);
- }
-
- public void onResponseReceived(Request request, Response response) {
- if (200 == response.getStatusCode()) {
- String text = response.getText();
- JsArray<ValuesImpl<Employee>> valueArray = ValuesImpl.arrayFromJson(text);
- shell.setValueList(valueArray);
- } else {
- shell.error.setInnerText(SERVER_ERROR + " ("
- + response.getStatusText() + ")");
- }
- }
- });
-
- try {
- builder.send();
- } catch (RequestException e) {
- shell.error.setInnerText(SERVER_ERROR + " (" + e.getMessage() + ")");
- }
- }
- };
- refresh.execute();
- shell.setRefresh(refresh);
final HasValueList<Values<Employee>> employees = new HasValueList<Values<Employee>>() {
@@ -110,7 +72,7 @@
};
requestFactory.employeeRequest().findAllEmployees().forProperty(
- Employee.DISPLAY_NAME).forProperty(Employee.USER_NAME).to(employees).fire();
+ Employee.DISPLAY_NAME).forProperty(Employee.USER_NAME).to(shell).fire();
// TODO(rjrjr) now get details
final TextBox nameHolder = new TextBox();
diff --git a/bikeshed/src/com/google/gwt/sample/expenses/client/Shell.java b/bikeshed/src/com/google/gwt/sample/expenses/client/Shell.java
index a195f4c..c83daac 100644
--- a/bikeshed/src/com/google/gwt/sample/expenses/client/Shell.java
+++ b/bikeshed/src/com/google/gwt/sample/expenses/client/Shell.java
@@ -16,20 +16,16 @@
package com.google.gwt.sample.expenses.client;
import com.google.gwt.core.client.GWT;
-import com.google.gwt.core.client.JsArray;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NodeList;
import com.google.gwt.dom.client.TableCellElement;
import com.google.gwt.dom.client.TableElement;
import com.google.gwt.dom.client.TableRowElement;
-import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.sample.expenses.shared.Employee;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
-import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.Command;
-import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HasValueList;
import com.google.gwt.user.client.ui.ListBox;
@@ -54,8 +50,6 @@
@UiField
TableRowElement header;
@UiField
- Button refreshButton;
- @UiField
ListBox users;
private Command refresh;
@@ -69,21 +63,11 @@
throw new UnsupportedOperationException();
}
- /**
- * @param refresh the refresh to set
- */
- public void setRefresh(Command refresh) {
- this.refresh = refresh;
- }
-
- /**
- * @param valueArray
- */
- public void setValueList(JsArray<ValuesImpl<Employee>> newValues) {
+ public void setValueList(List<Values<Employee>> newValues) {
int r = 1; // skip header
NodeList<TableRowElement> tableRows = table.getRows();
- for (int i = 0; i < newValues.length(); i++) {
- ValuesImpl<Employee> valueRow = newValues.get(i);
+ for (int i = 0; i < newValues.size(); i++) {
+ Values<Employee> valueRow = newValues.get(i);
if (r < tableRows.getLength()) {
reuseRow(r, tableRows, valueRow);
} else {
@@ -106,21 +90,10 @@
}
}
- public void setValueList(List<Values<Employee>> newValues) {
- throw new UnsupportedOperationException();
- }
-
public void setValueListSize(int size, boolean exact) {
throw new UnsupportedOperationException();
}
- @UiHandler("refreshButton")
- void onRefreshClick(@SuppressWarnings("unused") ClickEvent event) {
- if (refresh != null) {
- refresh.execute();
- }
- }
-
/**
* @param r
* @param tableRows
diff --git a/bikeshed/src/com/google/gwt/sample/expenses/client/Shell.ui.xml b/bikeshed/src/com/google/gwt/sample/expenses/client/Shell.ui.xml
index 808e6d7..75e2294 100644
--- a/bikeshed/src/com/google/gwt/sample/expenses/client/Shell.ui.xml
+++ b/bikeshed/src/com/google/gwt/sample/expenses/client/Shell.ui.xml
@@ -48,7 +48,6 @@
<g:center>
<g:HTMLPanel width='100%' height='100%'>
<h1>Employees</h1>
- <g:Button ui:field='refreshButton'>Refresh</g:Button>
<table ui:field='table' class='{style.reports}' width='100%'>
<col width='0%'></col>
<col width='100%'></col>
diff --git a/bikeshed/src/com/google/gwt/sample/expenses/domain/Storage.java b/bikeshed/src/com/google/gwt/sample/expenses/domain/Storage.java
index a5c1ad8..11ef96b 100644
--- a/bikeshed/src/com/google/gwt/sample/expenses/domain/Storage.java
+++ b/bikeshed/src/com/google/gwt/sample/expenses/domain/Storage.java
@@ -25,17 +25,6 @@
* frameworks do. For goodness sake don't imitate this for production code.
*/
class Storage {
-
- static final Storage INSTANCE;
- static {
- INSTANCE = new Storage();
- fill(INSTANCE);
- }
-
- public static <E extends Entity> E edit(E v1) {
- return v1.accept(new CreationVisitor<E>(v1));
- }
-
/**
* @param storage to fill with demo entities
*/
@@ -57,13 +46,38 @@
e2.setDisplayName("George H. Indigo");
e2.setSupervisor(e);
storage.persist(e2);
- }
+}
private final Map<Long, Entity> soup = new HashMap<Long, Entity>();
private final Map<String, Long> employeeUserNameIndex = new HashMap<String, Long>();
private long serial = 0;
- public synchronized <E extends Entity> E persist(final E delta) {
+ static final Storage INSTANCE;
+ static {
+ INSTANCE = new Storage();
+ fill(INSTANCE);
+ }
+
+ public static <E extends Entity> E edit(E v1) {
+ return v1.accept(new CreationVisitor<E>(v1));
+ }
+
+ @SuppressWarnings("unchecked")
+ // We make runtime checks that return type matches in type
+ synchronized <E extends Entity> E get(final E entity) {
+ Entity previous = soup.get(entity.getId());
+ if (null == previous) {
+ throw new IllegalArgumentException(String.format(
+ "In %s, unknown id %d", entity, entity.getId()));
+ }
+ if (!previous.getClass().equals(entity.getClass())) {
+ throw new IllegalArgumentException(String.format(
+ "Type mismatch, fetched %s for %s", entity, previous));
+ }
+ return (E) previous;
+ }
+
+ synchronized public <E extends Entity> E persist(final E delta) {
E next = null;
E previous = null;
@@ -97,7 +111,7 @@
synchronized List<Employee> findAllEmployees() {
List<Employee> rtn = new ArrayList<Employee>();
for (Map.Entry<String, Long> entry : employeeUserNameIndex.entrySet()) {
- rtn.add((Employee) get(entry.getValue()));
+ rtn.add((Employee)get(entry.getValue()));
}
return rtn;
}
@@ -107,22 +121,7 @@
return (Employee) get(id);
}
- @SuppressWarnings("unchecked")
- // We make runtime checks that return type matches in type
- synchronized <E extends Entity> E get(final E entity) {
- Entity previous = soup.get(entity.getId());
- if (null == previous) {
- throw new IllegalArgumentException(String.format("In %s, unknown id %d",
- entity, entity.getId()));
- }
- if (!previous.getClass().equals(entity.getClass())) {
- throw new IllegalArgumentException(String.format(
- "Type mismatch, fetched %s for %s", entity, previous));
- }
- return (E) previous;
- }
-
- private synchronized Entity get(Long id) {
+ synchronized private Entity get(Long id) {
return soup.get(id);
}
@@ -133,8 +132,7 @@
}
public Void visit(Employee employee) {
- if (null == employee.getUserName())
- return null;
+ if (null == employee.getUserName()) return null;
if (previous != null) {
Employee prevEmployee = (Employee) previous;
if (!prevEmployee.getUserName().equals(next)) {
diff --git a/bikeshed/src/com/google/gwt/sample/expenses/server/ExpensesDataServlet.java b/bikeshed/src/com/google/gwt/sample/expenses/server/ExpensesDataServlet.java
index 921c900..f452fcc 100644
--- a/bikeshed/src/com/google/gwt/sample/expenses/server/ExpensesDataServlet.java
+++ b/bikeshed/src/com/google/gwt/sample/expenses/server/ExpensesDataServlet.java
@@ -15,6 +15,13 @@
*/
package com.google.gwt.sample.expenses.server;
+import com.google.gwt.sample.expenses.domain.Employee;
+import com.google.gwt.sample.expenses.shared.MethodName;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
import java.io.IOException;
import java.io.PrintWriter;
@@ -33,8 +40,41 @@
response.setStatus(HttpServletResponse.SC_OK);
+ MethodName methodName = getMethodName(request.getParameter("methodName"));
PrintWriter writer = response.getWriter();
- writer.print("[ {USER_NAME: 'amitmanjhi', DISPLAY_NAME: 'Amit Manjhi'}, {USER_NAME: 'rjrjr', DISPLAY_NAME: 'Ray Ryan'}, {USER_NAME: 'jgw', DISPLAY_NAME: 'Joel Weber'} ]");
+ switch (methodName) {
+ case FIND_ALL_EMPLOYEES:
+ JSONArray jsonArray = new JSONArray();
+ for (Employee e : Employee.findAllEmployees()) {
+ try {
+ JSONObject jsonObject = new JSONObject();
+ jsonObject.put("USER_NAME", e.getUserName());
+ jsonObject.put("DISPLAY_NAME", e.getDisplayName());
+ jsonArray.put(jsonObject);
+ } catch (JSONException ex) {
+ System.err.println("Unable to create a JSON object " + ex);
+ }
+ }
+ writer.print(jsonArray.toString());
+ break;
+ case FIND_EMPLOYEE:
+ // TODO
+ break;
+ }
writer.flush();
}
+
+ /**
+ * @param request
+ * @return
+ */
+ private MethodName getMethodName(String methodString) {
+ for (MethodName method : MethodName.values()) {
+ if (method.name().equals(methodString)) {
+ return method;
+ }
+ }
+ throw new IllegalArgumentException("unknown methodName: " + methodString);
+ }
+
}
diff --git a/bikeshed/src/com/google/gwt/sample/expenses/shared/EmployeeRequests.java b/bikeshed/src/com/google/gwt/sample/expenses/shared/EmployeeRequests.java
index b9e2d8a..fa2ab39 100644
--- a/bikeshed/src/com/google/gwt/sample/expenses/shared/EmployeeRequests.java
+++ b/bikeshed/src/com/google/gwt/sample/expenses/shared/EmployeeRequests.java
@@ -15,25 +15,34 @@
*/
package com.google.gwt.sample.expenses.shared;
+import com.google.gwt.core.client.JsArray;
+import com.google.gwt.http.client.Request;
+import com.google.gwt.http.client.RequestBuilder;
+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.shared.Entity;
import com.google.gwt.requestfactory.shared.EntityListRequest;
+import com.google.gwt.sample.expenses.client.ValuesImpl;
import com.google.gwt.user.client.ui.HasValueList;
import com.google.gwt.valuestore.shared.Property;
import com.google.gwt.valuestore.shared.ValueStore;
import com.google.gwt.valuestore.shared.Values;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
/**
- * "Generated" from static methods of {@link com.google.gwt.sample.expenses.domain.Employee}
+ * "Generated" from static methods of
+ * {@link com.google.gwt.sample.expenses.domain.Employee}.
*/
public class EmployeeRequests {
private final ValueStore values;
- private int nextFutureId = -1;
private final Map<Object, Entity<?>> futures = new HashMap<Object, Entity<?>>();
@@ -51,9 +60,43 @@
private HasValueList<Values<Employee>> watcher;
public void fire() {
- Employee future = new Employee("" + nextFutureId--, null);
- futures.put(future.getId(), future);
- values.subscribe(watcher, future, properties);
+
+ // TODO: need someway to track that this request has been issued so that
+ // we don't issue another request that arrives while we are waiting for
+ // the response.
+ RequestBuilder builder = new RequestBuilder(RequestBuilder.GET,
+ "/expenses/data?methodName=" + MethodName.FIND_ALL_EMPLOYEES.name());
+ builder.setCallback(new RequestCallback() {
+
+ public void onError(Request request, Throwable exception) {
+ // shell.error.setInnerText(SERVER_ERROR);
+ }
+
+ public void onResponseReceived(Request request, Response response) {
+ if (200 == response.getStatusCode()) {
+ String text = response.getText();
+ JsArray<ValuesImpl<Employee>> valueArray = ValuesImpl.arrayFromJson(text);
+ List<Values<Employee>> valueList = new ArrayList<Values<Employee>>(
+ valueArray.length());
+ for (int i = 0; i < valueArray.length(); i++) {
+ valueList.add(valueArray.get(i));
+ }
+ watcher.setValueList(valueList);
+ } else {
+ // shell.error.setInnerText(SERVER_ERROR + " ("
+ // + response.getStatusText() + ")");
+ }
+ }
+ });
+
+ try {
+ builder.send();
+ } catch (RequestException e) {
+ // shell.error.setInnerText(SERVER_ERROR + " (" + e.getMessage() +
+ // ")");
+ }
+
+ // values.subscribe(watcher, future, properties);
// TODO(rjrjr) now make the call, and in the callback replace the future
// with the real id. No no no, no need for the future thing.
diff --git a/bikeshed/src/com/google/gwt/sample/expenses/shared/MethodName.java b/bikeshed/src/com/google/gwt/sample/expenses/shared/MethodName.java
new file mode 100644
index 0000000..ee4e809
--- /dev/null
+++ b/bikeshed/src/com/google/gwt/sample/expenses/shared/MethodName.java
@@ -0,0 +1,24 @@
+/*
+ * 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.sample.expenses.shared;
+
+/**
+ * Represents the MethodName.
+ */
+public enum MethodName {
+ FIND_ALL_EMPLOYEES,
+ FIND_EMPLOYEE,
+}
diff --git a/bikeshed/src/com/google/gwt/valuestore/shared/Path.java b/bikeshed/src/com/google/gwt/valuestore/shared/Path.java
index 44460e6..de1964e 100644
--- a/bikeshed/src/com/google/gwt/valuestore/shared/Path.java
+++ b/bikeshed/src/com/google/gwt/valuestore/shared/Path.java
@@ -18,17 +18,17 @@
import java.util.List;
/**
- * A path of entity properties.
+ * A path of entity properties.
*
- * @param <T>
- * @param <V>
+ * @param <T> The type of the property owner at the head of the path.
+ * @param <V> The value type of the last property in the path.
*/
public class Path<T, V> {
List<Property<?,?>> getProperties() {
return null;
}
- Property<T,V> getLastProperty() {
+ Property<?,V> getLastProperty() {
return null;
}
}
diff --git a/bikeshed/src/com/google/gwt/valuestore/shared/Property.java b/bikeshed/src/com/google/gwt/valuestore/shared/Property.java
index 4d55da0..75a4f0a 100644
--- a/bikeshed/src/com/google/gwt/valuestore/shared/Property.java
+++ b/bikeshed/src/com/google/gwt/valuestore/shared/Property.java
@@ -18,14 +18,14 @@
/**
* Represents a property of a type managed by {@link ValueStore}.
*
- * @param <T>
- * @param <V>
+ * @param <T> type of the property holder
+ * @param <V> type of the property
*/
public class Property<T, V> {
private final Class<T> propertyHolderType;
private final Class<V> valueType;
private final String name;
-
+
public Property(Class<T> propertyHolderType, Class<V> valueType, String name) {
this.propertyHolderType = propertyHolderType;
this.valueType = valueType;
@@ -45,7 +45,7 @@
public String getName() {
return name;
}
-
+
/**
* @return the valueClass
*/
diff --git a/bikeshed/war/WEB-INF/lib/json.jar b/bikeshed/war/WEB-INF/lib/json.jar
new file mode 100644
index 0000000..82ad5fb
--- /dev/null
+++ b/bikeshed/war/WEB-INF/lib/json.jar
Binary files differ