Brian Slesinsky has uploaded a new change for review.

  https://gwt-review.googlesource.com/2341


Change subject: Added gwt.codeserver.port parameter to RemoteServiceServlet
......................................................................

Added gwt.codeserver.port parameter to RemoteServiceServlet

This parameter is the port of a Super Dev Mode code server running
on localhost. When a serialization policy isn't found locally, the
servlet attempts to download it from the code server.

API change: added two protected methods that can be used to customize
the behavior of this feature:

  getCodeServerPolicyUrl() controls whether it's enabled and the URL
  getCodeServerClient() can be overridden to change the implementation

Change-Id: Iaf2366cb94297e738cf50bb9d8038fef66b89722
---
M user/src/com/google/gwt/user/server/rpc/RemoteServiceServlet.java
A user/src/com/google/gwt/user/server/rpc/SerializationPolicyClient.java
A user/src/com/google/gwt/user/server/rpc/SimpleSerializationPolicyClient.java
3 files changed, 222 insertions(+), 9 deletions(-)



diff --git a/user/src/com/google/gwt/user/server/rpc/RemoteServiceServlet.java b/user/src/com/google/gwt/user/server/rpc/RemoteServiceServlet.java
index 9bddd66..d73bb85 100644
--- a/user/src/com/google/gwt/user/server/rpc/RemoteServiceServlet.java
+++ b/user/src/com/google/gwt/user/server/rpc/RemoteServiceServlet.java
@@ -27,6 +27,7 @@
 import java.util.HashMap;
 import java.util.Map;

+import javax.servlet.ServletConfig;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
@@ -38,10 +39,12 @@
  * outgoing responses for client/server RPCs.
  */
 public class RemoteServiceServlet extends AbstractRemoteServiceServlet
