You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shindig.apache.org by lr...@apache.org on 2008/04/02 00:00:34 UTC

svn commit: r643608 - in /incubator/shindig/trunk: features/core.io/ java/gadgets/src/main/java/org/apache/shindig/gadgets/ java/gadgets/src/main/java/org/apache/shindig/gadgets/http/ java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/ java/gad...

Author: lryan
Date: Tue Apr  1 15:00:32 2008
New Revision: 643608

URL: http://svn.apache.org/viewvc?rev=643608&view=rev
Log:
Support for Preload

Added:
    incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/Preload.java
Modified:
    incubator/shindig/trunk/features/core.io/io.js
    incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Gadget.java
    incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServer.java
    incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/GadgetRenderer.java
    incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/ModulePrefs.java
    incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/spec/ModulePrefsTest.java

Modified: incubator/shindig/trunk/features/core.io/io.js
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/features/core.io/io.js?rev=643608&r1=643607&r2=643608&view=diff
==============================================================================
--- incubator/shindig/trunk/features/core.io/io.js (original)
+++ incubator/shindig/trunk/features/core.io/io.js Tue Apr  1 15:00:32 2008
@@ -182,6 +182,33 @@
   }
 
   /**
+   * Satisfy a request with data that is prefetched as per the gadget Preload
+   * directive. The preloader will only satisfy a request for a specific piece
+   * of content once.
+   *
+   * @param postData The definition of the request to be executed by the proxy
+   * @param params The params to use when processing the response
+   * @param callback The function to call once the data is fetched
+   * @return true if the request can be satisfied by the preloaded content
+   *         false otherwise
+   */
+  function respondWithPreload(postData, params, callback) {
+    if (gadgets.io.preloaded && gadgets.io.preloaded[postData.url]) {
+      var preload = gadgets.io.preloaded[postData.url];
+      if (postData.httpMethod == "GET" && postData.authz == "none") {
+        delete gadgets.io.preloaded[postData.url];
+        if (preload.rc !== 200) {
+          callback({errors : ["Error " + preload.rc]});
+        } else {
+          callback(transformResponseData(params, preload.body));
+        }
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
    * @param {Object} configuration Configuration settings
    * @private
    */
@@ -239,12 +266,14 @@
         httpMethod : params.METHOD || "GET",
         headers: gadgets.io.encodeValues(headers, false),
         postData : params.POST_DATA || "",
-        authz : auth || "",
+        authz : auth || "none",
         st : st || ""
       };
 
-      makePostRequest(url, config.jsonProxyUrl, callback,
-          gadgets.io.encodeValues(postData), params, processResponse);
+      if (!respondWithPreload(postData, params, callback, processResponse)) {
+        makePostRequest(url, config.jsonProxyUrl, callback,
+            gadgets.io.encodeValues(postData), params, processResponse);
+      }
     },
 
     /**

Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Gadget.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Gadget.java?rev=643608&r1=643607&r2=643608&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Gadget.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Gadget.java Tue Apr  1 15:00:32 2008
@@ -19,8 +19,12 @@
 
 import org.apache.shindig.gadgets.spec.GadgetSpec;
 import org.apache.shindig.gadgets.spec.MessageBundle;
+import org.apache.shindig.gadgets.spec.Preload;
 
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Future;
 
 /**
  * Intermediary representation of all state associated with processing
@@ -58,6 +62,12 @@
   private final List<JsLibrary> jsLibraries;
   public List<JsLibrary> getJsLibraries() {
     return jsLibraries;
+  }
+
+  private final Map<Preload, Future<RemoteContent>> preloads
+      = new HashMap<Preload, Future<RemoteContent>>();
+  public Map<Preload, Future<RemoteContent>> getPreloadMap() {
+    return preloads;
   }
 
   /**

Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServer.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServer.java?rev=643608&r1=643607&r2=643608&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServer.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServer.java Tue Apr  1 15:00:32 2008
@@ -21,6 +21,7 @@
 import org.apache.shindig.gadgets.spec.GadgetSpec;
 import org.apache.shindig.gadgets.spec.LocaleSpec;
 import org.apache.shindig.gadgets.spec.MessageBundle;
+import org.apache.shindig.gadgets.spec.Preload;
 import org.apache.shindig.util.Check;
 
 import java.util.HashMap;
@@ -176,7 +177,17 @@
   private void runTasks(Gadget gadget,
       Map<GadgetFeatureRegistry.Entry, GadgetFeature> tasks)
       throws GadgetException {
-    CompletionService<GadgetException> processor
+
+    // Immediately enqueue all the preloads
+    CompletionService<RemoteContent> preloadProcessor
+        = new ExecutorCompletionService<RemoteContent>(config.getExecutor());
+    for (Preload preload : gadget.getSpec().getModulePrefs().getPreloads()) {
+      gadget.getPreloadMap().put(preload,
+          preloadProcessor.submit(
+              new PreloadTask(preload, getConfig().getContentFetcher())));
+    }
+
+    CompletionService<GadgetException> featureProcessor
         = new ExecutorCompletionService<GadgetException>(config.getExecutor());
     // FeatureTask is OK has a hash key because we want actual instances, not
     // names.
@@ -196,14 +207,14 @@
         if (task.depsDone(done)) {
           pending.remove(task);
           running.add(task);
-          processor.submit(task);
+          featureProcessor.submit(task);
         }
       }
 
       if (running.size() > 0) {
         try {
           Future<GadgetException> future;
-          while ((future = processor.take()) != null) {
+          while ((future = featureProcessor.take()) != null) {
             GadgetException e = future.get();
             if (future.get() != null) {
               throw future.get();
@@ -296,5 +307,23 @@
     this.gadget = gadget;
     this.context = context;
     this.dependencies = dependencies;
+  }
+}
+
+/**
+ * Provides a task for preloading data into the gadget content
+ */
+class PreloadTask implements Callable<RemoteContent> {
+  private final Preload preload;
+  private final RemoteContentFetcher fetcher;
+
+  public RemoteContent call() {
+    RemoteContentRequest request = new RemoteContentRequest(preload.getHref());
+    return fetcher.fetch(request);
+  }
+
+  public PreloadTask(Preload preload, RemoteContentFetcher fetcher) {
+    this.preload = preload;
+    this.fetcher = fetcher;
   }
 }

Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/GadgetRenderer.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/GadgetRenderer.java?rev=643608&r1=643607&r2=643608&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/GadgetRenderer.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/GadgetRenderer.java Tue Apr  1 15:00:32 2008
@@ -26,13 +26,14 @@
 import org.apache.shindig.gadgets.GadgetFeatureRegistry;
 import org.apache.shindig.gadgets.GadgetServerConfigReader;
 import org.apache.shindig.gadgets.JsLibrary;
+import org.apache.shindig.gadgets.RemoteContent;
 import org.apache.shindig.gadgets.SyndicatorConfig;
 import org.apache.shindig.gadgets.spec.Feature;
 import org.apache.shindig.gadgets.spec.LocaleSpec;
 import org.apache.shindig.gadgets.spec.MessageBundle;
 import org.apache.shindig.gadgets.spec.ModulePrefs;
+import org.apache.shindig.gadgets.spec.Preload;
 import org.apache.shindig.gadgets.spec.View;
-
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
@@ -44,7 +45,10 @@
 import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import java.util.regex.Pattern;
@@ -232,6 +236,32 @@
 
     String msgs = new JSONObject(bundle.getMessages()).toString();
     inlineJs.append("gadgets.Prefs.setMessages_(").append(msgs).append(");");
+
+    // Output preloads. We will allow the gadget render to continue
+    // even if a preload fails
+    JSONObject resp = new JSONObject();
+    for (Map.Entry<Preload, Future<RemoteContent>> entry : gadget
+        .getPreloadMap().entrySet()) {
+      try {
+        // Use raw param as key as URL may have to be decoded
+        JSONObject jsonEntry = new JSONObject();
+        jsonEntry.put("body", entry.getValue().get().getResponseAsString()).
+            put("rc", entry.getValue().get().getHttpStatusCode());
+        resp.put(entry.getKey().getHref().toString(), jsonEntry);
+      } catch (JSONException je) {
+        logger.log(Level.INFO,
+            "Error outputting preload for " + entry.getKey().getHref(), je);
+      } catch (InterruptedException ie) {
+        logger.log(Level.INFO,
+            "Error scheduling preload for " + entry.getKey().getHref(), ie);
+      } catch (ExecutionException ee) {
+        logger.log(Level.INFO,
+            "Error executing preload for " + entry.getKey().getHref(),
+            ee.getCause());
+      }
+    }
+    inlineJs.append("\ngadgets.io.preloaded = ").append(resp.toString())
+        .append(";\n");
 
     if (inlineJs.length() > 0) {
       markup.append("<script><!--\n").append(inlineJs)

Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/ModulePrefs.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/ModulePrefs.java?rev=643608&r1=643607&r2=643608&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/ModulePrefs.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/ModulePrefs.java Tue Apr  1 15:00:32 2008
@@ -262,8 +262,8 @@
   /**
    * ModuleSpec.Preload
    */
-  private final List<URI> preloads;
-  public List<URI> getPreloads() {
+  private final List<Preload> preloads;
+  public List<Preload> getPreloads() {
     return preloads;
   }
 
@@ -389,8 +389,8 @@
        .append(" scaling=\"").append(scaling).append('\"')
        .append(" scrolling=\"").append(scrolling).append('\"')
        .append(">\n");
-    for (URI preload : preloads) {
-      buf.append("<Preload href=\"").append(preload).append("\"/>\n");
+    for (Preload preload : preloads) {
+      buf.append(preload).append("\n");
     }
     for (Feature feature : features.values()) {
       buf.append(feature).append('\n');
@@ -489,13 +489,10 @@
  * Processes ModulePrefs.Preload into a list.
  */
 class PreloadVisitor implements ElementVisitor {
-  final List<URI> preloads = new LinkedList<URI>();
+  final List<Preload> preloads = new LinkedList<Preload>();
   public void visit(Element element) throws SpecParserException {
-    URI href = XmlUtil.getUriAttribute(element, "href");
-    if (href == null) {
-      throw new SpecParserException("Preload@href is required.");
-    }
-    preloads.add(href);
+    Preload preload = new Preload(element);
+    preloads.add(preload);
   }
 }
 

Added: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/Preload.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/Preload.java?rev=643608&view=auto
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/Preload.java (added)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/Preload.java Tue Apr  1 15:00:32 2008
@@ -0,0 +1,47 @@
+package org.apache.shindig.gadgets.spec;
+
+import org.apache.shindig.util.XmlUtil;
+import org.w3c.dom.Element;
+
+import java.net.URI;
+import java.util.Map;
+
+/**
+ * Represents an addressable piece of content that can be preloaded by the server
+ * to satisfy makeRequest calls
+ */
+public class Preload {
+
+  /**
+   * Preload@href
+   */
+  private final URI href;
+  public URI getHref() {
+    return href;
+  }
+
+  /**
+   * Produces an xml representation of the Preload.
+   */
+  @Override
+  public String toString() {
+    StringBuilder buf = new StringBuilder();
+    buf.append("<Preload href=\"").append(href).append("\"/>");
+    return buf.toString();
+  }
+  /**
+   * Creates a new Preload from an xml node.
+   *
+   * @param preload The Preload to create
+   * @throws SpecParserException When the href is not specified
+   */
+  public Preload(Element preload) throws SpecParserException {
+    href = XmlUtil.getUriAttribute(preload, "href");
+    if (href == null) {
+      throw new SpecParserException("Preload@href is required.");
+    }
+  }
+
+
+
+}
\ No newline at end of file

Modified: incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/spec/ModulePrefsTest.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/spec/ModulePrefsTest.java?rev=643608&r1=643607&r2=643608&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/spec/ModulePrefsTest.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/spec/ModulePrefsTest.java Tue Apr  1 15:00:32 2008
@@ -45,7 +45,7 @@
                  " category2=\"category2\">" +
                  "  <Require feature=\"require\"/>" +
                  "  <Optional feature=\"optional\"/>" +
-                 "  <Preload href=\"preload\"/>" +
+                 "  <Preload href=\"http://www.google.com\"/>" +
                  "  <Icon/>" +
                  "  <Locale/>" +
                  "</ModulePrefs>";
@@ -64,7 +64,8 @@
     assertEquals("category2", prefs.getCategories().get(1));
     assertEquals(true, prefs.getFeatures().get("require").getRequired());
     assertEquals(false, prefs.getFeatures().get("optional").getRequired());
-    assertEquals("preload", prefs.getPreloads().get(0).toString());
+    assertEquals("http://www.google.com",
+        prefs.getPreloads().get(0).getHref().toString());
     assertEquals(1, prefs.getIcons().size());
     assertEquals(1, prefs.getLocales().size());
   }