Revision: 9880
Author:   [email protected]
Date:     Wed Mar 23 09:23:21 2011
Log: Fixing issue 5807 on server side, new issue due to rietveld problems
Formerly at 1384802

Review at http://gwt-code-reviews.appspot.com/1384806

http://code.google.com/p/google-web-toolkit/source/detail?r=9880

Added:
/trunk/user/test/com/google/gwt/requestfactory/server/ServiceInheritanceJreTest.java /trunk/user/test/com/google/gwt/requestfactory/shared/ServiceInheritanceTest.java
Modified:
/trunk/user/src/com/google/gwt/requestfactory/server/LocatorServiceLayer.java /trunk/user/src/com/google/gwt/requestfactory/server/ResolverServiceLayer.java
 /trunk/user/src/com/google/gwt/requestfactory/server/ServiceLayer.java
/trunk/user/src/com/google/gwt/requestfactory/server/ServiceLayerDecorator.java
 /trunk/user/test/com/google/gwt/requestfactory/RequestFactoryJreSuite.java
 /trunk/user/test/com/google/gwt/requestfactory/RequestFactorySuite.java

=======================================
--- /dev/null
+++ /trunk/user/test/com/google/gwt/requestfactory/server/ServiceInheritanceJreTest.java Wed Mar 23 09:23:21 2011
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2011 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.server;
+
+import com.google.gwt.requestfactory.shared.ServiceInheritanceTest;
+
+/**
+ * A JRE version of {@link ServiceInheritanceTest}.
+ */
+public class ServiceInheritanceJreTest extends ServiceInheritanceTest {
+  @Override
+  public String getModuleName() {
+    return null;
+  }
+
+  @Override
+  protected Factory createFactory() {
+    return RequestFactoryJreTest.createInProcess(Factory.class);
+  }
+}
=======================================
--- /dev/null
+++ /trunk/user/test/com/google/gwt/requestfactory/shared/ServiceInheritanceTest.java Wed Mar 23 09:23:21 2011
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2011 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;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.event.shared.SimpleEventBus;
+import com.google.gwt.junit.client.GWTTestCase;
+
+/**
+ * Tests the ability of instance services to inherit methods
+ * from a base class.
+ */
+public class ServiceInheritanceTest extends GWTTestCase {
+
+  /**
+   * ServiceLocator that returns the base class or subclass implementation
+   * specified in the @{@link Service} annotation.
+   */
+  public static class SumServiceLocator implements ServiceLocator {
+    @Override
+    public Object getInstance(Class<?> clazz) {
+      if (BaseImpl.class.equals(clazz)) {
+        return new BaseImpl();
+      } else if (SubclassImpl.class.equals(clazz)) {
+        return new SubclassImpl();
+      }
+      return null;
+    }
+  }
+
+  /**
+   * The factory under test.
+   */
+  protected interface Factory extends RequestFactory {
+    SumServiceBase baseContext();
+    SumServiceSub subContext();
+  }
+
+  /**
+   * Specifies the base class implementation
+   */
+  @Service(value = BaseImpl.class, locator = SumServiceLocator.class)
+  interface SumServiceBase extends RequestContext {
+    Request<Integer> add(int n);
+    Request<Integer> subtract(int n);
+  }
+
+  /**
+   * Specifies the subclass implementation
+   */
+  @Service(value = SubclassImpl.class, locator = SumServiceLocator.class)
+  interface SumServiceSub extends RequestContext {
+    Request<Integer> add(int n);
+    Request<Integer> subtract(int n);
+  }
+
+  /**
+   * Base implementation of {@link SumService}
+   */
+  static class BaseImpl {
+    protected int initialValue;
+
+    public BaseImpl() {
+      initialValue = 5;
+    }
+
+    public Integer add(int n) {
+      return initialValue + n;
+    }
+
+    public Integer subtract(int n) {
+      return initialValue - n;
+    }
+  }
+
+  /**
+   * Subclass implementation of {@link SumService}
+   * inherits the add() method
+   */
+  static class SubclassImpl extends BaseImpl {
+    public SubclassImpl() {
+      /*
+       * Init with a different value to distinguish between base & subclass
+       * implementations in the tests
+       */
+      initialValue = 8;
+    }
+
+    @Override
+    public Integer subtract(int n) {
+      return 0;
+    }
+  }
+
+  private static final int TEST_DELAY = 5000;
+
+  private Factory factory;
+
+  @Override
+  public String getModuleName() {
+    return "com.google.gwt.requestfactory.RequestFactorySuite";
+  }
+
+  /**
+   * Call a method inherited from a base class
+   */
+  public void testInvokeInheritedMethod() {
+    delayTestFinish(TEST_DELAY);
+    factory.subContext().add(13).fire(new Receiver<Integer>() {
+      @Override
+      public void onSuccess(Integer response) {
+        assertEquals((Integer) 21, response);
+        finishTest();
+      }
+    });
+  }
+
+  /**
+   * Call a method implemented in a base class
+   */
+  public void testInvokeMethodOnBaseClass() {
+    delayTestFinish(TEST_DELAY);
+    factory.baseContext().add(13).fire(new Receiver<Integer>() {
+      @Override
+      public void onSuccess(Integer response) {
+        assertEquals((Integer) 18, response);
+        finishTest();
+      }
+    });
+  }
+
+  /**
+   * Call a method overridden in a subclass
+   */
+  public void testInvokeOverriddenMethod() {
+    delayTestFinish(TEST_DELAY);
+    factory.subContext().subtract(3).fire(new Receiver<Integer>() {
+      @Override
+      public void onSuccess(Integer response) {
+        assertEquals((Integer) 0, response);
+        finishTest();
+      }
+    });
+  }
+
+  protected Factory createFactory() {
+    Factory toReturn = GWT.create(Factory.class);
+    toReturn.initialize(new SimpleEventBus());
+    return toReturn;
+  }
+
+  @Override
+  protected void gwtSetUp() throws Exception {
+    factory = createFactory();
+  }
+
+}
=======================================
--- /trunk/user/src/com/google/gwt/requestfactory/server/LocatorServiceLayer.java Wed Mar 16 12:12:36 2011 +++ /trunk/user/src/com/google/gwt/requestfactory/server/LocatorServiceLayer.java Wed Mar 23 09:23:21 2011
@@ -20,6 +20,7 @@
 import com.google.gwt.requestfactory.shared.ProxyFor;
 import com.google.gwt.requestfactory.shared.ProxyForName;
 import com.google.gwt.requestfactory.shared.Request;
