Added a warning for each use of the gwt.defaultEntryPoint javadoc annotation on RemoteService interfaces.  (This annotation causes the client side proxy to automatically call the ServiceDefTarget.setServiceEntryPoint(String) method.)  Introduced a Java 1.5 style annotation, RemoteServiceRelativePath, which has the same effect.

Review by: Bobv

git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@2048 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/client/rpc/RemoteServiceRelativePath.java b/user/src/com/google/gwt/user/client/rpc/RemoteServiceRelativePath.java
new file mode 100644
index 0000000..65bc9fe
--- /dev/null
+++ b/user/src/com/google/gwt/user/client/rpc/RemoteServiceRelativePath.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2008 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.client.rpc;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+ * Associates a {@link RemoteService} with a relative path. This annotation will
+ * cause the client-side proxy to automatically invoke the
+ * {@link ServiceDefTarget#setServiceEntryPoint(String)} method with
+ * <code>{@link com.google.gwt.core.client.GWT#getModuleBaseURL() GWT.getModuleBaseURL()} + {@link RemoteServiceRelativePath#value()}</code>
+ * as its argument. Subsequent calls to
+ * {@link ServiceDefTarget#setServiceEntryPoint(String)} will override this
+ * default path.
+ */
+@Documented
+@Target(ElementType.TYPE)
+public @interface RemoteServiceRelativePath {
+  /**
+   * The relative path for the {@link RemoteService} implementation.
+   * 
+   * @return relative path for the {@link RemoteService} implementation
+   */
+  String value();
+}
diff --git a/user/src/com/google/gwt/user/client/rpc/impl/RemoteServiceProxy.java b/user/src/com/google/gwt/user/client/rpc/impl/RemoteServiceProxy.java
index 83e9c8c..9a3a555 100644
--- a/user/src/com/google/gwt/user/client/rpc/impl/RemoteServiceProxy.java
+++ b/user/src/com/google/gwt/user/client/rpc/impl/RemoteServiceProxy.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2007 Google Inc.
+ * Copyright 2008 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
@@ -94,10 +94,19 @@
    */
   private final Serializer serializer;
 
-  protected RemoteServiceProxy(String moduleBaseURL, String remoteServiceURL,
-      String serializationPolicyName, Serializer serializer) {
+  protected RemoteServiceProxy(String moduleBaseURL,
+      String remoteServiceRelativePath, String serializationPolicyName,
+      Serializer serializer) {
     this.moduleBaseURL = moduleBaseURL;
-    this.remoteServiceURL = remoteServiceURL;
+    if (remoteServiceRelativePath != null) {
+      /*
+       * If the module relative URL is not null we set the remote service URL to
+       * be the module base URL plus the module relative remote service URL.
+       * Otherwise an explicit call to
+       * ServiceDefTarget.setServiceEntryPoint(String) is required.
+       */
+      this.remoteServiceURL = moduleBaseURL + remoteServiceRelativePath;
+    }
     this.serializer = serializer;
     this.serializationPolicyName = serializationPolicyName;
   }
diff --git a/user/src/com/google/gwt/user/rebind/rpc/ProxyCreator.java b/user/src/com/google/gwt/user/rebind/rpc/ProxyCreator.java
index 415775f..c7e10be 100644
--- a/user/src/com/google/gwt/user/rebind/rpc/ProxyCreator.java
+++ b/user/src/com/google/gwt/user/rebind/rpc/ProxyCreator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2007 Google Inc.
+ * Copyright 2008 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
@@ -28,10 +28,11 @@
 import com.google.gwt.core.ext.typeinfo.TypeOracle;
 import com.google.gwt.dev.generator.NameFactory;
 import com.google.gwt.dev.util.Util;
+import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
 import com.google.gwt.user.client.rpc.SerializationException;
-import com.google.gwt.user.client.rpc.impl.RemoteServiceProxy;
 import com.google.gwt.user.client.rpc.impl.ClientSerializationStreamReader;
 import com.google.gwt.user.client.rpc.impl.ClientSerializationStreamWriter;
+import com.google.gwt.user.client.rpc.impl.RemoteServiceProxy;
 import com.google.gwt.user.client.rpc.impl.RequestCallbackAdapter.ResponseReader;
 import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
 import com.google.gwt.user.rebind.SourceWriter;
@@ -96,6 +97,12 @@
       throws UnableToCompleteException {
     TypeOracle typeOracle = context.getTypeOracle();
 
+    TreeLogger javadocAnnotationDeprecationBranch = logger.branch(
+        TreeLogger.TRACE,
+        "Scanning this RemoteService for deprecated annotations; "
+            + "Please see " + RemoteServiceRelativePath.class.getName()
+            + " for more information.", null);
+
     JClassType serviceAsync = typeOracle.findType(serviceIntf.getQualifiedSourceName()
         + "Async");
     if (serviceAsync == null) {
@@ -138,7 +145,7 @@
 
     generateProxyFields(srcWriter, sto, serializationPolicyStrongName);
 
-    generateProxyContructor(srcWriter);
+    generateProxyContructor(javadocAnnotationDeprecationBranch, srcWriter);
 
     generateProxyMethods(srcWriter, sto, syncMethToAsyncMethMap);
 
@@ -152,12 +159,14 @@
    * using the default address for the
    * {@link com.google.gwt.user.client.rpc.RemoteService RemoteService}.
    */
-  private void generateProxyContructor(SourceWriter srcWriter) {
+  private void generateProxyContructor(
+      TreeLogger javadocAnnotationDeprecationBranch, SourceWriter srcWriter) {
     srcWriter.println("public " + getProxySimpleName() + "() {");
     srcWriter.indent();
     srcWriter.println("super(GWT.getModuleBaseURL(),");
     srcWriter.indent();
-    srcWriter.println(getDefaultServiceDefName() + ",");
+    srcWriter.println(getRemoteServiceRelativePath(javadocAnnotationDeprecationBranch)
+        + ", ");
     srcWriter.println("SERIALIZATION_POLICY, ");
     srcWriter.println("SERIALIZER);");
     srcWriter.outdent();
@@ -265,7 +274,7 @@
           + "\");");
     }
 
-    // Encode all of the arguments to the asynchronous method, but exclude the 
+    // Encode all of the arguments to the asynchronous method, but exclude the
     // last argument which is the callback instance.
     //
     for (int i = 0; i < asyncParams.length - 1; ++i) {
@@ -315,15 +324,6 @@
     }
   }
 
-  private String getDefaultServiceDefName() {
-    String[][] metaData = serviceIntf.getMetaData(ENTRY_POINT_TAG);
-    if (metaData.length == 0) {
-      return null;
-    }
-
-    return serviceIntf.getMetaData(ENTRY_POINT_TAG)[0][0];
-  }
-
   private String getProxyQualifiedName() {
     String[] name = Shared.synthesizeTopLevelClassName(serviceIntf,
         PROXY_SUFFIX);
@@ -336,6 +336,24 @@
     return name[1];
   }
 
+  private String getRemoteServiceRelativePath(
+      TreeLogger javadocAnnotationDeprecationBranch) {
+    String[][] metaData = serviceIntf.getMetaData(ENTRY_POINT_TAG);
+    if (metaData.length != 0) {
+      javadocAnnotationDeprecationBranch.log(TreeLogger.WARN,
+          "Deprecated use of " + ENTRY_POINT_TAG + "; Please use "
+              + RemoteServiceRelativePath.class.getName() + " instead", null);
+      return metaData[0][0];
+    } else {
+      RemoteServiceRelativePath moduleRelativeURL = serviceIntf.getAnnotation(RemoteServiceRelativePath.class);
+      if (moduleRelativeURL != null) {
+        return "\"" + moduleRelativeURL.value() + "\"";
+      }
+    }
+    
+    return null;
+  }
+
   private ResponseReader getResponseReaderFor(JType returnType) {
     if (returnType.isPrimitive() != null) {
       return JPRIMITIVETYPE_TO_RESPONSEREADER.get(returnType.isPrimitive());