-    implements SerializationPolicyProvider {
+ implements SerializationPolicyProvider, SimpleSerializationPolicyClient.Logger {

   /**
-   * Used by HybridServiceServlet.
+   * Loads a serialization policy stored as a servlet resource in the same
+   * ServletContext as this servlet. Returns null if not found.
+   * (Used by HybridServiceServlet.)
    */
   static SerializationPolicy loadSerializationPolicy(HttpServlet servlet,
HttpServletRequest request, String moduleBaseURL, String strongName) {
@@ -128,6 +131,13 @@
   private final Object delegate;

   /**
+ * The HTTP port of a Super Dev Mode code server running on localhost where this servlet will + * download serialization policies. (If set to zero, this feature is disabled and no download
+   * will be attempted.)
+   */
+  private int codeServerPort = 0;
+
+  /**
    * The default constructor used by service implementations that
    * extend this class.  The servlet will delegate AJAX requests to
    * the appropriate method in the subclass.
@@ -143,6 +153,35 @@
    */
   public RemoteServiceServlet(Object delegate) {
     this.delegate = delegate;
+  }
+
+  /***
+   * Overridden to load the gwt.codeserver.port parameter.
+   */
+  @Override
+  public void init(ServletConfig config) throws ServletException {
+    super.init(config);
+
+    String value = config.getInitParameter("gwt.codeserver.port");
+    if (value == null) {
+      return;
+    }
+
+    try {
+      int port = Integer.parseInt(value);
+      if (port >= 0) {
+        codeServerPort = port;
+        return;
+      }
+      // invalid because negative; fall through
+
+    } catch (NumberFormatException e) {
+      // fall through
+    }
+
+    // Fail loudly so that that a configuration error will be noticed.
+ throw new ServletException("Invalid value of gwt.codeserver.port servlet parameter;"
+        + " expected integer but got: " + value);
   }

public final SerializationPolicy getSerializationPolicy(String moduleBaseURL,
@@ -275,22 +314,64 @@
   }

   /**
- * Gets the {@link SerializationPolicy} for given module base URL and strong
-   * name if there is one.
+ * Loads the {@link SerializationPolicy} for given module base URL and strong name. + * Returns the policy if successful or null if not found. Due to caching, this method + * will only be called once for each combination of moduleBaseURL and strongName.</p>
+   *
+ * <p>The default implementation loads serialization policies stored as servlet resources + * in the same ServletContext as this servlet. If no policy is found, it then attempts to + * load the policy from the URL returned by {@link #getCodeServerPolicyUrl}.</p>
    *
-   * Override this method to provide a {@link SerializationPolicy} using an
-   * alternative approach.
+ * <p>Override this method to load the {@link SerializationPolicy} using an
+   * alternative approach.</p>
    *
    * @param request the HTTP request being serviced
    * @param moduleBaseURL as specified in the incoming payload
* @param strongName a strong name that uniquely identifies a serialization
    *          policy file
- * @return a {@link SerializationPolicy} for the given module base URL and
-   *         strong name, or <code>null</code> if there is none
    */
   protected SerializationPolicy doGetSerializationPolicy(
HttpServletRequest request, String moduleBaseURL, String strongName) { - return loadSerializationPolicy(this, request, moduleBaseURL, strongName);
+
+    SerializationPolicy policy =
+ RemoteServiceServlet.loadSerializationPolicy(this, request, moduleBaseURL, strongName);
+    if (policy != null) {
+      return policy;
+    }
+
+    String url = getCodeServerPolicyUrl(strongName);
+    if (url != null) {
+      return getCodeServerClient().loadPolicy(url, this);
+    }
+
+    return null;
+  }
+
+  /**
+ * Returns the URL for fetching a serialization policy from a Super Dev Mode server.
+   *
+ * <p>By default, returns null. If the <i>gwt.codeserver.port</i> servlet parameter is set,
+   * returns a URL under <tt>http://localhost:{port}</tt>.</p>
+   *
+ * @param strongName the strong name from the GWT-RPC request (already validated).
+   * @return the policy, or null if not available.
+   */
+  protected String getCodeServerPolicyUrl(String strongName) {
+    if (codeServerPort <= 0) {
+      return null;
+    }
+ return "http://localhost:"; + codeServerPort + "/policies/" + strongName + ".gwt.rpc";
+  }
+
+  /**
+ * Returns a client for downloading a serialization policy from a Super Dev Mode server.
+   * (Not used unless {@link #getCodeServerPolicyUrl} returns a URL.)
+   *
+ * <p>The default version is a naive implementation built on java.net.URL that does
+   * no authentication. It should only be used during development.</p>
+   */
+  protected SerializationPolicyClient getCodeServerClient() {
+    return new SimpleSerializationPolicyClient();
   }

   /**
diff --git a/user/src/com/google/gwt/user/server/rpc/SerializationPolicyClient.java b/user/src/com/google/gwt/user/server/rpc/SerializationPolicyClient.java
new file mode 100644
index 0000000..6db3215
--- /dev/null
+++ b/user/src/com/google/gwt/user/server/rpc/SerializationPolicyClient.java
@@ -0,0 +1,24 @@
+package com.google.gwt.user.server.rpc;
+
+/**
+ * A client that downloads serialization policies from a URL, for use with
+ * Super Dev Mode.
+ * @see RemoteServiceServlet#getCodeServerClient
+ */
+public interface SerializationPolicyClient {
+
+  /**
+   * Attempts to read a policy from a given URL.
+   * Logs any errors to the given interface.
+   * @return the policy or null if unavailable.
+   */
+  SerializationPolicy loadPolicy(String url, Logger logger);
+
+  /**
+   * Destination for the loader's log messages.
+   */
+  interface Logger {
+    void log(String message);
+    void log(String message, Throwable throwable);
+  }
+}
diff --git a/user/src/com/google/gwt/user/server/rpc/SimpleSerializationPolicyClient.java b/user/src/com/google/gwt/user/server/rpc/SimpleSerializationPolicyClient.java
new file mode 100644
index 0000000..fbc8b3a
--- /dev/null
+++ b/user/src/com/google/gwt/user/server/rpc/SimpleSerializationPolicyClient.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2013 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.server.rpc;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A simple and relatively naive client for downloading serialization policies from a URL.
+ * (Intended only for development.)
+ */
+class SimpleSerializationPolicyClient implements SerializationPolicyClient {
+
+  @Override
+  public SerializationPolicy loadPolicy(String url, Logger logger) {
+    URL urlObj;
+    try {
+      urlObj = new URL(url);
+    } catch (MalformedURLException e) {
+      logger.log("can't parse serialization policy URL: " + url, e);
+      return null;
+    }
+
+    URLConnection conn;
+    InputStream in;
+    try {
+      conn = urlObj.openConnection();
+      conn.setConnectTimeout(5000);
+      conn.setReadTimeout(5000);
+      if (conn instanceof HttpURLConnection) {
+        ((HttpURLConnection)conn).setInstanceFollowRedirects(false);
+      }
+      conn.connect();
+      in = conn.getInputStream();
+    } catch (IOException e) {
+      logger.log("can't open serialization policy URL: " + url, e);
+      return null;
+    }
+
+    return readPolicy(in, url, logger);
+  }
+
+  /**
+ * Attempts to read a policy from a given InputStream and logs any errors.
+   *
+ * @param sourceName names the source of the input stream for log messages.
+   * @return the policy or null if unavailable.
+   */
+ private static SerializationPolicy readPolicy(InputStream in, String sourceName,
+      Logger logger) {
+    try {
+ List<ClassNotFoundException> errs = new ArrayList<ClassNotFoundException>(); + SerializationPolicy policy = SerializationPolicyLoader.loadFromStream(in, errs);
+      logger.log("downloaded serialization policy from " + sourceName);
+
+      if (!errs.isEmpty()) {
+        logMissingClasses(logger, errs);
+      }
+      return policy;
+
+    } catch (ParseException e) {
+      logger.log("can't parse serialization policy from " + sourceName, e);
+      return null;
+    } catch (IOException e) {
+      logger.log("can't read serialization policy from " + sourceName, e);
+      return null;
+    } finally {
+      try {
+        in.close();
+      } catch (IOException e) {
+ logger.log("can't close serialization policy url: " + sourceName, e);
+      }
+    }
+  }
+
+ private static void logMissingClasses(Logger logger, List<ClassNotFoundException> errs) {
+    logger.log("unable to load server-side classes used by policy:");
+
+    int limit = Math.min(10, errs.size());
+    for (int i = 0; i < limit; i++) {
+      logger.log(errs.get(i).getMessage());
+    }
+    int omitted = errs.size() - limit;
+    if (omitted > 0) {
+      logger.log("(omitted " + omitted + " more classes)");
+    }
+  }
+}

--
To view, visit https://gwt-review.googlesource.com/2341
To unsubscribe, visit https://gwt-review.googlesource.com/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Iaf2366cb94297e738cf50bb9d8038fef66b89722
Gerrit-PatchSet: 1
Gerrit-Project: gwt
Gerrit-Branch: master
Gerrit-Owner: Brian Slesinsky <[email protected]>

--
--
http://groups.google.com/group/Google-Web-Toolkit-Contributors
--- You received this message because you are subscribed to the Google Groups "Google Web Toolkit Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to