+import com.google.gwt.requestfactory.shared.RequestContext;
 import com.google.gwt.requestfactory.shared.Service;
 import com.google.gwt.requestfactory.shared.ServiceLocator;
 import com.google.gwt.requestfactory.shared.ServiceName;
@@ -52,7 +53,11 @@
     Class<? extends ServiceLocator> locatorType =
         getTop().resolveServiceLocator(contextMethod, domainMethod);
ServiceLocator locator = newInstance(locatorType, ServiceLocator.class);
-    return locator.getInstance(domainMethod.getDeclaringClass());
+    // Enclosing class may be a parent class, so invoke on service class
+    Class<?> declaringClass = contextMethod.getDeclaringClass();
+    Class<?> serviceClass =
+ getTop().resolveServiceClass(declaringClass.asSubclass(RequestContext.class));
+    return locator.getInstance(serviceClass);
   }

   @Override
=======================================
--- /trunk/user/src/com/google/gwt/requestfactory/server/ResolverServiceLayer.java Wed Mar 16 12:12:36 2011 +++ /trunk/user/src/com/google/gwt/requestfactory/server/ResolverServiceLayer.java Wed Mar 23 09:23:21 2011
@@ -117,22 +117,9 @@

   @Override
   public Method resolveDomainMethod(Method requestContextMethod) {
-    Class<?> enclosing = requestContextMethod.getDeclaringClass();
-
-    Class<?> searchIn = null;
-    Service s = enclosing.getAnnotation(Service.class);
-    if (s != null) {
-      searchIn = s.value();
-    }
-    ServiceName sn = enclosing.getAnnotation(ServiceName.class);
-    if (sn != null) {
-      searchIn = forName(sn.value());
-    }
-    if (searchIn == null) {
- die(null, "The %s type %s did not specify a service type", RequestContext.class
-          .getSimpleName(), enclosing.getCanonicalName());
-    }
-
+    Class<?> declaringClass = requestContextMethod.getDeclaringClass();
+    Class<?> searchIn =
+ getTop().resolveServiceClass(declaringClass.asSubclass(RequestContext.class));
     Class<?>[] parameterTypes = requestContextMethod.getParameterTypes();
     Class<?>[] domainArgs = new Class<?>[parameterTypes.length];
     for (int i = 0, j = domainArgs.length; i < j; i++) {
@@ -177,6 +164,25 @@
return report("Could not locate %s method %s::%s", RequestContext.class.getSimpleName(),
         requestContextClass, methodName);
   }
+
+  @Override
+ public Class<?> resolveServiceClass(Class<? extends RequestContext> requestContextClass) {
+    Class<?> searchIn = null;
+    Service s = requestContextClass.getAnnotation(Service.class);
+    // TODO Handle case when both annotations are present
+    if (s != null) {
+      searchIn = s.value();
+    }
+    ServiceName sn = requestContextClass.getAnnotation(ServiceName.class);
+    if (sn != null) {
+      searchIn = forName(sn.value());
+    }
+    if (searchIn == null) {
+ die(null, "The %s type %s did not specify a service type", RequestContext.class
+          .getSimpleName(), requestContextClass.getCanonicalName());
+    }
+    return searchIn;
+  }

   @Override
   public String resolveTypeToken(Class<? extends BaseProxy> clazz) {
=======================================
--- /trunk/user/src/com/google/gwt/requestfactory/server/ServiceLayer.java Mon Mar 21 12:22:19 2011 +++ /trunk/user/src/com/google/gwt/requestfactory/server/ServiceLayer.java Wed Mar 23 09:23:21 2011
@@ -17,6 +17,7 @@

 import com.google.gwt.requestfactory.shared.BaseProxy;
 import com.google.gwt.requestfactory.shared.Locator;
+import com.google.gwt.requestfactory.shared.RequestContext;
 import com.google.gwt.requestfactory.shared.ServiceLocator;

 import java.lang.reflect.Method;
@@ -331,6 +332,15 @@
    */
public abstract Method resolveRequestContextMethod(String requestContextClass, String methodName);

+  /**
+ * Given a {@link RequestContext} method, find the service class referenced in
+   * the {@link Service} or {@link ServiceName} annotation.
+   *
+   * @param requestContextClass a RequestContext interface
+   * @return the type of service to use
+   */
+ public abstract Class<?> resolveServiceClass(Class<? extends RequestContext> requestContextClass);
+
   /**
    * Given a RequestContext method declaration, resolve the
* {@link ServiceLocator} that should be used when invoking the domain method.
=======================================
--- /trunk/user/src/com/google/gwt/requestfactory/server/ServiceLayerDecorator.java Mon Mar 21 12:22:19 2011 +++ /trunk/user/src/com/google/gwt/requestfactory/server/ServiceLayerDecorator.java Wed Mar 23 09:23:21 2011
@@ -17,6 +17,7 @@

 import com.google.gwt.requestfactory.shared.BaseProxy;
 import com.google.gwt.requestfactory.shared.Locator;
+import com.google.gwt.requestfactory.shared.RequestContext;
 import com.google.gwt.requestfactory.shared.ServiceLocator;

 import java.lang.reflect.InvocationTargetException;
@@ -154,6 +155,11 @@
public Method resolveRequestContextMethod(String requestContextClass, String methodName) { return getNext().resolveRequestContextMethod(requestContextClass, methodName);
   }
+
+  @Override
+ public Class<?> resolveServiceClass(Class<? extends RequestContext> requestContextClass) {
+    return getNext().resolveServiceClass(requestContextClass);
+  }

   @Override
public Class<? extends ServiceLocator> resolveServiceLocator(Method contextMethod,
=======================================
--- /trunk/user/test/com/google/gwt/requestfactory/RequestFactoryJreSuite.java Wed Mar 16 12:12:36 2011 +++ /trunk/user/test/com/google/gwt/requestfactory/RequestFactoryJreSuite.java Wed Mar 23 09:23:21 2011
@@ -24,6 +24,7 @@
import com.google.gwt.requestfactory.server.RequestFactoryInterfaceValidatorTest;
 import com.google.gwt.requestfactory.server.RequestFactoryJreTest;
import com.google.gwt.requestfactory.server.RequestFactoryUnicodeEscapingJreTest;
+import com.google.gwt.requestfactory.server.ServiceInheritanceJreTest;
 import com.google.gwt.requestfactory.shared.impl.SimpleEntityProxyIdTest;

 import junit.framework.Test;
@@ -50,6 +51,7 @@
     suite.addTestSuite(RequestFactoryJreTest.class);
     suite.addTestSuite(RequestFactoryModelTest.class);
     suite.addTestSuite(RequestFactoryUnicodeEscapingJreTest.class);
+    suite.addTestSuite(ServiceInheritanceJreTest.class);
     suite.addTestSuite(SimpleEntityProxyIdTest.class);
     return suite;
   }
=======================================
--- /trunk/user/test/com/google/gwt/requestfactory/RequestFactorySuite.java Fri Jan 14 04:27:42 2011 +++ /trunk/user/test/com/google/gwt/requestfactory/RequestFactorySuite.java Wed Mar 23 09:23:21 2011
@@ -26,6 +26,7 @@
 import com.google.gwt.requestfactory.shared.BoxesAndPrimitivesTest;
 import com.google.gwt.requestfactory.shared.ComplexKeysTest;
 import com.google.gwt.requestfactory.shared.LocatorTest;
+import com.google.gwt.requestfactory.shared.ServiceInheritanceTest;

 import junit.framework.Test;

@@ -46,6 +47,7 @@
     suite.addTestSuite(RequestFactoryExceptionPropagationTest.class);
     suite.addTestSuite(RequestFactoryPolymorphicTest.class);
     suite.addTestSuite(RequestFactoryUnicodeEscapingTest.class);
+    suite.addTestSuite(ServiceInheritanceTest.class);
     return suite;
   }
 }

--
http://groups.google.com/group/Google-Web-Toolkit-Contributors

Reply via email to