Revision: 7882
Author: [email protected]
Date: Mon Apr 5 15:30:42 2010
Log: Config class no longer so monolithic.
Review at http://gwt-code-reviews.appspot.com/310802
Review by: [email protected]
http://code.google.com/p/google-web-toolkit/source/detail?r=7882
Modified:
/trunk/bikeshed/src/com/google/gwt/requestfactory/server/RequestFactoryServlet.java
/trunk/bikeshed/src/com/google/gwt/requestfactory/shared/RequestFactory.java
/trunk/bikeshed/src/com/google/gwt/sample/expenses/gwt/request/EmployeeRequest.java
/trunk/bikeshed/src/com/google/gwt/sample/expenses/gwt/request/ExpensesServerSideOperations.java
/trunk/bikeshed/src/com/google/gwt/sample/expenses/gwt/request/ReportRequest.java
/trunk/bikeshed/war/WEB-INF/web.xml
=======================================
---
/trunk/bikeshed/src/com/google/gwt/requestfactory/server/RequestFactoryServlet.java
Fri Apr 2 16:51:38 2010
+++
/trunk/bikeshed/src/com/google/gwt/requestfactory/server/RequestFactoryServlet.java
Mon Apr 5 15:30:42 2010
@@ -16,6 +16,7 @@
package com.google.gwt.requestfactory.server;
import com.google.gwt.requestfactory.shared.RequestFactory;
+import com.google.gwt.requestfactory.shared.RequestFactory.Config;
import
com.google.gwt.requestfactory.shared.RequestFactory.RequestDefinition;
import com.google.gwt.requestfactory.shared.impl.RequestDataManager;
import com.google.gwt.valuestore.shared.Property;
@@ -43,15 +44,16 @@
import javax.servlet.http.HttpServletResponse;
/**
- * Handles GWT RequestFactory requests. Configured via servlet context
param
- * servlet.serverOperation, which must be set to the fully qualified name
of an
- * enum implementing {...@link RequestDefinition}.
+ * Handles GWT RequestFactory JSON requests. Configured via servlet context
+ * param <code>servlet.serverOperation</code>, which must be set to the
name of a default
+ * instantiable class implementing
+ * com.google.gwt.requestfactory.shared.RequestFactory.Config.
* <p>
* e.g.
*
* <pre> <context-param>
<param-name>servlet.serverOperation</param-name>
-
<param-value>com.google.gwt.sample.expenses.shared.ExpenseRequestFactory$ServerSideOperation</param-value>
+
<param-value>com.myco.myapp.MyAppServerSideOperations</param-value>
</context-param>
* </pre>
@@ -68,6 +70,8 @@
PROPERTY_SET.add(str);
}
}
+
+ private Config config;
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse
response)
@@ -83,8 +87,7 @@
sync(topLevelJsonObject.getString(RequestDataManager.CONTENT_TOKEN),
writer);
} else {
-
- operation = getOperationFromName(operationName, getConfigClass());
+ operation = getOperation(operationName);
Class<?> domainClass =
Class.forName(operation.getDomainClassName());
Method domainMethod = domainClass.getMethod(
operation.getDomainMethodName(),
operation.getParameterTypes());
@@ -122,8 +125,9 @@
}
/**
- * Allows subclass to provide hack implementation. TODO real reflection
based
- * implsementation.
+ * Allows subclass to provide hack implementation.
+ * <p>
+ * TODO real reflection based implementation.
*/
@SuppressWarnings("unused")
protected void sync(String content, PrintWriter writer) {
@@ -131,25 +135,49 @@
}
@SuppressWarnings("unchecked")
- private Class<? extends RequestDefinition> getConfigClass() {
- try {
- final String serverOperation = getServletContext().getInitParameter(
- SERVER_OPERATION_CONTEXT_PARAM);
- if (null == serverOperation) {
- throw new IllegalStateException(String.format(
- "Context parameter \"%s\" must name an enum implementing %s",
- SERVER_OPERATION_CONTEXT_PARAM,
RequestDefinition.class.getName()));
- }
- Class<?> clazz = Class.forName(serverOperation);
- if (!RequestDefinition.class.isAssignableFrom(clazz)) {
- throw new RuntimeException(serverOperation + " must implement "
- + RequestDefinition.class.getName());
- }
- return (Class<? extends RequestDefinition>) clazz;
- } catch (ClassNotFoundException e) {
- throw new RuntimeException(e);
+ private void ensureConfig() {
+ if (config == null) {
+ synchronized (this) {
+ if (config != null) {
+ return;
+ }
+ try {
+ final String serverOperation =
getServletContext().getInitParameter(
+ SERVER_OPERATION_CONTEXT_PARAM);
+ if (null == serverOperation) {
+ failConfig();
+ }
+ Class<?> clazz = Class.forName(serverOperation);
+ if (Config.class.isAssignableFrom(clazz)) {
+ config = ((Class<? extends Config>) clazz).newInstance();
+ }
+
+ } catch (ClassNotFoundException e) {
+ failConfig(e);
+ } catch (InstantiationException e) {
+ failConfig(e);
+ } catch (IllegalAccessException e) {
+ failConfig(e);
+ } catch (SecurityException e) {
+ failConfig(e);
+ } catch (ClassCastException e) {
+ failConfig(e);
+ }
+ }
}
}
+
+ private void failConfig() {
+ failConfig(null);
+ }
+
+ private void failConfig(Throwable e) {
+ final String message = String.format("Context parameter \"%s\" must
name "
+ + "a default instantiable configuration class implementing %s",
+ SERVER_OPERATION_CONTEXT_PARAM,
RequestFactory.Config.class.getName());
+
+ throw new IllegalStateException(message, e);
+ }
private String getContent(HttpServletRequest request) throws IOException
{
int contentLength = request.getContentLength();
@@ -211,16 +239,15 @@
return methodName.toString();
}
- private RequestDefinition getOperationFromName(String operationName,
- Class<? extends RequestDefinition> enumClass) throws
SecurityException,
- IllegalAccessException, InvocationTargetException,
NoSuchMethodException {
- for (RequestDefinition operation : ((RequestDefinition[])
enumClass.getMethod(
- "values").invoke(null))) {
- if (operation.name().equals(operationName)) {
- return operation;
- }
- }
- throw new IllegalArgumentException("Unknown operation " +
operationName);
+ private RequestDefinition getOperation(String operationName) {
+ RequestDefinition operation;
+ ensureConfig();
+ operation = config.requestDefinitions().get(operationName);
+ if (null == operation) {
+ throw new IllegalArgumentException("Unknown operation "
+ + operationName);
+ }
+ return operation;
}
/**
=======================================
---
/trunk/bikeshed/src/com/google/gwt/requestfactory/shared/RequestFactory.java
Thu Apr 1 12:25:39 2010
+++
/trunk/bikeshed/src/com/google/gwt/requestfactory/shared/RequestFactory.java
Mon Apr 5 15:30:42 2010
@@ -16,49 +16,31 @@
package com.google.gwt.requestfactory.shared;
import com.google.gwt.event.shared.HandlerManager;
+import com.google.gwt.requestfactory.server.RequestFactoryServlet;
import com.google.gwt.valuestore.shared.DeltaValueStore;
import com.google.gwt.valuestore.shared.ValueStore;
import com.google.gwt.valuestore.shared.ValuesKey;
+import java.util.Map;
+
/**
* Marker interface for the RequestFactory code generator.
*/
public interface RequestFactory {
- String URL = "/expenses/data";
-
- /*
- * eventually, this will become an enum of update operations.
- */
- String UPDATE_STRING = "SYNC";
-
/**
- * Implemented by the request objects created by this factory.
+ * Implemented by the configuration class used by
+ * {...@link RequestFactoryServlet}.
*/
- interface RequestObject {
- void fire();
-
- String getRequestData();
-
- void handleResponseText(String responseText);
- }
-
- ValueStore getValueStore();
-
- void init(HandlerManager handlerManager);
-
- SyncRequest syncRequest(DeltaValueStore deltaValueStore);
+ interface Config {
+ Map<String, RequestDefinition> requestDefinitions();
+ }
/**
- * Implemented by the enum that defines the mapping between request
objects
- * and service methods.
+ * Implemented by enums that defines the mapping between request objects
and
+ * service methods.
*/
interface RequestDefinition {
- /**
- * Returns the name.
- */
- String name();
-
/**
* Returns the name of the (domain) class that contains the method to
be
* invoked on the server.
@@ -79,5 +61,34 @@
* Returns the return type of the method to be invoked on the server.
*/
Class<? extends ValuesKey<?>> getReturnType();
- }
-}
+
+ /**
+ * Returns the name.
+ */
+ String name();
+ }
+
+ /**
+ * Implemented by the request objects created by this factory.
+ */
+ interface RequestObject {
+ void fire();
+
+ String getRequestData();
+
+ void handleResponseText(String responseText);
+ }
+
+ String URL = "/expenses/data";
+
+ /*
+ * eventually, this will become an enum of update operations.
+ */
+ String UPDATE_STRING = "SYNC";
+
+ ValueStore getValueStore();
+
+ void init(HandlerManager handlerManager);
+
+ SyncRequest syncRequest(DeltaValueStore deltaValueStore);
+}
=======================================
---
/trunk/bikeshed/src/com/google/gwt/sample/expenses/gwt/request/EmployeeRequest.java
Mon Apr 5 10:10:06 2010
+++
/trunk/bikeshed/src/com/google/gwt/sample/expenses/gwt/request/EmployeeRequest.java
Mon Apr 5 15:30:42 2010
@@ -16,12 +16,33 @@
package com.google.gwt.sample.expenses.gwt.request;
import com.google.gwt.requestfactory.shared.EntityListRequest;
+import com.google.gwt.requestfactory.shared.RequestFactory;
import com.google.gwt.requestfactory.shared.ServerOperation;
+import com.google.gwt.valuestore.shared.ValuesKey;
/**
* Request selector.
*/
public interface EmployeeRequest {
+ public enum ServerOperations implements RequestFactory.RequestDefinition
{
+ FIND_ALL_EMPLOYEES {
+ public String getDomainMethodName() {
+ return "findAllEmployees";
+ }
+
+ public Class<? extends ValuesKey<?>> getReturnType() {
+ return
com.google.gwt.sample.expenses.gwt.request.EmployeeKey.class;
+ }
+ };
+
+ public String getDomainClassName() {
+ return "com.google.gwt.sample.expenses.server.domain.Employee";
+ }
+
+ public Class<?>[] getParameterTypes() {
+ return null;
+ }
+ }
/**
* @return a request object
=======================================
---
/trunk/bikeshed/src/com/google/gwt/sample/expenses/gwt/request/ExpensesServerSideOperations.java
Mon Apr 5 10:10:06 2010
+++
/trunk/bikeshed/src/com/google/gwt/sample/expenses/gwt/request/ExpensesServerSideOperations.java
Mon Apr 5 15:30:42 2010
@@ -15,67 +15,38 @@
*/
package com.google.gwt.sample.expenses.gwt.request;
+import com.google.gwt.requestfactory.shared.RequestFactory.Config;
import
com.google.gwt.requestfactory.shared.RequestFactory.RequestDefinition;
-import com.google.gwt.valuestore.shared.ValuesKey;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
/**
- * Represents the server side operation to be carried out. This enum will
be
- * generated by the JPA-aware tool.
+ * Configuration class for
+ * {...@link com.google.gwt.requestfactory.server.RequestFactoryServlet
+ * RequestFactoryServlet}
*/
-public enum ExpensesServerSideOperations implements RequestDefinition {
-
FIND_ALL_EMPLOYEES("com.google.gwt.sample.expenses.server.domain.Employee",
- "findAllEmployees", null,
- com.google.gwt.sample.expenses.gwt.request.EmployeeKey.class), //
- FIND_ALL_REPORTS("com.google.gwt.sample.expenses.server.domain.Report",
- "findAllReports", null,
- com.google.gwt.sample.expenses.gwt.request.ReportKey.class), //
- FIND_REPORTS_BY_EMPLOYEE(
- "com.google.gwt.sample.expenses.server.domain.Report",
- "findReportsByEmployee", new Class[] {java.lang.Long.class},
- com.google.gwt.sample.expenses.gwt.request.ReportKey.class); //
-
- /**
- * the server side domain class.
- */
- private final String domainClassName;
-
- /**
- * the methodName of the domain class that is to be invoked.
- */
- private final String domainMethodName;
-
- /**
- * the parameterTypes of the parameters the domain method requires.
- */
- private final Class<?>[] parameterTypes;
-
- /**
- * for "READ" methods, the methods return a List. This class denotes the
types
- * of the elements of the list.
- */
- private final Class<? extends ValuesKey<?>> returnType;
-
- private ExpensesServerSideOperations(String domainClassName, String
domainMethodName,
- Class<?> parameterTypes[], Class<? extends ValuesKey<?>>
entryReturnType) {
- this.domainClassName = domainClassName;
- this.domainMethodName = domainMethodName;
- this.parameterTypes = parameterTypes;
- this.returnType = entryReturnType;
+public class ExpensesServerSideOperations implements Config {
+
+ private static void putAll(RequestDefinition[] values,
+ Map<String, RequestDefinition> newMap) {
+ for (RequestDefinition def : values) {
+ newMap.put(def.name(), def);
+ }
}
- public String getDomainClassName() {
- return domainClassName;
- }
-
- public String getDomainMethodName() {
- return domainMethodName;
+ private final Map<String, RequestDefinition> map;
+
+ public ExpensesServerSideOperations() {
+ Map<String, RequestDefinition> newMap = new HashMap<String,
RequestDefinition>();
+ putAll(EmployeeRequest.ServerOperations.values(), newMap);
+ putAll(ReportRequest.ServerOperations.values(), newMap);
+ map = Collections.unmodifiableMap(newMap);
}
- public Class<?>[] getParameterTypes() {
- return parameterTypes;
+ public Map<String, RequestDefinition> requestDefinitions() {
+ return map;
}
- public Class<? extends ValuesKey<?>> getReturnType() {
- return returnType;
- }
-}
+}
=======================================
---
/trunk/bikeshed/src/com/google/gwt/sample/expenses/gwt/request/ReportRequest.java
Mon Apr 5 10:10:06 2010
+++
/trunk/bikeshed/src/com/google/gwt/sample/expenses/gwt/request/ReportRequest.java
Mon Apr 5 15:30:42 2010
@@ -17,13 +17,48 @@
import com.google.gwt.requestfactory.shared.EntityListRequest;
import com.google.gwt.requestfactory.shared.LongString;
+import com.google.gwt.requestfactory.shared.RequestFactory;
import com.google.gwt.requestfactory.shared.ServerOperation;
import com.google.gwt.valuestore.shared.ValueRef;
+import com.google.gwt.valuestore.shared.ValuesKey;
/**
* Request selector.
*/
public interface ReportRequest {
+ public enum ServerOperations implements RequestFactory.RequestDefinition
{
+ FIND_REPORTS_BY_EMPLOYEE {
+ public String getDomainMethodName() {
+ return "findReportsByEmployee";
+ }
+
+ public Class<?>[] getParameterTypes() {
+ return new Class[] { java.lang.Long.class };
+ }
+
+ public Class<? extends ValuesKey<?>> getReturnType() {
+ return com.google.gwt.sample.expenses.gwt.request.ReportKey.class;
+ }
+ },
+
+ FIND_ALL_REPORTS {
+ public String getDomainMethodName() {
+ return "findAllReports";
+ }
+
+ public Class<? extends ValuesKey<?>> getReturnType() {
+ return com.google.gwt.sample.expenses.gwt.request.ReportKey.class;
+ }
+ };
+
+ public String getDomainClassName() {
+ return "com.google.gwt.sample.expenses.server.domain.Report";
+ }
+
+ public Class<?>[] getParameterTypes() {
+ return null;
+ }
+ }
/**
* @return a request object
=======================================
--- /trunk/bikeshed/war/WEB-INF/web.xml Mon Apr 5 10:10:06 2010
+++ /trunk/bikeshed/war/WEB-INF/web.xml Mon Apr 5 15:30:42 2010
@@ -8,7 +8,7 @@
<!-- Configures expensesData servlet -->
<context-param>
<param-name>servlet.serverOperation</param-name>
-
<param-value>com.google.gwt.sample.expenses.gwt.request.ExpensesRequests</param-value>
+
<param-value>com.google.gwt.sample.expenses.gwt.request.ExpensesServerSideOperations</param-value>
</context-param>
<!-- Servlets -->
--
http://groups.google.com/group/Google-Web-Toolkit-Contributors
To unsubscribe, reply using "remove me" as the subject.