Author: mhermanto
Date: Wed Oct 13 20:40:04 2010
New Revision: 1022286

URL: http://svn.apache.org/viewvc?rev=1022286&view=rev
Log:
Add support for &jsload=1 to JsServlet to load versioned JS
http://codereview.appspot.com/2370041/

Added:
    
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/JsServletTest.java
    
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/uri/JsUriManagerTest.java
Modified:
    
shindig/trunk/java/common/src/test/java/org/apache/shindig/common/servlet/HttpServletResponseRecorder.java
    
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/DefaultGuiceModule.java
    
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriter.java
    
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/JsServlet.java
    
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/DefaultJsUriManager.java
    
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/JsUriManager.java
    
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/ProxyUriBase.java
    
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/UriCommon.java
    
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriterTest.java
    
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/uri/DefaultJsUriManagerTest.java

Modified: 
shindig/trunk/java/common/src/test/java/org/apache/shindig/common/servlet/HttpServletResponseRecorder.java
URL: 
http://svn.apache.org/viewvc/shindig/trunk/java/common/src/test/java/org/apache/shindig/common/servlet/HttpServletResponseRecorder.java?rev=1022286&r1=1022285&r2=1022286&view=diff
==============================================================================
--- 
shindig/trunk/java/common/src/test/java/org/apache/shindig/common/servlet/HttpServletResponseRecorder.java
 (original)
+++ 
shindig/trunk/java/common/src/test/java/org/apache/shindig/common/servlet/HttpServletResponseRecorder.java
 Wed Oct 13 20:40:04 2010
@@ -41,7 +41,7 @@ public class HttpServletResponseRecorder
   protected final ByteArrayOutputStream baos = new ByteArrayOutputStream();
   private PrintWriter writer;
   private final Map<String, String> headers = 
