1) The service methods will now be annotated with a @ServerOperation. Used during code-gen.
2) The code generator now exists.
3) Other updates to the app code and gwt.xml to make use of the code generator.
Patch by: amitmanjhi
Review by: rjrjr (desk review)
Review at http://gwt-code-reviews.appspot.com/301801
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@7849 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/bikeshed/src/com/google/gwt/requestfactory/RequestFactory.gwt.xml b/bikeshed/src/com/google/gwt/requestfactory/RequestFactory.gwt.xml
index 79bbab5..495b94f 100644
--- a/bikeshed/src/com/google/gwt/requestfactory/RequestFactory.gwt.xml
+++ b/bikeshed/src/com/google/gwt/requestfactory/RequestFactory.gwt.xml
@@ -19,4 +19,7 @@
<source path="client"/>
<source path="shared"/>
+ <generate-with class="com.google.gwt.requestfactory.rebind.RequestFactoryGenerator">
+ <when-type-assignable class='com.google.gwt.requestfactory.shared.RequestFactory'/>
+ </generate-with>
</module>
diff --git a/bikeshed/src/com/google/gwt/requestfactory/client/impl/RequestFactoryJsonImpl.java b/bikeshed/src/com/google/gwt/requestfactory/client/impl/RequestFactoryJsonImpl.java
index 2eba95f..b013efd 100644
--- a/bikeshed/src/com/google/gwt/requestfactory/client/impl/RequestFactoryJsonImpl.java
+++ b/bikeshed/src/com/google/gwt/requestfactory/client/impl/RequestFactoryJsonImpl.java
@@ -15,6 +15,7 @@
*/
package com.google.gwt.requestfactory.client.impl;
+import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
@@ -33,13 +34,13 @@
*/
public class RequestFactoryJsonImpl implements RequestFactory {
- private final ValueStoreJsonImpl valueStore;
+ private ValueStoreJsonImpl valueStore;
/**
* @param valueStore
*/
- public RequestFactoryJsonImpl(ValueStoreJsonImpl valueStore) {
- this.valueStore = valueStore;
+ public void init(HandlerManager handlerManager) {
+ this.valueStore = new ValueStoreJsonImpl(handlerManager);
}
public void fire(final RequestObject requestObject) {
diff --git a/bikeshed/src/com/google/gwt/requestfactory/rebind/RequestFactoryGenerator.java b/bikeshed/src/com/google/gwt/requestfactory/rebind/RequestFactoryGenerator.java
new file mode 100644
index 0000000..f2d0fcb
--- /dev/null
+++ b/bikeshed/src/com/google/gwt/requestfactory/rebind/RequestFactoryGenerator.java
@@ -0,0 +1,310 @@
+/*
+ * 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.rebind;
+
+import com.google.gwt.core.ext.Generator;
+import com.google.gwt.core.ext.GeneratorContext;
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.typeinfo.JClassType;
+import com.google.gwt.core.ext.typeinfo.JMethod;
+import com.google.gwt.core.ext.typeinfo.JParameter;
+import com.google.gwt.core.ext.typeinfo.JParameterizedType;
+import com.google.gwt.core.ext.typeinfo.JType;
+import com.google.gwt.core.ext.typeinfo.TypeOracle;
+import com.google.gwt.requestfactory.client.gen.ClientRequestObject;
+import com.google.gwt.requestfactory.client.impl.AbstractListJsonRequestObject;
+import com.google.gwt.requestfactory.client.impl.RequestFactoryJsonImpl;
+import com.google.gwt.requestfactory.shared.EntityListRequest;
+import com.google.gwt.requestfactory.shared.ServerOperation;
+import com.google.gwt.requestfactory.shared.impl.RequestDataManager;
+import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
+import com.google.gwt.user.rebind.PrintWriterManager;
+import com.google.gwt.user.rebind.SourceWriter;
+import com.google.gwt.valuestore.client.ValueStoreJsonImpl;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Generates implementations of
+ * {@link com.google.gwt.requestfactory.shared.RequestFactory RequestFactory}
+ * and its nested interfaces.
+ */
+public class RequestFactoryGenerator extends Generator {
+
+ @Override
+ public String generate(TreeLogger logger, GeneratorContext generatorContext,
+ String interfaceName) throws UnableToCompleteException {
+ // The TypeOracle knows about all types in the type system
+ TypeOracle typeOracle = generatorContext.getTypeOracle();
+
+ // Get a reference to the type that the generator should implement
+ JClassType interfaceType = typeOracle.findType(interfaceName);
+
+ // Ensure that the requested type exists
+ if (interfaceType == null) {
+ logger.log(TreeLogger.ERROR, "Could not find requested typeName: "
+ + interfaceName);
+ throw new UnableToCompleteException();
+ }
+ if (interfaceType.isInterface() == null) {
+ // The incoming type wasn't a plain interface, we don't support
+ // abstract base classes
+ logger.log(TreeLogger.ERROR, interfaceType.getQualifiedSourceName()
+ + " is not an interface.", null);
+ throw new UnableToCompleteException();
+ }
+
+ String packageName = interfaceType.getPackage().getName();
+ PrintWriterManager printWriters = new PrintWriterManager(generatorContext,
+ logger, packageName);
+ // the replace protects against inner classes
+ String implName = interfaceType.getName().replace('.', '_') + "Impl";
+ PrintWriter out = printWriters.tryToMakePrintWriterFor(implName);
+
+ // If an implementation already exists, we don't need to do any work
+ if (out != null) {
+ generateOnce(logger, generatorContext, printWriters, out, interfaceType,
+ packageName, implName);
+ }
+
+ return packageName + "." + implName;
+ }
+
+ private void generateNestedInterfaceImplementation(TreeLogger logger,
+ GeneratorContext generatorContext, PrintWriter out,
+ JClassType interfaceType, JClassType mainType, String packageName,
+ String implName) throws UnableToCompleteException {
+ ClassSourceFileComposerFactory f = new ClassSourceFileComposerFactory(
+ packageName, implName);
+ f.addImport(ClientRequestObject.class.getName());
+ f.addImport(AbstractListJsonRequestObject.class.getName());
+ f.addImport(EntityListRequest.class.getName());
+ f.addImport(RequestDataManager.class.getName());
+
+ JClassType returnType = getReturnType(logger, interfaceType);
+ f.addImport(returnType.getQualifiedBinaryName());
+
+ f.addImport(mainType.getQualifiedBinaryName());
+ f.addImplementedInterface(interfaceType.getName());
+
+ // mainType
+ SourceWriter sw = f.createSourceWriter(generatorContext, out);
+ sw.println();
+
+ printRequestImplClass(sw, returnType);
+
+ sw.println("private final " + mainType.getName() + "Impl factory;");
+ sw.println();
+ // constructor for the class.
+ sw.println("public " + implName + "(" + mainType.getName()
+ + "Impl factory) {");
+ sw.indent();
+ sw.println("this.factory = factory;");
+ sw.outdent();
+ sw.println("}");
+ sw.println();
+
+ // write each method.
+ for (JMethod method : interfaceType.getMethods()) {
+ ServerOperation annotation = method.getAnnotation(ServerOperation.class);
+ if (annotation == null) {
+ logger.log(TreeLogger.ERROR, "no annotation on the service method "
+ + method);
+ throw new UnableToCompleteException();
+ }
+ sw.println(getMethodDeclaration(method) + " {");
+ sw.indent();
+ sw.println("return new RequestImpl() {");
+ sw.indent();
+ sw.println("public String getRequestData() {");
+ sw.indent();
+ sw.println("return " + ClientRequestObject.class.getSimpleName()
+ + ".getRequestString(" + RequestDataManager.class.getSimpleName()
+ + ".getRequestMap(\"" + annotation.value() + "\", "
+ + getParametersAsString(method) + ", null));");
+ sw.outdent();
+ sw.println("}");
+ sw.outdent();
+ sw.println("};");
+ sw.outdent();
+ sw.println("}");
+ }
+
+ sw.outdent();
+ sw.println("}");
+ }
+
+ private void generateOnce(TreeLogger logger,
+ GeneratorContext generatorContext, PrintWriterManager printWriters,
+ PrintWriter out, JClassType interfaceType, String packageName,
+ String implName) throws UnableToCompleteException {
+ ClassSourceFileComposerFactory f = new ClassSourceFileComposerFactory(
+ packageName, implName);
+ f.addImport(RequestFactoryJsonImpl.class.getName());
+ f.addImport(ValueStoreJsonImpl.class.getName());
+ f.addImplementedInterface(interfaceType.getQualifiedSourceName());
+ f.setSuperclass(RequestFactoryJsonImpl.class.getName());
+
+ SourceWriter sw = f.createSourceWriter(generatorContext, out);
+ sw.println();
+
+ // get the sub-interfaces
+ List<JClassType> nestedInterfaces = new ArrayList<JClassType>();
+ for (JClassType nestedType : interfaceType.getNestedTypes()) {
+ if (nestedType.isInterface() != null) {
+ nestedInterfaces.add(nestedType);
+ }
+ }
+ // write a method for each sub-interface
+ for (JClassType nestedInterface : nestedInterfaces) {
+ String simpleSourceName = nestedInterface.getSimpleSourceName();
+ sw.println("public " + simpleSourceName + " "
+ + getMethodName(simpleSourceName) + "() {");
+ sw.indent();
+ sw.println("return new " + simpleSourceName + "Impl(this);");
+ sw.outdent();
+ sw.println("}");
+ sw.println();
+ }
+ sw.outdent();
+ sw.println("}");
+
+ // generate an implementation for each nested interface
+ String interfacePrefix = interfaceType.getName() + ".";
+ for (JClassType nestedInterface : nestedInterfaces) {
+ String nestedImplName = nestedInterface.getName();
+ if (nestedImplName.startsWith(interfacePrefix)) {
+ nestedImplName = nestedImplName.substring(interfacePrefix.length(),
+ nestedImplName.length())
+ + "Impl";
+ }
+ PrintWriter pw = printWriters.makePrintWriterFor(nestedImplName);
+ if (pw != null) {
+ generateNestedInterfaceImplementation(logger, generatorContext, pw,
+ nestedInterface, interfaceType, packageName, nestedImplName);
+ }
+ }
+ printWriters.commit();
+ }
+
+ /**
+ * This method is very similar to {@link
+ * com.google.gwt.core.ext.typeinfo.JMethod.getReadableDeclaration()}. The
+ * only change is that each parameter is final.
+ */
+ private String getMethodDeclaration(JMethod method) {
+ StringBuilder sb = new StringBuilder("public ");
+ sb.append(method.getReturnType().getParameterizedQualifiedSourceName());
+ sb.append(" ");
+ sb.append(method.getName());
+ sb.append("(");
+
+ boolean needComma = false;
+ for (JParameter param : method.getParameters()) {
+ if (needComma) {
+ sb.append(", ");
+ } else {
+ needComma = true;
+ }
+ sb.append("final "); // so that an anonymous class can refer it
+ sb.append(param.getType().getParameterizedQualifiedSourceName());
+ sb.append(" ");
+ sb.append(param.getName());
+ }
+ sb.append(")");
+ return sb.toString();
+ }
+
+ private String getMethodName(String simpleSourceName) {
+ int length = simpleSourceName.length();
+ assert length > 0;
+ return Character.toLowerCase(simpleSourceName.charAt(0))
+ + simpleSourceName.substring(1, length);
+ }
+
+ /**
+ * Returns the string representation of the parameters to be passed to the
+ * server side method.
+ */
+ private String getParametersAsString(JMethod method) {
+ StringBuilder sb = new StringBuilder();
+ for (JParameter parameter : method.getParameters()) {
+ if (sb.length() > 0) {
+ sb.append(", ");
+ }
+ sb.append(parameter.getName());
+ if ("com.google.gwt.valuestore.shared.ValueRef".equals(parameter.getType().getQualifiedBinaryName())) {
+ sb.append(".get()");
+ }
+ }
+ return "new Object[] {" + sb.toString() + "}";
+ }
+
+ /**
+ * Inspect all the get methods that are returning a List of "domain type".
+ * Return the domain type.
+ * <p>
+ * TODO: Lift the restriction that there be just one return type.
+ */
+ private JClassType getReturnType(TreeLogger logger, JClassType interfaceType)
+ throws UnableToCompleteException {
+ Set<JClassType> returnTypes = new HashSet<JClassType>();
+ for (JMethod method : interfaceType.getMethods()) {
+ JType returnType = method.getReturnType();
+ if (returnType instanceof JParameterizedType) {
+ for (JClassType typeArg : ((JParameterizedType) returnType).getTypeArgs()) {
+ returnTypes.add(typeArg);
+ }
+ }
+ }
+ if (returnTypes.size() != 1) {
+ logger.log(TreeLogger.ERROR, "Methods return objects of different types");
+ throw new UnableToCompleteException();
+ }
+ return returnTypes.toArray(new JClassType[0])[0];
+ }
+
+ /**
+ * Prints the RequestImpl class.
+ */
+ private void printRequestImplClass(SourceWriter sw, JClassType returnType) {
+ sw.println("private abstract class RequestImpl extends "
+ + AbstractListJsonRequestObject.class.getSimpleName() + "<"
+ + returnType.getName() + ",RequestImpl> {");
+ sw.println();
+ sw.indent();
+ sw.println("RequestImpl() {");
+ sw.indent();
+ sw.println("super(" + returnType.getName() + ".get(), factory);");
+ sw.outdent();
+ sw.println("}");
+ sw.println();
+ sw.println("@Override");
+ sw.println("protected RequestImpl getThis() {");
+ sw.indent();
+ sw.println("return this;");
+ sw.outdent();
+ sw.println("}");
+ sw.outdent();
+ sw.println("}");
+ sw.println();
+ }
+}
diff --git a/bikeshed/src/com/google/gwt/requestfactory/shared/RequestFactory.java b/bikeshed/src/com/google/gwt/requestfactory/shared/RequestFactory.java
index f13ddbd..1cdb8bd 100644
--- a/bikeshed/src/com/google/gwt/requestfactory/shared/RequestFactory.java
+++ b/bikeshed/src/com/google/gwt/requestfactory/shared/RequestFactory.java
@@ -15,6 +15,7 @@
*/
package com.google.gwt.requestfactory.shared;
+import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.valuestore.shared.DeltaValueStore;
import com.google.gwt.valuestore.shared.ValueStore;
import com.google.gwt.valuestore.shared.ValuesKey;
@@ -44,6 +45,8 @@
ValueStore getValueStore();
+ void init(HandlerManager handlerManager);
+
SyncRequest syncRequest(DeltaValueStore deltaValueStore);
/**
diff --git a/bikeshed/src/com/google/gwt/requestfactory/shared/ServerOperation.java b/bikeshed/src/com/google/gwt/requestfactory/shared/ServerOperation.java
new file mode 100644
index 0000000..4e85abe
--- /dev/null
+++ b/bikeshed/src/com/google/gwt/requestfactory/shared/ServerOperation.java
@@ -0,0 +1,26 @@
+/*
+ * 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;
+
+/**
+ * Annotation to mark RPC methods that specifies details about the operation to
+ * be invoked on the server.
+ */
+public @interface ServerOperation {
+
+ String value();
+
+}
diff --git a/bikeshed/src/com/google/gwt/sample/expenses/Expenses.gwt.xml b/bikeshed/src/com/google/gwt/sample/expenses/Expenses.gwt.xml
index d71754e..9f46f26 100644
--- a/bikeshed/src/com/google/gwt/sample/expenses/Expenses.gwt.xml
+++ b/bikeshed/src/com/google/gwt/sample/expenses/Expenses.gwt.xml
@@ -16,5 +16,4 @@
<source path='client'/>
<source path='shared'/>
<source path='gen'/>
-
</module>
diff --git a/bikeshed/src/com/google/gwt/sample/expenses/ExpensesScaffold.gwt.xml b/bikeshed/src/com/google/gwt/sample/expenses/ExpensesScaffold.gwt.xml
index 07e5eee..30e7a84 100644
--- a/bikeshed/src/com/google/gwt/sample/expenses/ExpensesScaffold.gwt.xml
+++ b/bikeshed/src/com/google/gwt/sample/expenses/ExpensesScaffold.gwt.xml
@@ -14,10 +14,4 @@
<source path='gen' />
<entry-point
class="com.google.gwt.sample.expenses.client.ExpensesScaffold" />
-
- <!-- TODO: generate-with -->
- <replace-with class='com.google.gwt.sample.expenses.gen.ExpenseRequestFactoryImpl'>
- <when-type-is class='com.google.gwt.sample.expenses.shared.ExpenseRequestFactory'/>
- </replace-with>
-
</module>
\ No newline at end of file
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 0e99527..7124305 100644
--- a/bikeshed/src/com/google/gwt/sample/expenses/client/Expenses.java
+++ b/bikeshed/src/com/google/gwt/sample/expenses/client/Expenses.java
@@ -16,13 +16,13 @@
package com.google.gwt.sample.expenses.client;
import com.google.gwt.core.client.EntryPoint;
+import com.google.gwt.core.client.GWT;
import com.google.gwt.event.shared.HandlerManager;
-import com.google.gwt.sample.expenses.gen.ExpenseRequestFactoryImpl;
import com.google.gwt.sample.expenses.shared.EmployeeKey;
+import com.google.gwt.sample.expenses.shared.ExpenseRequestFactory;
import com.google.gwt.sample.expenses.shared.ReportChanged;
import com.google.gwt.sample.expenses.shared.ReportKey;
import com.google.gwt.user.client.ui.RootLayoutPanel;
-import com.google.gwt.valuestore.client.ValueStoreJsonImpl;
import com.google.gwt.valuestore.shared.DeltaValueStore;
import com.google.gwt.valuestore.shared.Property;
import com.google.gwt.valuestore.shared.Values;
@@ -44,9 +44,8 @@
*/
public void onModuleLoad() {
final HandlerManager eventBus = new HandlerManager(null);
- final ValueStoreJsonImpl valueStore = new ValueStoreJsonImpl(eventBus);
- final ExpenseRequestFactoryImpl requestFactory = new ExpenseRequestFactoryImpl(
- valueStore);
+ final ExpenseRequestFactory requestFactory = GWT.create(ExpenseRequestFactory.class);
+ requestFactory.init(eventBus);
RootLayoutPanel root = RootLayoutPanel.get();
diff --git a/bikeshed/src/com/google/gwt/sample/expenses/client/ExpensesScaffold.java b/bikeshed/src/com/google/gwt/sample/expenses/client/ExpensesScaffold.java
index 925a0ac..6e70c09 100644
--- a/bikeshed/src/com/google/gwt/sample/expenses/client/ExpensesScaffold.java
+++ b/bikeshed/src/com/google/gwt/sample/expenses/client/ExpensesScaffold.java
@@ -19,16 +19,16 @@
import com.google.gwt.app.place.PlaceController;
import com.google.gwt.app.place.PlacePicker;
import com.google.gwt.core.client.EntryPoint;
+import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.sample.expenses.client.place.AbstractExpensesPlace;
import com.google.gwt.sample.expenses.client.place.EntityListPlace;
import com.google.gwt.sample.expenses.client.place.Places;
-import com.google.gwt.sample.expenses.gen.ExpenseRequestFactoryImpl;
+import com.google.gwt.sample.expenses.shared.ExpenseRequestFactory;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.RootLayoutPanel;
-import com.google.gwt.valuestore.client.ValueStoreJsonImpl;
/**
* Application for browsing the entities of the Expenses app.
@@ -39,8 +39,9 @@
// App controllers and services
final HandlerManager eventBus = new HandlerManager(null);
- final ValueStoreJsonImpl valueStore = new ValueStoreJsonImpl(eventBus);
- final ExpenseRequestFactoryImpl requests = new ExpenseRequestFactoryImpl(valueStore);
+ final ExpenseRequestFactory requests = GWT.create(ExpenseRequestFactory.class);
+ requests.init(eventBus);
+
final PlaceController<AbstractExpensesPlace> placeController = new PlaceController<AbstractExpensesPlace>(
eventBus);
final Places places = new Places(placeController);
diff --git a/bikeshed/src/com/google/gwt/sample/expenses/gen/EmployeeRequestImpl.java b/bikeshed/src/com/google/gwt/sample/expenses/gen/EmployeeRequestImpl.java
deleted file mode 100644
index ec5622b..0000000
--- a/bikeshed/src/com/google/gwt/sample/expenses/gen/EmployeeRequestImpl.java
+++ /dev/null
@@ -1,61 +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.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.impl.RequestDataManager;
-import com.google.gwt.sample.expenses.shared.EmployeeKey;
-import com.google.gwt.sample.expenses.shared.ExpenseRequestFactory;
-
-/**
- * "Code generated" implementation of {ExpenseRequestFactory.EmployeeRequest}.
- * <p>
- * IRL this will be generated as a side effect of a call to
- * GWT.create(ExpenseRequestFactory.class)
- */
-public class EmployeeRequestImpl implements
- ExpenseRequestFactory.EmployeeRequest {
-
- private abstract class RequestImpl extends
- AbstractListJsonRequestObject<EmployeeKey, RequestImpl> {
-
- RequestImpl() {
- super(EmployeeKey.get(), factory);
- }
-
- @Override
- protected RequestImpl getThis() {
- return this;
- }
- }
-
- private final ExpenseRequestFactoryImpl factory;
-
- public EmployeeRequestImpl(ExpenseRequestFactoryImpl factory) {
- this.factory = factory;
- }
-
- public EntityListRequest<EmployeeKey> findAllEmployees() {
- return new RequestImpl() {
- public String getRequestData() {
- return ClientRequestObject.getRequestString(RequestDataManager.getRequestMap(
- ExpenseRequestFactory.ServerSideOperation.FIND_ALL_EMPLOYEES.name(), null, null));
- }
- };
- }
-}
diff --git a/bikeshed/src/com/google/gwt/sample/expenses/gen/ExpenseRequestFactoryImpl.java b/bikeshed/src/com/google/gwt/sample/expenses/gen/ExpenseRequestFactoryImpl.java
deleted file mode 100644
index ce04301..0000000
--- a/bikeshed/src/com/google/gwt/sample/expenses/gen/ExpenseRequestFactoryImpl.java
+++ /dev/null
@@ -1,43 +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.sample.expenses.gen;
-
-import com.google.gwt.requestfactory.client.impl.RequestFactoryJsonImpl;
-import com.google.gwt.sample.expenses.shared.ExpenseRequestFactory;
-import com.google.gwt.valuestore.client.ValueStoreJsonImpl;
-
-/**
- * "Code generated" factory for requests against
- * com.google.gwt.sample.expenses.domain.
- * <p>
- * IRL this will be generated by a call to
- * GWT.create(ExpenseRequestFactory.class)
- */
-public class ExpenseRequestFactoryImpl extends RequestFactoryJsonImpl implements
- ExpenseRequestFactory {
-
- public ExpenseRequestFactoryImpl(ValueStoreJsonImpl valueStore) {
- super(valueStore);
- }
-
- public EmployeeRequest employeeRequest() {
- return new EmployeeRequestImpl(this);
- }
-
- public ReportRequest reportRequest() {
- return new ReportRequestImpl(this);
- }
-}
diff --git a/bikeshed/src/com/google/gwt/sample/expenses/gen/ReportRequestImpl.java b/bikeshed/src/com/google/gwt/sample/expenses/gen/ReportRequestImpl.java
deleted file mode 100644
index c340856..0000000
--- a/bikeshed/src/com/google/gwt/sample/expenses/gen/ReportRequestImpl.java
+++ /dev/null
@@ -1,75 +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.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.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;
-import com.google.gwt.valuestore.shared.ValueRef;
-
-/**
- * "Code generated" implementation of {ExpenseRequestFactory.ReportRequest}.
- * <p>
- * IRL this will be generated as a side effect of a call to
- * GWT.create(ExpenseRequestFactory.class)
- */
-public class ReportRequestImpl implements ExpenseRequestFactory.ReportRequest {
-
- private abstract class RequestImpl extends
- AbstractListJsonRequestObject<ReportKey, RequestImpl> {
-
- RequestImpl() {
- super(ReportKey.get(), requestFactory);
- }
-
- @Override
- protected RequestImpl getThis() {
- return this;
- }
- }
-
- private final ExpenseRequestFactoryImpl requestFactory;
-
- public ReportRequestImpl(ExpenseRequestFactoryImpl requestFactory) {
- this.requestFactory = requestFactory;
- }
-
- public EntityListRequest<ReportKey> findAllReports() {
- return new RequestImpl() {
- public String getRequestData() {
- return ClientRequestObject.getRequestString(RequestDataManager.getRequestMap(
- ExpenseRequestFactory.ServerSideOperation.FIND_ALL_REPORTS.name(), null,
- null));
- }
-
- };
- };
-
- public EntityListRequest<ReportKey> findReportsByEmployee(
- final ValueRef<EmployeeKey, String> id) {
- return new RequestImpl() {
- public String getRequestData() {
- return ClientRequestObject.getRequestString(RequestDataManager.getRequestMap(
- ExpenseRequestFactory.ServerSideOperation.FIND_REPORTS_BY_EMPLOYEE.name(),
- new Object[] {id.get()}, null));
- }
- };
- }
-}
diff --git a/bikeshed/src/com/google/gwt/sample/expenses/shared/ExpenseRequestFactory.java b/bikeshed/src/com/google/gwt/sample/expenses/shared/ExpenseRequestFactory.java
index ca5beca..280df5f 100644
--- a/bikeshed/src/com/google/gwt/sample/expenses/shared/ExpenseRequestFactory.java
+++ b/bikeshed/src/com/google/gwt/sample/expenses/shared/ExpenseRequestFactory.java
@@ -18,6 +18,7 @@
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;
@@ -38,6 +39,7 @@
/**
* @return a request object
*/
+ @ServerOperation("FIND_ALL_EMPLOYEES")
EntityListRequest<EmployeeKey> findAllEmployees();
}
@@ -49,12 +51,14 @@
/**
* @return a request object
*/
+ @ServerOperation("FIND_REPORTS_BY_EMPLOYEE")
EntityListRequest<ReportKey> findReportsByEmployee(
@LongString ValueRef<EmployeeKey, String> id);
/**
* @return a request object
*/
+ @ServerOperation("FIND_ALL_REPORTS")
EntityListRequest<ReportKey> findAllReports();
}
@@ -70,9 +74,6 @@
FIND_ALL_REPORTS("com.google.gwt.sample.expenses.server.domain.Report",
"findAllReports", null,
com.google.gwt.sample.expenses.shared.ReportKey.class), //
- FIND_EMPLOYEE("com.google.gwt.sample.expenses.server.domain.Employee",
- "findEmployee", new Class[] {java.lang.Long.class},
- com.google.gwt.sample.expenses.shared.EmployeeKey.class), //
FIND_REPORTS_BY_EMPLOYEE(
"com.google.gwt.sample.expenses.server.domain.Report",
"findReportsByEmployee", new Class[] {java.lang.Long.class},
diff --git a/bikeshed/src/com/google/gwt/user/rebind/PrintWriterManager.java b/bikeshed/src/com/google/gwt/user/rebind/PrintWriterManager.java
new file mode 100644
index 0000000..0e65299
--- /dev/null
+++ b/bikeshed/src/com/google/gwt/user/rebind/PrintWriterManager.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2009 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.user.rebind;
+
+import com.google.gwt.core.ext.GeneratorContext;
+import com.google.gwt.core.ext.TreeLogger;
+
+import java.io.PrintWriter;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Factory for printwriters creating source files in a particular package.
+ */
+public class PrintWriterManager {
+ private final GeneratorContext genCtx;
+ private final String packageName;
+ private final TreeLogger logger;
+ private final Set<PrintWriter> writers = new HashSet<PrintWriter>();
+
+ public PrintWriterManager(GeneratorContext genCtx, TreeLogger logger,
+ String packageName) {
+ this.genCtx = genCtx;
+ this.packageName = packageName;
+ this.logger = logger;
+ }
+
+ /**
+ * Commit all writers we have vended.
+ */
+ public void commit() {
+ for (PrintWriter writer : writers) {
+ genCtx.commit(logger, writer);
+ }
+ }
+
+ /**
+ * @param name classname
+ * @return the printwriter
+ * @throws RuntimeException if this class has already been written
+ */
+ public PrintWriter makePrintWriterFor(String name) {
+ PrintWriter writer = tryToMakePrintWriterFor(name);
+ if (writer == null) {
+ throw new RuntimeException(String.format("Tried to write %s.%s twice.",
+ packageName, name));
+ }
+ return writer;
+ }
+
+ /**
+ * @param name classname
+ * @return the printwriter, or null if this class has already been written
+ */
+ public PrintWriter tryToMakePrintWriterFor(String name) {
+ PrintWriter writer = genCtx.tryCreate(logger, packageName, name);
+ if (writer != null) {
+ writers.add(writer);
+ }
+ return writer;
+ }
+}