Maps.newTreeMap(String.CASE_INSENSITIVE_ORDER);
-  private int httpStatusCode = 200;
+  private int httpStatusCode = HttpServletResponse.SC_OK;
   private String encoding = Charset.defaultCharset().name();
 
   public HttpServletResponseRecorder(HttpServletResponse response) {
@@ -116,7 +116,7 @@ public class HttpServletResponseRecorder
   public void sendError(int httpStatusCode) {
     this.httpStatusCode = httpStatusCode;
   }
-  
+
   @Override
   public void sendRedirect(String location) {
     setStatus(302);

Modified: 
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/DefaultGuiceModule.java
URL: 
http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/DefaultGuiceModule.java?rev=1022286&r1=1022285&r2=1022286&view=diff
==============================================================================
--- 
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/DefaultGuiceModule.java
 (original)
+++ 
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/DefaultGuiceModule.java
 Wed Oct 13 20:40:04 2010
@@ -70,7 +70,10 @@ public class DefaultGuiceModule extends 
     bind(ExecutorService.class).toInstance(service);
     
bind(ExecutorService.class).annotatedWith(Names.named("shindig.concat.executor")).toInstance(service);
 
+    bindConstant().annotatedWith(Names.named("shindig.jsload.ttl-secs")).to(60 
* 60); // 1 hour
+
     Runtime.getRuntime().addShutdownHook(new Thread() {
+        @Override
         public void run() {
             service.shutdownNow();
         }

Modified: 
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriter.java
URL: 
http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriter.java?rev=1022286&r1=1022285&r2=1022286&view=diff
==============================================================================
--- 
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriter.java
 (original)
+++ 
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriter.java
 Wed Oct 13 20:40:04 2010
@@ -228,7 +228,8 @@ public class RenderingGadgetRewriter imp
     }
 
     if (!externForcedLibs.isEmpty()) {
-      String jsUrl = jsUriManager.makeExternJsUri(gadget, 
externForcedLibs).toString();
+      String jsUrl = jsUriManager.makeExternJsUri(gadget.getContext(), 
externForcedLibs)
+          .toString();
       Element libsTag = headTag.getOwnerDocument().createElement("script");
       libsTag.setAttribute("src", jsUrl);
       headTag.insertBefore(libsTag, firstHeadChild);
@@ -270,7 +271,8 @@ public class RenderingGadgetRewriter imp
       externGadgetLibs.removeAll(externForcedLibs);
 
       if (!externGadgetLibs.isEmpty()) {
-        String jsUrl = jsUriManager.makeExternJsUri(gadget, 
externGadgetLibs).toString();
+        String jsUrl = jsUriManager.makeExternJsUri(gadget.getContext(), 
externGadgetLibs)
+            .toString();
         Element libsTag = headTag.getOwnerDocument().createElement("script");
         libsTag.setAttribute("src", jsUrl);
         headTag.insertBefore(libsTag, firstHeadChild);

Modified: 
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/JsServlet.java
URL: 
http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/JsServlet.java?rev=1022286&r1=1022285&r2=1022286&view=diff
==============================================================================
--- 
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/JsServlet.java
 (original)
+++ 
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/JsServlet.java
 Wed Oct 13 20:40:04 2010
@@ -17,18 +17,25 @@
  */
 package org.apache.shindig.gadgets.servlet;
 
-import org.apache.commons.lang.StringEscapeUtils;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
 
+import org.apache.commons.lang.StringEscapeUtils;
 import org.apache.shindig.common.servlet.HttpUtil;
 import org.apache.shindig.common.servlet.InjectedServlet;
+import org.apache.shindig.common.uri.Uri;
 import org.apache.shindig.common.uri.UriBuilder;
+import org.apache.shindig.gadgets.GadgetContext;
 import org.apache.shindig.gadgets.GadgetException;
+import org.apache.shindig.gadgets.RenderingContext;
 import org.apache.shindig.gadgets.uri.JsUriManager;
 import org.apache.shindig.gadgets.uri.UriStatus;
-
-import com.google.inject.Inject;
+import org.apache.shindig.gadgets.uri.JsUriManager.JsUri;
+import org.apache.shindig.gadgets.uri.UriCommon.Param;
 
 import java.io.IOException;
+import java.io.UnsupportedEncodingException;
 import java.util.regex.Pattern;
 
 import javax.servlet.http.HttpServletRequest;
@@ -39,19 +46,43 @@ import javax.servlet.http.HttpServletRes
  * Used by type=URL gadgets in loading JavaScript resources.
  */
 public class JsServlet extends InjectedServlet {
-  
   private static final long serialVersionUID = 6255917470412008175L;
 
+  @VisibleForTesting
+  static final String JSLOAD_ONLOAD_ERROR = "jsload must require onload";
+
+  @VisibleForTesting
   static final String ONLOAD_JS_TPL = "(function() {" +
       "var nm='%s';" +
       "if (typeof window[nm]==='function') {" +
       "window[nm]();" +
       '}' +
       "})();";
+
+  @VisibleForTesting
+  static final String JSLOAD_JS_TPL = "(function() {" +
+      "document.write('<scr' + 'ipt type=\"text/javascript\" src=\"%s\"></scr' 
+ 'ipt>');" +
+      "})();"; // Concatenated to avoid some browsers do dynamic script 
injection.
+
   private static final Pattern ONLOAD_FN_PATTERN = 
Pattern.compile("[a-zA-Z0-9_]+");
 
   private transient JsHandler jsHandler;
   private transient JsUriManager jsUriManager;
+  private int jsloadTtlSecs;
+  private CachingSetter cachingSetter;
+
+  @VisibleForTesting
+  static class CachingSetter {
+    public void setCachingHeaders(HttpServletResponse resp, int ttl, boolean 
noProxy) {
+      HttpUtil.setCachingHeaders(resp, ttl, false);
+    }
+  }
+
+  @Inject
+  @VisibleForTesting
+  void setCachingSetter(CachingSetter util) {
+    this.cachingSetter = util;
+  }
 
   @Inject
   public void setJsHandler(JsHandler jsHandler) {
@@ -64,22 +95,37 @@ public class JsServlet extends InjectedS
     checkInitialized();
     this.jsUriManager = jsUriManager;
   }
-  
+
+  @Inject
+  public void setJsloadTtlSecs(@Named("shindig.jsload.ttl-secs") int 
jsloadTtlSecs) {
+    this.jsloadTtlSecs = jsloadTtlSecs;
+  }
+
   @Override
   protected void doGet(HttpServletRequest req, HttpServletResponse resp)
       throws IOException {
-    // If an If-Modified-Since header is ever provided, we always say
-    // not modified. This is because when there actually is a change,
-    // cache busting should occur.
-    UriStatus vstatus = null;
+
+    JsUri jsUri = null;
     try {
-      vstatus = jsUriManager.processExternJsUri(new 
UriBuilder(req).toUri()).getStatus();
+      jsUri = jsUriManager.processExternJsUri(new UriBuilder(req).toUri());
     } catch (GadgetException e) {
-      resp.sendError(e.getHttpStatusCode(), e.getMessage());
+      resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
       return;
     }
+
+    // Don't emit the JS itself; instead emit JS loader script that loads
+    // versioned JS. The loader script is much smaller and cacheable for a
+    // configurable amount of time.
+    if (jsUri.isJsload()) {
+      doJsload(jsUri, resp);
+      return;
+    }
+
+    // If an If-Modified-Since header is ever provided, we always say
+    // not modified. This is because when there actually is a change,
+    // cache busting should occur.
     if (req.getHeader("If-Modified-Since") != null &&
-        vstatus == UriStatus.VALID_VERSIONED) {
+        jsUri.getStatus() == UriStatus.VALID_VERSIONED) {
       resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
       return;
     }
@@ -90,13 +136,13 @@ public class JsServlet extends InjectedS
     boolean isProxyCacheable = handlerResponse.isProxyCacheable();
 
     // Add onload handler to add callback function.
-    String onloadStr = req.getParameter("onload");
+    String onloadStr = req.getParameter(Param.ONLOAD.getKey());
     if (onloadStr != null) {
       if (!ONLOAD_FN_PATTERN.matcher(onloadStr).matches()) {
         resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid onload 
callback specified");
         return;
       }
-      jsData.append(String.format(ONLOAD_JS_TPL, 
StringEscapeUtils.escapeJavaScript(onloadStr)));
+      jsData.append(createOnloadScript(onloadStr));
     }
 
     if (jsData.length() == 0) {
@@ -105,7 +151,7 @@ public class JsServlet extends InjectedS
     }
 
     // post JavaScript content fetching
-    postJsContentProcessing(resp, vstatus, isProxyCacheable);
+    postJsContentProcessing(resp, jsUri.getStatus(), isProxyCacheable);
 
     resp.setContentType("text/javascript; charset=utf-8");
     byte[] response = jsData.toString().getBytes("UTF-8");
@@ -113,10 +159,62 @@ public class JsServlet extends InjectedS
     resp.getOutputStream().write(response);
   }
 
+  private void doJsload(JsUri jsUri, HttpServletResponse resp)
+      throws IOException, UnsupportedEncodingException {
+    String onloadStr = jsUri.getOnload();
+
+    // Require users to specify &onload=. This ensures a reliable continuation 
of JS
+    // execution. IE asynchronously loads script, before it loads 
source-scripted and
+    // inlined JS.
+    if (onloadStr == null) {
+      resp.sendError(HttpServletResponse.SC_BAD_REQUEST, JSLOAD_ONLOAD_ERROR);
+      return;
+    }
+
+    GadgetContext ctx = makeContextObject(jsUri);
+
+    Uri incUri = jsUriManager.makeExternJsUri(ctx, jsUri.getLibs());
+    UriBuilder uriBuilder = new UriBuilder(incUri);
+    uriBuilder.putQueryParameter(Param.ONLOAD.getKey(), onloadStr);
+    uriBuilder.putQueryParameter(Param.NO_CACHE.getKey(), jsUri.isNoCache() ? 
"1" : "0");
+    incUri = uriBuilder.toUri();
+
+    int refresh = getCacheTtlSecs(jsUri);
+    cachingSetter.setCachingHeaders(resp, refresh, false);
+
+    resp.setContentType("text/javascript; charset=utf-8");
+    byte[] incBytes = createJsloadScript(incUri).getBytes("UTF-8");
+    resp.setContentLength(incBytes.length);
+    resp.getOutputStream().write(incBytes);
+  }
+
+  private int getCacheTtlSecs(JsUri jsUri) {
+    int refresh;
+    if (jsUri.isNoCache()) {
+      return 0;
+    } else {
+      Integer jsUriRefresh = jsUri.getRefresh();
+      return (jsUriRefresh != null && jsUriRefresh >= 0)
+          ? jsUriRefresh : jsloadTtlSecs;
+    }
+  }
+
+
+  @VisibleForTesting
+  String createOnloadScript(String function) {
+    return String.format(ONLOAD_JS_TPL, 
StringEscapeUtils.escapeJavaScript(function));
+  }
+
+  @VisibleForTesting
+  String createJsloadScript(Uri uri) {
+    String uriString = uri.toString();
+    return String.format(JSLOAD_JS_TPL, uriString, uriString);
+  }
+
   /**
    * Provides post JavaScript content processing. The default behavior will 
check the UriStatus and
    * update the response header with cache option.
-   * 
+   *
    * @param resp The HttpServeltResponse object.
    * @param vstatus The UriStatus object.
    * @param isProxyCacheable boolean true if content is cacheable and false 
otherwise.
@@ -139,4 +237,33 @@ public class JsServlet extends InjectedS
         break;
     }
   }
+
+  private GadgetContext makeContextObject(final JsUri jsUri) {
+    return new GadgetContext() {
+      @Override
+      public RenderingContext getRenderingContext() {
+        return jsUri.getContext();
+      }
+
+      @Override
+      public String getContainer() {
+        return jsUri.getContainer();
+      }
+
+      @Override
+      public Uri getUrl() {
+        return jsUri.getGadget() != null ? Uri.parse(jsUri.getGadget()) : null;
+      }
+
+      @Override
+      public boolean getIgnoreCache() {
+        return jsUri.isNoCache();
+      }
+
+      @Override
+      public boolean getDebug() {
+        return jsUri.isDebug();
+      }
+    };
+  }
 }

Modified: 
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/DefaultJsUriManager.java
URL: 
http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/DefaultJsUriManager.java?rev=1022286&r1=1022285&r2=1022286&view=diff
==============================================================================
--- 
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/DefaultJsUriManager.java
 (original)
+++ 
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/DefaultJsUriManager.java
 Wed Oct 13 20:40:04 2010
@@ -25,7 +25,7 @@ import org.apache.commons.lang.StringUti
 import org.apache.shindig.common.uri.Uri;
 import org.apache.shindig.common.uri.UriBuilder;
 import org.apache.shindig.config.ContainerConfig;
-import org.apache.shindig.gadgets.Gadget;
+import org.apache.shindig.gadgets.GadgetContext;
 import org.apache.shindig.gadgets.GadgetException;
 import org.apache.shindig.gadgets.RenderingContext;
 import org.apache.shindig.gadgets.GadgetException.Code;
@@ -49,14 +49,13 @@ public class DefaultJsUriManager impleme
   private final Versioner versioner;
 
   @Inject
-  public DefaultJsUriManager(ContainerConfig config,
-                             Versioner versioner) {
+  public DefaultJsUriManager(ContainerConfig config, Versioner versioner) {
     this.config = config;
     this.versioner = versioner;
   }
 
-  public Uri makeExternJsUri(Gadget gadget, Collection<String> extern) {
-    String container = gadget.getContext().getContainer();
+  public Uri makeExternJsUri(GadgetContext ctx, Collection<String> extern) {
+    String container = ctx.getContainer();
     String jsHost = getReqConfig(container, JS_HOST_PARAM);
     String jsPathBase = getReqConfig(container, JS_PATH_PARAM);
 
@@ -77,24 +76,24 @@ public class DefaultJsUriManager impleme
 
     // Pass through nocache param for dev purposes.
     uri.addQueryParameter(Param.NO_CACHE.getKey(),
-        gadget.getContext().getIgnoreCache() ? "1" : "0");
+        ctx.getIgnoreCache() ? "1" : "0");
 
     // Pass through debug param for debugging use.
     uri.addQueryParameter(Param.DEBUG.getKey(),
-        gadget.getContext().getDebug() ? "1" : "0");
-    
+        ctx.getDebug() ? "1" : "0");
+
     uri.addQueryParameter(Param.CONTAINER_MODE.getKey(),
-        gadget.getContext().getRenderingContext() == 
RenderingContext.CONTAINER ? "1" : "0");
+        ctx.getRenderingContext() == RenderingContext.CONTAINER ? "1" : "0");
 
     // Pass through gadget Uri
     if (addGadgetUri()) {
-      uri.addQueryParameter(Param.URL.getKey(), 
gadget.getSpec().getUrl().toString());
+      uri.addQueryParameter(Param.URL.getKey(), ctx.getUrl().toString());
     }
 
     // Finally, version it, but only if !nocache.
-    if (versioner != null && !gadget.getContext().getIgnoreCache()) {
+    if (versioner != null && !ctx.getIgnoreCache()) {
       uri.addQueryParameter(Param.VERSION.getKey(),
-          versioner.version(gadget.getContext().getUrl(), container, extern));
+          versioner.version(ctx.getUrl(), container, extern));
     }
 
     return uri.toUri();
@@ -132,12 +131,12 @@ public class DefaultJsUriManager impleme
       return INVALID_URI;
     }
     path = path.substring(jsPrefix.length());
-    
+
     // Convenience suffix: pull off .js if present; leave alone otherwise.
     if (path.endsWith(JS_SUFFIX)) {
       path = path.substring(0, path.length() - JS_SUFFIX.length());
     }
-    
+
     while (path.startsWith("/")) {
       path = path.substring(1);
     }
@@ -154,7 +153,7 @@ public class DefaultJsUriManager impleme
       status = versioner.validate(gadgetUri, container, libs, version);
     }
 
-    return new JsUri(status, libs);
+    return new JsUri(status, uri, libs);
   }
 
   static String addJsLibs(Collection<String> extern) {

Modified: 
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/JsUriManager.java
URL: 
http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/JsUriManager.java?rev=1022286&r1=1022285&r2=1022286&view=diff
==============================================================================
--- 
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/JsUriManager.java
 (original)
+++ 
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/JsUriManager.java
 Wed Oct 13 20:40:04 2010
@@ -22,8 +22,10 @@ import java.util.Collection;
 import java.util.Collections;
 
 import org.apache.shindig.common.uri.Uri;
-import org.apache.shindig.gadgets.Gadget;
+import org.apache.shindig.gadgets.GadgetContext;
 import org.apache.shindig.gadgets.GadgetException;
+import org.apache.shindig.gadgets.RenderingContext;
+import org.apache.shindig.gadgets.uri.UriCommon.Param;
 
 import com.google.inject.ImplementedBy;
 
@@ -32,11 +34,11 @@ import com.google.inject.ImplementedBy;
  */
 public interface JsUriManager {
   /**
-   * @param gadget The gadget in which the requested JS will be externed.
+   * @param ctx The gadget context in which the requested JS will be externed.
    * @param extern The list of features that js is needed for.
    * @return The uri for the externed javascript that includes all listed 
extern libraries.
    */
-  Uri makeExternJsUri(Gadget gadget, Collection<String> extern);
+  Uri makeExternJsUri(GadgetContext ctx, Collection<String> extern);
 
   /**
    * Processes the inbound URL, for use by serving code in determining which 
JS to serve
@@ -47,28 +49,53 @@ public interface JsUriManager {
    */
   JsUri processExternJsUri(Uri uri) throws GadgetException;
 
-  public static class JsUri {
-    private final UriStatus status;
+  public static class JsUri extends ProxyUriBase {
     private final Collection<String> libs;
-
-    public JsUri(UriStatus status, Collection<String> libs) {
-      this.status = status;
+    private final String onload;
+    private final boolean jsload;
+    private final RenderingContext context;
+
+    public JsUri(UriStatus status, Uri origUri, Collection<String> libs) {
+      super(status, origUri);
+      if (origUri != null) {
+        this.context = 
"1".equals(origUri.getQueryParameter(Param.CONTAINER_MODE.getKey())) ?
+            RenderingContext.CONTAINER : RenderingContext.GADGET;
+        this.jsload = 
"1".equals(origUri.getQueryParameter(Param.JSLOAD.getKey()));
+        this.onload = origUri.getQueryParameter(Param.ONLOAD.getKey());
+      } else {
+        this.context = RenderingContext.GADGET;
+        this.jsload = false;
+        this.onload = null;
+      }
       this.libs = libs;
     }
 
-    public UriStatus getStatus() {
-      return status;
+    public JsUri(UriStatus status, Collection<String> libs) {
+      this(status, null, libs);
     }
 
     public Collection<String> getLibs() {
       return Collections.unmodifiableCollection(libs);
     }
+
+    public RenderingContext getContext() {
+      return context;
+    }
+
+    public String getOnload() {
+      return onload;
+    }
+
+    public boolean isJsload() {
+      return jsload;
+    }
   }
 
   @ImplementedBy(DefaultJsVersioner.class)
   public interface Versioner {
     /**
-     * @param gadgeUri Gadget for which extern Uri was generated.
+     * @param gadgetUri Gadget for which extern Uri was generated.
+     * @param container The container for this gadget.
      * @param extern Collection of libs externed.
      * @return Version string for the Uri.
      */

Modified: 
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/ProxyUriBase.java
URL: 
http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/ProxyUriBase.java?rev=1022286&r1=1022285&r2=1022286&view=diff
==============================================================================
--- 
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/ProxyUriBase.java
 (original)
+++ 
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/ProxyUriBase.java
 Wed Oct 13 20:40:04 2010
@@ -24,6 +24,7 @@ import org.apache.commons.lang.StringUti
 import org.apache.commons.lang.math.NumberUtils;
 import org.apache.shindig.common.uri.Uri;
 import org.apache.shindig.common.uri.UriBuilder;
+import org.apache.shindig.config.ContainerConfig;
 import org.apache.shindig.gadgets.Gadget;
 import org.apache.shindig.gadgets.GadgetException;
 import org.apache.shindig.gadgets.http.HttpRequest;
@@ -40,7 +41,7 @@ public class ProxyUriBase {
   private Integer refresh = null;
   private boolean debug = false;
   private boolean noCache = false;
-  private String container = null;
+  private String container = ContainerConfig.DEFAULT_CONTAINER;
   private String gadget = null;
   private String rewriteMimeType = null;
   private boolean sanitizeContent = false;
@@ -81,10 +82,14 @@ public class ProxyUriBase {
       refresh = getIntegerValue(uri.getQueryParameter(Param.REFRESH.getKey()));
       debug = getBooleanValue(uri.getQueryParameter(Param.DEBUG.getKey()));
       noCache = 
getBooleanValue(uri.getQueryParameter(Param.NO_CACHE.getKey()));
-      container = uri.getQueryParameter(Param.CONTAINER.getKey());
-      if (container == null) {
+      String newContainer = uri.getQueryParameter(Param.CONTAINER.getKey());
+      if (newContainer == null) {
         // Support "synd" for legacy purposes.
-        container = uri.getQueryParameter(Param.SYND.getKey());
+        newContainer = uri.getQueryParameter(Param.SYND.getKey());
+      }
+      // Preserve "default" container.
+      if (newContainer != null) {
+        container = newContainer;
       }
       gadget = uri.getQueryParameter(Param.GADGET.getKey());
       rewriteMimeType = 
uri.getQueryParameter(Param.REWRITE_MIME_TYPE.getKey());

Modified: 
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/UriCommon.java
URL: 
http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/UriCommon.java?rev=1022286&r1=1022285&r2=1022286&view=diff
==============================================================================
--- 
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/UriCommon.java
 (original)
+++ 
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/UriCommon.java
 Wed Oct 13 20:40:04 2010
@@ -43,9 +43,13 @@ public interface UriCommon {
     TYPE("type"),
     REWRITE_MIME_TYPE("rewriteMime"),
     SANITIZE("sanitize"),
-    CAJOLE("cajole"),    
+    CAJOLE("cajole"),
+
+    // JS request params
     CONTAINER_MODE("c"),
-    
+    JSLOAD("jsload"),
+    ONLOAD("onload"),
+
     // Proxy resize params:
     RESIZE_HEIGHT("resize_h"),
     RESIZE_WIDTH("resize_w"),
@@ -61,12 +65,12 @@ public interface UriCommon {
     // This is a legacy param, superseded by container.
     @Deprecated
     SYND("synd");
-   
+
     private final String key;
     private Param(String key) {
       this.key = key;
     }
-    
+
     public String getKey() {
       return key;
     }

Modified: 
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriterTest.java
URL: 
http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriterTest.java?rev=1022286&r1=1022285&r2=1022286&view=diff
==============================================================================
--- 
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriterTest.java
 (original)
+++ 
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriterTest.java
 Wed Oct 13 20:40:04 2010
@@ -149,7 +149,7 @@ public class RenderingGadgetRewriterTest
   @Test
   public void defaultOutput() throws Exception {
     Gadget gadget = makeDefaultGadget();
-    
+
     String rewritten = rewrite(gadget, BODY_CONTENT);
 
     Matcher matcher = DOCUMENT_SPLIT_PATTERN.matcher(rewritten);
@@ -277,7 +277,7 @@ public class RenderingGadgetRewriterTest
         ImmutableList.of(fooResource),
         libs,
         ImmutableList.of(fooResource, inline("bar-c", "bar-d"), 
inline("baz-c", "baz-d")));
-    
+
     String rewritten = rewrite(gadget, "");
 
     Set<String> actual = getInjectedScript(rewritten);
@@ -305,7 +305,7 @@ public class RenderingGadgetRewriterTest
 
     assertTrue("Requested scripts not inlined.", 
rewritten.contains("foo_content();"));
   }
-  
+
   @Test
   public void featuresNotInjectedWhenRemoved() throws Exception {
     String gadgetXml =
@@ -345,7 +345,7 @@ public class RenderingGadgetRewriterTest
         ImmutableList.of(inline("foo_content();", "foo_content_dbg();")),
         ImmutableSet.<String>of(),
         ImmutableList.<FeatureResource>of());
-    
+
     String rewritten = rewrite(gadget, "");
 
     assertTrue("Added script not inlined.", 
rewritten.contains("foo_content();"));
@@ -423,7 +423,7 @@ public class RenderingGadgetRewriterTest
         ImmutableList.of(inline("foo_content();", "foo_content_debug();")),
         ImmutableSet.<String>of(),
         ImmutableList.<FeatureResource>of());
-    
+
     String rewritten = rewrite(gadget, BODY_CONTENT);
 
     Matcher matcher = DOCUMENT_SPLIT_PATTERN.matcher(rewritten);
@@ -463,13 +463,13 @@ public class RenderingGadgetRewriterTest
     };
 
     Gadget gadget = makeGadgetWithSpec(gadgetXml).setContext(context);
-    
+
     expectFeatureCalls(gadget,
         ImmutableList.of(inline("foo_content();", "foo_content_debug();"),
                          extern("http://example.org/external.js";, "dbg")),
         ImmutableSet.of("baz"),
         ImmutableList.of(inline("does-not-matter", "dbg")));
-    
+
     String rewritten = rewrite(gadget, "");
 
     Set<String> actual = getInjectedScript(rewritten);
@@ -498,12 +498,12 @@ public class RenderingGadgetRewriterTest
       "</Module>";
 
     Gadget gadget = makeGadgetWithSpec(gadgetXml);
-    
+
     expectFeatureCalls(gadget,
         ImmutableList.of(inline("foo", "dbg")),
         ImmutableSet.<String>of(),
         ImmutableList.<FeatureResource>of());
-    
+
     config.data.put(FEATURES_KEY, ImmutableMap.of("foo", "blah"));
 
     String rewritten = rewrite(gadget, "");
@@ -537,7 +537,7 @@ public class RenderingGadgetRewriterTest
         ImmutableList.of(inline("foo", "foo-dbg")),
         ImmutableSet.of("bar"),
         ImmutableList.of(inline("bar", "bar-dbg")));
-    
+
     config.data.put(FEATURES_KEY, ImmutableMap.of(
         "foo", "blah",
         "bar", "baz"
@@ -568,7 +568,7 @@ public class RenderingGadgetRewriterTest
       "</Module>";
 
     Gadget gadget = makeGadgetWithSpec(gadgetXml);
-    
+
     expectFeatureCalls(gadget,
         ImmutableList.of(inline("foo", "foo-dbg"), inline("foo2", "foo2-dbg")),
         ImmutableSet.<String>of(),
@@ -580,7 +580,7 @@ public class RenderingGadgetRewriterTest
 
     JSONObject json = getConfigJson(rewritten);
     assertEquals("blah", json.get("foo"));
-    
+
     JSONObject util = json.getJSONObject("core.util");
     JSONObject foo = util.getJSONObject("foo");
     assertEquals("baz", foo.get("bar"));
@@ -646,7 +646,7 @@ public class RenderingGadgetRewriterTest
         "No shindig.xhrwrapper.oauthTokenName configuration present in 
rewritten HTML.",
         "oauth", "serviceName", "tokenName");
   }
-  
+
   private void checkXhrWrapperConfigurationInjection(String message, String 
auth, String oauthService, String oauthToken)
       throws Exception {
     String oAuthBlock = "";
@@ -676,21 +676,21 @@ public class RenderingGadgetRewriterTest
       "</ModulePrefs>" +
       "<Content type='html' href='http://foo.com/bar/baz.html'" + authzAttr + 
" />" +
       "</Module>";
-    
+
     String expected = '{' +
         (oauthService == null ? "" : "\"oauthService\":\"serviceName\",") +
         "\"contentUrl\":\"http://foo.com/bar/baz.html\""; +
         (auth == null ? "" : ",\"authorization\":\"" + auth + '\"') +
         (oauthToken == null ? "" : ",\"oauthTokenName\":\"tokenName\"") +
         '}';
-    
+
     Gadget gadget = makeGadgetWithSpec(gadgetXml);
     gadget.setCurrentView(gadget.getSpec().getView("default"));
     String rewritten = rewrite(gadget, BODY_CONTENT);
-    
+
     assertXhrConfigContains(message, expected, rewritten);
   }
-  
+
   private void assertXhrConfigContains(String message, String expected, String 
content) throws Exception {
     // TODO: make this test a little more robust. This check ensures that 
ordering is not taken
     // into account during config comparison.
@@ -712,12 +712,12 @@ public class RenderingGadgetRewriterTest
       "<Module><ModulePrefs title='' />" +
       "<Content type='html' href='http://foo.com/bar/baz.html' />" +
       "</Module>";
-    
+
     Gadget gadget = makeGadgetWithSpec(gadgetXml);
     gadget.setCurrentView(gadget.getSpec().getView("default"));
-    
+
     String rewritten = rewrite(gadget, BODY_CONTENT);
-    
+
     boolean containsConfig = rewritten.contains("\"shindig.xhrwrapper\"");
     assertFalse("shindig.xhrwrapper configuration present in rewritten HTML.", 
containsConfig);
   }
@@ -732,7 +732,7 @@ public class RenderingGadgetRewriterTest
       "</Module>";
 
     Gadget gadget = makeGadgetWithSpec(gadgetXml);
-    
+
     reset(featureRegistry);
     expect(featureRegistry.getFeatureResources(same(gadget.getContext()),
         eq(ImmutableSet.<String>of()), eq(Lists.<String>newArrayList())))
@@ -751,7 +751,7 @@ public class RenderingGadgetRewriterTest
 
     rewrite(gadget, "");
   }
-  
+
   @Test
   public void unsupportedExternFeatureDoesNotThrow() throws Exception {
     String gadgetXml =
@@ -759,7 +759,7 @@ public class RenderingGadgetRewriterTest
       "</ModulePrefs>" +
       "<Content type='html'/>" +
       "</Module>";
-    
+
     GadgetContext context = new GadgetContext() {
       @Override
       public String getParameter(String name) {
@@ -769,9 +769,9 @@ public class RenderingGadgetRewriterTest
         return null;
       }
     };
-    
+
     Gadget gadget = makeGadgetWithSpec(gadgetXml).setContext(context);
-    
+
     reset(featureRegistry);
     expect(featureRegistry.getFeatureResources(same(gadget.getContext()),
         eq(ImmutableSet.<String>of("bar")), eq(Lists.<String>newArrayList())))
@@ -791,7 +791,7 @@ public class RenderingGadgetRewriterTest
     expect(featureRegistry.getFeatures(eq(ImmutableList.of("core"))))
         .andReturn(ImmutableList.of("core"));
     replay(featureRegistry);
-    
+
     rewrite(gadget, "");
   }
 
@@ -941,7 +941,7 @@ public class RenderingGadgetRewriterTest
     assertFalse("Didn't rewrite when sanitize was '0'.",
         BODY_CONTENT.equals(rewrite(gadget, BODY_CONTENT)));
   }
-  
+
   private void expectFeatureCalls(Gadget gadget,
                                   List<FeatureResource> gadgetResources,
                                   Set<String> externLibs,
@@ -966,11 +966,11 @@ public class RenderingGadgetRewriterTest
         andReturn(ImmutableSet.of("foo", "foo2", "core.util")).anyTimes();
     replay(featureRegistry);
   }
-  
+
   private FeatureResource inline(String content, String debugContent) {
     return new FeatureResource.Simple(content, debugContent);
   }
-  
+
   private FeatureResource extern(String content, String debugContent) {
     return new FeatureResource.Simple(content, debugContent) {
       @Override
@@ -999,7 +999,7 @@ public class RenderingGadgetRewriterTest
   }
 
   private static class FakeJsUriManager implements JsUriManager {
-    public Uri makeExternJsUri(Gadget gadget, Collection<String> extern) {
+    public Uri makeExternJsUri(GadgetContext ctx, Collection<String> extern) {
       return Uri.parse("/js/" + Join.join(":", extern));
     }
 

Added: 
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/JsServletTest.java
URL: 
http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/JsServletTest.java?rev=1022286&view=auto
==============================================================================
--- 
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/JsServletTest.java
 (added)
+++ 
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/JsServletTest.java
 Wed Oct 13 20:40:04 2010
@@ -0,0 +1,167 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.shindig.gadgets.servlet;
+
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.isA;
+
+import com.google.caja.util.Lists;
+
+import org.apache.shindig.common.uri.Uri;
+import org.apache.shindig.gadgets.GadgetContext;
+import org.apache.shindig.gadgets.RenderingContext;
+import org.apache.shindig.gadgets.uri.JsUriManager;
+import org.apache.shindig.gadgets.uri.JsUriManager.JsUri;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Collection;
+
+import javax.servlet.http.HttpServletResponse;
+
+public class JsServletTest extends ServletTestFixture {
+  private static final String CONTAINER_PARAM = "im_a_container";
+  private static final String ONLOAD_PARAM = "onload_me";
+  private static final int REFRESH_INTERVAL_SEC = 200;
+  private static final int TIMEOUT_SEC = 1000;
+
+  private final JsServlet servlet = new JsServlet();
+  private JsServlet.CachingSetter httpUtilMock;
+  private JsHandler jsHandlerMock;
+  private JsUriManager jsUriManagerMock;
+
+  @Before
+  public void setUp() throws Exception {
+    httpUtilMock = mock(JsServlet.CachingSetter.class);
+    servlet.setCachingSetter(httpUtilMock);
+
+    jsHandlerMock = mock(JsHandler.class);
+    servlet.setJsHandler(jsHandlerMock);
+
+    jsUriManagerMock = mock(JsUriManager.class);
+    servlet.setUrlGenerator(jsUriManagerMock);
+
+    // TODO: Abstract this out into a helper function associated with Uri 
class.
+    expect(request.getScheme()).andReturn("http");
+    expect(request.getServerPort()).andReturn(8080);
+    expect(request.getServerName()).andReturn("localhost");
+    expect(request.getRequestURI()).andReturn("/gadgets/js");
+    expect(request.getQueryString()).andReturn(null);
+  }
+
+  private JsUri mockJsUri(String container, RenderingContext context, boolean 
debug,
+      boolean jsload, boolean nocache, String onload, int refresh, String... 
libs) {
+    JsUri result = mock(JsUri.class);
+    expect(result.getContainer()).andReturn(container).anyTimes();
+    expect(result.getContext()).andReturn(context).anyTimes();
+    expect(result.getOnload()).andReturn(onload).anyTimes();
+    expect(result.getRefresh()).andReturn(refresh).anyTimes();
+    expect(result.isDebug()).andReturn(debug).anyTimes();
+    expect(result.isNoCache()).andReturn(nocache).anyTimes();
+    expect(result.isJsload()).andReturn(jsload).anyTimes();
+    if (libs != null) {
+      expect(result.getLibs()).andReturn(Lists.newArrayList(libs)).anyTimes();
+    }
+    return result;
+  }
+
+  @Test
+  @SuppressWarnings("unchecked")
+  public void testDoJsloadNormal() throws Exception {
+    String url = "http://localhost/gadgets/js/feature.js?v=abc";;
+    JsUri jsUri = mockJsUri(CONTAINER_PARAM, RenderingContext.CONTAINER, true, 
true, false,
+        ONLOAD_PARAM, REFRESH_INTERVAL_SEC);
+
+    
expect(jsUriManagerMock.processExternJsUri(isA(Uri.class))).andReturn(jsUri);
+    expect(jsUriManagerMock.makeExternJsUri(isA(GadgetContext.class),
+        isA(Collection.class))).andReturn(Uri.parse(url));
+    httpUtilMock.setCachingHeaders(recorder, REFRESH_INTERVAL_SEC, false);
+    replay();
+
+    servlet.doGet(request, recorder);
+    assertEquals(HttpServletResponse.SC_OK, recorder.getHttpStatusCode());
+    assertEquals(
+        String.format(JsServlet.JSLOAD_JS_TPL, url
+            + "&onload=" + ONLOAD_PARAM
+            + "&nocache=0"),
+        recorder.getResponseAsString());
+    verify();
+  }
+
+  @Test
+  @SuppressWarnings("unchecked")
+  public void testDoJsloadWithJsLoadTimeout() throws Exception {
+    String url = "http://localhost/gadgets/js/feature.js?v=abc";;
+    JsUri jsUri = mockJsUri(CONTAINER_PARAM, RenderingContext.CONTAINER, true, 
true,
+        false, ONLOAD_PARAM, -1); // Disable refresh interval.
+
+    
expect(jsUriManagerMock.processExternJsUri(isA(Uri.class))).andReturn(jsUri);
+    expect(jsUriManagerMock.makeExternJsUri(isA(GadgetContext.class),
+        isA(Collection.class))).andReturn(Uri.parse(url));
+    servlet.setJsloadTtlSecs(TIMEOUT_SEC); // Enable JS load timeout.
+    httpUtilMock.setCachingHeaders(recorder, TIMEOUT_SEC, false);
+    replay();
+
+    servlet.doGet(request, recorder);
+    assertEquals(HttpServletResponse.SC_OK, recorder.getHttpStatusCode());
+    assertEquals(
+        String.format(JsServlet.JSLOAD_JS_TPL, url
+            + "&onload=" + ONLOAD_PARAM
+            + "&nocache=0"),
+        recorder.getResponseAsString());
+    verify();
+  }
+
+  @Test
+  public void testDoJsloadNoOnload() throws Exception {
+    JsUri jsUri = mockJsUri(CONTAINER_PARAM, RenderingContext.CONTAINER, true, 
true, false,
+        null, // lacks &onload=
+        REFRESH_INTERVAL_SEC);
+    
expect(jsUriManagerMock.processExternJsUri(isA(Uri.class))).andReturn(jsUri);
+    replay();
+
+    servlet.doGet(request, recorder);
+    assertEquals(HttpServletResponse.SC_BAD_REQUEST, 
recorder.getHttpStatusCode());
+    assertEquals(JsServlet.JSLOAD_ONLOAD_ERROR, 
recorder.getResponseAsString());
+    verify();
+  }
+
+  @Test
+  public void testDoJsloadNoCache() throws Exception {
+    String url = "http://localhost/gadgets/js/feature.js?v=abc";;
+    JsUri jsUri = mockJsUri(CONTAINER_PARAM, RenderingContext.CONTAINER, true, 
true,
+        true, // Set to no cache.
+        ONLOAD_PARAM, REFRESH_INTERVAL_SEC);
+
+    
expect(jsUriManagerMock.processExternJsUri(isA(Uri.class))).andReturn(jsUri);
+    expect(jsUriManagerMock.makeExternJsUri(isA(GadgetContext.class),
+        isA(Collection.class))).andReturn(Uri.parse(url));
+    httpUtilMock.setCachingHeaders(recorder, 0, false); // TTL of 0 is set.
+    replay();
+
+    servlet.doGet(request, recorder);
+    assertEquals(HttpServletResponse.SC_OK, recorder.getHttpStatusCode());
+    assertEquals(
+        String.format(JsServlet.JSLOAD_JS_TPL, url
+            + "&onload=" + ONLOAD_PARAM
+            + "&nocache=1"),
+        recorder.getResponseAsString());
+    verify();
+  }
+}

Modified: 
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/uri/DefaultJsUriManagerTest.java
URL: 
http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/uri/DefaultJsUriManagerTest.java?rev=1022286&r1=1022285&r2=1022286&view=diff
==============================================================================
--- 
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/uri/DefaultJsUriManagerTest.java
 (original)
+++ 
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/uri/DefaultJsUriManagerTest.java
 Wed Oct 13 20:40:04 2010
@@ -53,25 +53,25 @@ public class DefaultJsUriManagerTest {
   public void makeMissingHostConfig() {
     ContainerConfig config = mockConfig(null, "/gadgets/js");
     DefaultJsUriManager manager = makeManager(config, null);
-    Gadget gadget = mockGadget(false, false);
-    manager.makeExternJsUri(gadget, null);
+    GadgetContext ctx = mockGadgetContext(false, false);
+    manager.makeExternJsUri(ctx, null);
   }
 
   @Test(expected = RuntimeException.class)
   public void makeMissingPathConfig() {
     ContainerConfig config = mockConfig("foo", null);
     DefaultJsUriManager manager = makeManager(config, null);
-    Gadget gadget = mockGadget(false, false);
-    manager.makeExternJsUri(gadget, null);
+    GadgetContext ctx = mockGadgetContext(false, false);
+    manager.makeExternJsUri(ctx, null);
   }
 
   @Test
   public void makeJsUriNoPathSlashNoVersion() {
     ContainerConfig config = mockConfig("http://www.js.org";, "/gadgets/js/");
     TestDefaultJsUriManager manager = makeManager(config, null);
-    Gadget gadget = mockGadget(false, false);
+    GadgetContext ctx = mockGadgetContext(false, false);
     List<String> extern = Lists.newArrayList("feature");
-    Uri jsUri = manager.makeExternJsUri(gadget, extern);
+    Uri jsUri = manager.makeExternJsUri(ctx, extern);
     assertFalse(manager.hadError());
     assertEquals("http", jsUri.getScheme());
     assertEquals("www.js.org", jsUri.getAuthority());
@@ -86,9 +86,9 @@ public class DefaultJsUriManagerTest {
   public void makeJsUriAddPathSlashNoVersion() {
     ContainerConfig config = mockConfig("http://www.js.org";, "/gadgets/js");
     TestDefaultJsUriManager manager = makeManager(config, null);
-    Gadget gadget = mockGadget(false, false);
+    GadgetContext ctx = mockGadgetContext(false, false);
     List<String> extern = Lists.newArrayList("feature");
-    Uri jsUri = manager.makeExternJsUri(gadget, extern);
+    Uri jsUri = manager.makeExternJsUri(ctx, extern);
     assertFalse(manager.hadError());
     assertEquals("http", jsUri.getScheme());
     assertEquals("www.js.org", jsUri.getAuthority());
@@ -102,12 +102,12 @@ public class DefaultJsUriManagerTest {
   @Test
   public void makeJsUriAddPathSlashVersioned() {
     ContainerConfig config = mockConfig("http://www.js.org";, "/gadgets/js");
-    Gadget gadget = mockGadget(false, false);
+    GadgetContext ctx = mockGadgetContext(false, false);
     List<String> extern = Lists.newArrayList("feature");
     String version = "verstring";
     Versioner versioner = this.mockVersioner(extern, version, version);
     TestDefaultJsUriManager manager = makeManager(config, versioner);
-    Uri jsUri = manager.makeExternJsUri(gadget, extern);
+    Uri jsUri = manager.makeExternJsUri(ctx, extern);
     assertFalse(manager.hadError());
     assertEquals("http", jsUri.getScheme());
     assertEquals("www.js.org", jsUri.getAuthority());
@@ -122,12 +122,12 @@ public class DefaultJsUriManagerTest {
   @Test
   public void makeJsUriWithVersionerNoVersionOnIgnoreCache() {
     ContainerConfig config = mockConfig("http://www.js.org";, "/gadgets/js");
-    Gadget gadget = mockGadget(true, false);  // no cache
+    GadgetContext ctx = mockGadgetContext(true, false);  // no cache
     List<String> extern = Lists.newArrayList("feature");
     String version = "verstring";
     Versioner versioner = this.mockVersioner(extern, version, version);
     TestDefaultJsUriManager manager = makeManager(config, versioner);
-    Uri jsUri = manager.makeExternJsUri(gadget, extern);
+    Uri jsUri = manager.makeExternJsUri(ctx, extern);
     assertFalse(manager.hadError());
     assertEquals("http", jsUri.getScheme());
     assertEquals("www.js.org", jsUri.getAuthority());
@@ -139,14 +139,14 @@ public class DefaultJsUriManagerTest {
     assertEquals("0", jsUri.getQueryParameter(Param.DEBUG.getKey()));
     assertEquals("0", jsUri.getQueryParameter(Param.CONTAINER_MODE.getKey()));
   }
-  
+
   @Test
   public void makeJsUriWithContainerContext() {
     ContainerConfig config = mockConfig("http://www.js.org";, "/gadgets/js/");
     TestDefaultJsUriManager manager = makeManager(config, null);
-    Gadget gadget = mockGadget(false, false, true);
+    GadgetContext ctx = mockGadgetContext(false, false, true);
     List<String> extern = Lists.newArrayList("feature", "another");
-    Uri jsUri = manager.makeExternJsUri(gadget, extern);
+    Uri jsUri = manager.makeExternJsUri(ctx, extern);
     assertFalse(manager.hadError());
     assertEquals("http", jsUri.getScheme());
     assertEquals("www.js.org", jsUri.getAuthority());
@@ -278,12 +278,12 @@ public class DefaultJsUriManagerTest {
   public void makeAndProcessSymmetric() throws GadgetException {
     // Make...
     ContainerConfig config = mockConfig("http://www.js.org";, "/gadgets/js");
-    Gadget gadget = mockGadget(false, false);
+    GadgetContext ctx = mockGadgetContext(false, false);
     List<String> extern = Lists.newArrayList("feature1", "feature2", 
"feature3");
     String version = "verstring";
     Versioner versioner = mockVersioner(extern, version, version);
     TestDefaultJsUriManager manager = makeManager(config, versioner);
-    Uri jsUri = manager.makeExternJsUri(gadget, extern);
+    Uri jsUri = manager.makeExternJsUri(ctx, extern);
     assertFalse(manager.hadError());
     assertEquals("http", jsUri.getScheme());
     assertEquals("www.js.org", jsUri.getAuthority());
@@ -349,11 +349,11 @@ public class DefaultJsUriManagerTest {
     return versioner;
   }
 
-  private Gadget mockGadget(boolean nocache, boolean debug) {
-    return mockGadget(nocache, debug, false);
+  private GadgetContext mockGadgetContext(boolean nocache, boolean debug) {
+    return mockGadgetContext(nocache, debug, false);
   }
-  
-  private Gadget mockGadget(boolean nocache, boolean debug, boolean 
isContainer) {
+
+  private GadgetContext mockGadgetContext(boolean nocache, boolean debug, 
boolean isContainer) {
     GadgetContext context = createMock(GadgetContext.class);
     expect(context.getContainer()).andReturn(CONTAINER).anyTimes();
     expect(context.getIgnoreCache()).andReturn(nocache).anyTimes();
@@ -362,7 +362,7 @@ public class DefaultJsUriManagerTest {
     expect(context.getRenderingContext()).andReturn(
         isContainer ? RenderingContext.CONTAINER : 
RenderingContext.GADGET).anyTimes();
     replay(context);
-    return new Gadget().setContext(context);
+    return context;
   }
 
   private TestDefaultJsUriManager makeManager(ContainerConfig config, 
Versioner versioner) {

Added: 
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/uri/JsUriManagerTest.java
URL: 
http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/uri/JsUriManagerTest.java?rev=1022286&view=auto
==============================================================================
--- 
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/uri/JsUriManagerTest.java
 (added)
+++ 
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/uri/JsUriManagerTest.java
 Wed Oct 13 20:40:04 2010
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.shindig.gadgets.uri;
+
+import com.google.caja.util.Lists;
+
+import junit.framework.TestCase;
+
+import org.apache.shindig.common.uri.UriBuilder;
+import org.apache.shindig.config.ContainerConfig;
+import org.apache.shindig.gadgets.RenderingContext;
+import org.apache.shindig.gadgets.uri.UriCommon.Param;
+import org.junit.Test;
+
+import java.util.Collections;
+import java.util.List;
+
+public class JsUriManagerTest extends TestCase {
+  private static final UriStatus STATUS = UriStatus.VALID_UNVERSIONED;
+  private static final List<String> LIBS = Lists.newArrayList("feat1", 
"feat2");
+  private static final String CONTAINER_VALUE = "ig";
+  private static final String ONLOAD_VALUE = "ol";
+
+  @Test
+  public void testJsUriNormal() throws Exception {
+    UriBuilder builder = new UriBuilder();
+    builder.setScheme("http");
+    builder.setAuthority("localohst");
+    builder.setPath("/gadgets/js/feature.js");
+    builder.addQueryParameter(Param.CONTAINER.getKey(), CONTAINER_VALUE);
+    builder.addQueryParameter(Param.CONTAINER_MODE.getKey(), "1");
+    builder.addQueryParameter(Param.JSLOAD.getKey(), "1");
+    builder.addQueryParameter(Param.NO_CACHE.getKey(), "1");
+    builder.addQueryParameter(Param.ONLOAD.getKey(), ONLOAD_VALUE);
+
+    JsUriManager.JsUri jsUri = new JsUriManager.JsUri(STATUS, builder.toUri(), 
LIBS);
+    assertEquals(RenderingContext.CONTAINER, jsUri.getContext());
+    assertEquals(CONTAINER_VALUE, jsUri.getContainer());
+    assertTrue(jsUri.isJsload());
+    assertTrue(jsUri.isNoCache());
+    assertEquals(ONLOAD_VALUE, jsUri.getOnload());
+    assertEquals(LIBS, Lists.newArrayList(jsUri.getLibs()));
+  }
+
+  @Test
+  public void testJsUriNullUri() throws Exception {
+    JsUriManager.JsUri jsUri = new JsUriManager.JsUri(STATUS, null,
+        Collections.<String>emptyList()); // Null URI.
+    assertEquals(RenderingContext.GADGET, jsUri.getContext());
+    assertEquals(ContainerConfig.DEFAULT_CONTAINER, jsUri.getContainer());
+    assertFalse(jsUri.isJsload());
+    assertFalse(jsUri.isNoCache());
+    assertNull(ONLOAD_VALUE, jsUri.getOnload());
+    assertTrue(jsUri.getLibs().isEmpty());
+  }
+}


Reply via email to