You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shindig.apache.org by zh...@apache.org on 2010/11/12 03:04:23 UTC

svn commit: r1034245 - in /shindig/trunk/java/gadgets/src: main/java/org/apache/shindig/gadgets/servlet/ test/java/org/apache/shindig/gadgets/servlet/

Author: zhoresh
Date: Fri Nov 12 02:04:22 2010
New Revision: 1034245

URL: http://svn.apache.org/viewvc?rev=1034245&view=rev
Log:
Ref http://codereview.appspot.com/2988042/
Implement JS data fetch through GadgetHandler

Modified:
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandler.java
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerApi.java
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerService.java
    shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerServiceTest.java
    shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerTest.java

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandler.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandler.java?rev=1034245&r1=1034244&r2=1034245&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandler.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandler.java Fri Nov 12 02:04:22 2010
@@ -27,7 +27,9 @@ import com.google.inject.Inject;
 import org.apache.commons.lang.StringUtils;
 import org.apache.shindig.common.uri.Uri;
 import org.apache.shindig.common.uri.Uri.UriException;
+import org.apache.shindig.gadgets.http.HttpResponse;
 import org.apache.shindig.gadgets.process.ProcessingException;
+import org.apache.shindig.gadgets.servlet.GadgetsHandlerApi.RenderingContext;
 import org.apache.shindig.gadgets.spec.GadgetSpec;
 import org.apache.shindig.protocol.BaseRequestItem;
 import org.apache.shindig.protocol.Operation;
@@ -47,6 +49,9 @@ import java.util.concurrent.ExecutionExc
 import java.util.concurrent.ExecutorCompletionService;
 import java.util.concurrent.ExecutorService;
 
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
 import javax.servlet.http.HttpServletResponse;
 
 /**
@@ -62,6 +67,8 @@ public class GadgetsHandler {
   static final String FAILURE_TOKEN = "Failed to get gadget token.";
   @VisibleForTesting
   static final String FAILURE_PROXY = "Failed to get proxy data.";
+  @VisibleForTesting
+  static final String FAILURE_JS = "Failed to get js data.";
 
   private static final List<String> DEFAULT_METADATA_FIELDS =
       ImmutableList.of("iframeUrl", "userPrefs.*", "modulePrefs.*", "views.*");
@@ -70,6 +77,9 @@ public class GadgetsHandler {
 
   private static final List<String> DEFAULT_PROXY_FIELDS = ImmutableList.of("proxyUrl");
 
+  private static final List<String> DEFAULT_JS_FIELDS = ImmutableList.of("jsUrl");
+
+  private static final Logger LOG = Logger.getLogger(GadgetsHandler.class.getName());
 
   protected final ExecutorService executor;
   protected final GadgetsHandlerService handlerService;
@@ -111,6 +121,24 @@ public class GadgetsHandler {
     }.execute(request);
   }
 
+  @Operation(httpMethods = {"POST", "GET"}, path = "js")
+  public GadgetsHandlerApi.BaseResponse js(BaseRequestItem request)
+      throws ProtocolException {
+    // No need for threading since it is one request
+    GadgetsHandlerApi.BaseResponse response;
+    try {
+      JsRequestData jsRequest = new JsRequestData(request);
+      response = handlerService.getJs(jsRequest);
+    } catch (ProcessingException e) {
+      response = handlerService.createErrorResponse(null, e.getHttpStatusCode(), e.getMessage());
+    } catch (Exception e) {
+      LOG.log(Level.INFO, "Error fetching JS", e);
+      response = handlerService.createErrorResponse(null, HttpResponse.SC_INTERNAL_SERVER_ERROR,
+          FAILURE_JS);
+    }
+    return response;
+  }
+
   @Operation(httpMethods = {"POST", "GET"}, path = "proxy")
   public Map<String, GadgetsHandlerApi.BaseResponse> proxy(BaseRequestItem request)
       throws ProtocolException {
@@ -135,6 +163,12 @@ public class GadgetsHandler {
         beanFilter.getBeanFields(GadgetsHandlerApi.TokenResponse.class, 5));
   }
 
+  @Operation(httpMethods = "GET", path = "/@js.supportedFields")
+  public Set<String> jsSupportedFields(RequestItem request) {
+    return ImmutableSet.copyOf(
+        beanFilter.getBeanFields(GadgetsHandlerApi.JsResponse.class, 5));
+  }
+
   @Operation(httpMethods = "GET", path = "/@proxy.supportedFields")
   public Set<String> proxySupportedFields(RequestItem request) {
     return ImmutableSet.copyOf(
@@ -267,7 +301,7 @@ public class GadgetsHandler {
     public AbstractRequest(String url, BaseRequestItem request, List<String> defaultFields)
         throws ProcessingException {
       try {
-        this.uri = Uri.parse(url);
+        this.uri = (url != null ? Uri.parse(url) : null);
       } catch (UriException e) {
         throw new ProcessingException("Bad url - " + url, HttpServletResponse.SC_BAD_REQUEST);
       }
@@ -317,6 +351,36 @@ public class GadgetsHandler {
     }
   }
 
+  protected class JsRequestData extends AbstractRequest implements GadgetsHandlerApi.JsRequest {
+    private final Integer refresh;
+    private final boolean debug;
+    private final boolean ignoreCache;
+    private final List<String> features;
+    private final RenderingContext context;
+    private final String onload;
+    private final String gadget;
+
+    public JsRequestData(BaseRequestItem request) throws ProcessingException {
+      super(null, request, DEFAULT_JS_FIELDS);
+      this.ignoreCache = getBooleanParam(request, "ignoreCache");
+      this.debug = getBooleanParam(request, "debug");
+      this.refresh = getIntegerParam(request, "refresh");
+      this.features = request.getListParameter("features");
+      this.context = (getBooleanParam(request, "c") ?
+          RenderingContext.CONTAINER : RenderingContext.GADGET);
+      this.onload = request.getParameter("onload");
+      this.gadget = request.getParameter("gadget");
+    }
+
+    public RenderingContext getContext() { return context; }
+    public boolean getDebug() { return debug; }
+    public List<String> getFeatures() { return features; }
+    public boolean getIgnoreCache() { return ignoreCache; }
+    public String getOnload() { return onload; }
+    public Integer getRefresh() { return refresh; }
+    public String getGadget() { return gadget; }
+  }
+
   protected class ProxyRequestData extends AbstractRequest
       implements GadgetsHandlerApi.ProxyRequest {
 

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerApi.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerApi.java?rev=1034245&r1=1034244&r2=1034245&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerApi.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerApi.java Fri Nov 12 02:04:22 2010
@@ -212,11 +212,21 @@ public class GadgetsHandlerApi {
   }
 
   public interface JsRequest extends BaseRequest {
+    public String getGadget();
+    public Integer getRefresh();
+    public boolean getDebug();
+    public boolean getIgnoreCache();
     public List<String> getFeatures();
-    public boolean getForContainer();
+    public String getOnload();
+    public RenderingContext getContext();
+  }
+
+  public enum RenderingContext {
+    GADGET, CONTAINER
   }
 
   public interface JsResponse extends BaseResponse {
     public Uri getJsUrl();
+    public String getJsContent();
   }
 }

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerService.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerService.java?rev=1034245&r1=1034244&r2=1034245&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerService.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerService.java Fri Nov 12 02:04:22 2010
@@ -19,6 +19,7 @@
 package org.apache.shindig.gadgets.servlet;
 
 import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Joiner;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.inject.Inject;
@@ -29,6 +30,7 @@ import org.apache.commons.io.IOUtils;
 import org.apache.shindig.auth.SecurityToken;
 import org.apache.shindig.auth.SecurityTokenCodec;
 import org.apache.shindig.auth.SecurityTokenException;
+import org.apache.shindig.common.servlet.HttpUtil;
 import org.apache.shindig.common.uri.Uri;
 import org.apache.shindig.common.util.TimeSource;
 import org.apache.shindig.gadgets.Gadget;
@@ -48,6 +50,7 @@ import org.apache.shindig.gadgets.spec.U
 import org.apache.shindig.gadgets.uri.IframeUriManager;
 import org.apache.shindig.gadgets.uri.JsUriManager;
 import org.apache.shindig.gadgets.uri.ProxyUriManager;
+import org.apache.shindig.gadgets.uri.JsUriManager.JsUri;
 import org.apache.shindig.gadgets.uri.ProxyUriManager.ProxyUri;
 import org.apache.shindig.protocol.conversion.BeanDelegator;
 import org.apache.shindig.protocol.conversion.BeanFilter;
@@ -86,6 +89,7 @@ public class GadgetsHandlerService {
           // Enums
           .put(View.ContentType.class, GadgetsHandlerApi.ViewContentType.class)
           .put(UserPref.DataType.class, GadgetsHandlerApi.UserPrefDataType.class)
+          .put(GadgetsHandlerApi.RenderingContext.class, RenderingContext.class)
           .build();
 
   // Provide mapping for internal enums to api enums
@@ -98,6 +102,8 @@ public class GadgetsHandlerService {
           // UserPref.DataType mapping
           .putAll(BeanDelegator.createDefaultEnumMap(UserPref.DataType.class,
               GadgetsHandlerApi.UserPrefDataType.class))
+          .putAll(BeanDelegator.createDefaultEnumMap(GadgetsHandlerApi.RenderingContext.class,
+              RenderingContext.class))
           .build();
 
   protected final TimeSource timeSource;
@@ -106,6 +112,7 @@ public class GadgetsHandlerService {
   protected final SecurityTokenCodec securityTokenCodec;
   protected final ProxyUriManager proxyUriManager;
   protected final JsUriManager jsUriManager;
+  protected final JsHandler jsHandler;
   protected final ProxyHandler proxyHandler;
   protected final BeanDelegator beanDelegator;
   protected final long specRefreshInterval;
@@ -115,6 +122,7 @@ public class GadgetsHandlerService {
   public GadgetsHandlerService(TimeSource timeSource, Processor processor,
       IframeUriManager iframeUriManager, SecurityTokenCodec securityTokenCodec,
       ProxyUriManager proxyUriManager, JsUriManager jsUriManager, ProxyHandler proxyHandler,
+      JsHandler jsHandler,
       @Named("shindig.cache.xml.refreshInterval") long specRefreshInterval,
       BeanFilter beanFilter) {
     this.timeSource = timeSource;
@@ -124,6 +132,7 @@ public class GadgetsHandlerService {
     this.proxyUriManager = proxyUriManager;
     this.jsUriManager = jsUriManager;
     this.proxyHandler = proxyHandler;
+    this.jsHandler = jsHandler;
     this.specRefreshInterval = specRefreshInterval;
     this.beanFilter = beanFilter;
 
@@ -138,15 +147,7 @@ public class GadgetsHandlerService {
    */
   public GadgetsHandlerApi.MetadataResponse getMetadata(GadgetsHandlerApi.MetadataRequest request)
       throws ProcessingException {
-    if (request.getUrl() == null) {
-      throw new ProcessingException("Missing url paramater", HttpResponse.SC_BAD_REQUEST);
-    }
-    if (request.getContainer() == null) {
-      throw new ProcessingException("Missing container paramater", HttpResponse.SC_BAD_REQUEST);
-    }
-    if (request.getFields() == null) {
-      throw new ProcessingException("Missing fields paramater", HttpResponse.SC_BAD_REQUEST);
-    }
+    verifyBaseParams(request, true);
     Set<String> fields = beanFilter.processBeanFields(request.getFields());
 
     GadgetContext context = new MetadataGadgetContext(request);
@@ -172,15 +173,7 @@ public class GadgetsHandlerService {
    */
   public GadgetsHandlerApi.TokenResponse getToken(GadgetsHandlerApi.TokenRequest request)
       throws SecurityTokenException, ProcessingException {
-    if (request.getUrl() == null) {
-      throw new ProcessingException("Missing url paramater", HttpResponse.SC_BAD_REQUEST);
-    }
-    if (request.getContainer() == null) {
-      throw new ProcessingException("Missing container paramater", HttpResponse.SC_BAD_REQUEST);
-    }
-    if (request.getFields() == null) {
-      throw new ProcessingException("Missing fields paramater", HttpResponse.SC_BAD_REQUEST);
-    }
+    verifyBaseParams(request, true);
     Set<String> fields = beanFilter.processBeanFields(request.getFields());
 
     SecurityToken tokenData = convertToken(request.getToken(), request.getContainer(),
@@ -190,17 +183,41 @@ public class GadgetsHandlerService {
     return createTokenResponse(request.getUrl(), token, fields, expiryTimeMs);
   }
 
-  public GadgetsHandlerApi.ProxyResponse getProxy(GadgetsHandlerApi.ProxyRequest request)
+  public GadgetsHandlerApi.JsResponse getJs(GadgetsHandlerApi.JsRequest request)
       throws ProcessingException {
-    if (request.getContainer() == null) {
-      throw new ProcessingException("Missing container paramater", HttpResponse.SC_BAD_REQUEST);
-    }
-    if (request.getUrl() == null) {
-      throw new ProcessingException("Missing proxy url paramater", HttpResponse.SC_BAD_REQUEST);
-    }
-    if (request.getFields() == null) {
-      throw new ProcessingException("Missing fields paramater", HttpResponse.SC_BAD_REQUEST);
+    verifyBaseParams(request, false);
+    Set<String> fields = beanFilter.processBeanFields(request.getFields());
+
+    RenderingContext context =
+        (request.getContext() != null ?
+            (RenderingContext) beanDelegator.convertEnum(request.getContext())
+            : RenderingContext.GADGET);
+    JsUri jsUri = new JsUri(request.getRefresh(), request.getDebug(), request.getIgnoreCache(),
+        request.getContainer(), request.getGadget(), request.getFeatures(), request.getOnload(),
+        false, context);
+
+    Uri servedUri = jsUriManager.makeExternJsUri(jsUri);
+
+    String content = null;
+    Long expireMs = null;
+    if (isFieldIncluded(fields, "content")) {
+      JsHandler.Response response = jsHandler.getJsContent(jsUri, servedUri.getAuthority());
+      content = response.getJsData().toString();
+      if (content.length() == 0) {
+        // No content, meaning no such feature
+        throw new ProcessingException("Feature(s) " + Joiner.on(",").join(jsUri.getLibs())
+            + " not found", HttpResponse.SC_NOT_FOUND);
+      }
+      if (response.isProxyCacheable()) {
+        expireMs = timeSource.currentTimeMillis() + (HttpUtil.getDefaultTtl() * 1000);
+      }
     }
+    return createJsResponse(request.getUrl(), servedUri, content, fields, expireMs);
+  }
+
+  public GadgetsHandlerApi.ProxyResponse getProxy(GadgetsHandlerApi.ProxyRequest request)
+      throws ProcessingException {
+    verifyBaseParams(request, true);
     Set<String> fields = beanFilter.processBeanFields(request.getFields());
 
     ProxyUri proxyUri = createProxyUri(request);
@@ -231,6 +248,22 @@ public class GadgetsHandlerService {
     }
   }
 
+  /**
+   * Verify request parameter are defined.
+   */
+  protected void verifyBaseParams(GadgetsHandlerApi.BaseRequest request, boolean checkUrl)
+      throws ProcessingException {
+    if (checkUrl && request.getUrl() == null) {
+      throw new ProcessingException("Missing url paramater", HttpResponse.SC_BAD_REQUEST);
+    }
+    if (request.getContainer() == null) {
+      throw new ProcessingException("Missing container paramater", HttpResponse.SC_BAD_REQUEST);
+    }
+    if (request.getFields() == null) {
+      throw new ProcessingException("Missing fields paramater", HttpResponse.SC_BAD_REQUEST);
+    }
+  }
+
   protected Long getProxyExpireMs(ProxyUri proxyUri, HttpResponse httpResponse) {
     Long expireMs = null;
     if (httpResponse != null) {
@@ -352,7 +385,7 @@ public class GadgetsHandlerService {
   GadgetsHandlerApi.TokenResponse createTokenResponse(
       Uri url, String token, Set<String> fields, Long tokenExpire) {
     return (GadgetsHandlerApi.TokenResponse) beanFilter.createFilteredBean(
-        beanDelegator.createDelegator("empty", GadgetsHandlerApi.TokenResponse.class,
+        beanDelegator.createDelegator(null, GadgetsHandlerApi.TokenResponse.class,
             ImmutableMap.<String, Object>of(
                 "url", url,
                 "error", BeanDelegator.NULL,
@@ -363,6 +396,21 @@ public class GadgetsHandlerService {
   }
 
   @VisibleForTesting
+  GadgetsHandlerApi.JsResponse createJsResponse(
+      Uri url, Uri jsUri, String content, Set<String> fields, Long expireMs) {
+    return (GadgetsHandlerApi.JsResponse) beanFilter.createFilteredBean(
+        beanDelegator.createDelegator(null, GadgetsHandlerApi.JsResponse.class,
+            ImmutableMap.<String, Object>builder()
+                .put("url", BeanDelegator.nullable(url))
+                .put("error", BeanDelegator.NULL)
+                .put("jsurl", jsUri)
+                .put("jscontent", BeanDelegator.nullable(content))
+                .put("responsetimems", timeSource.currentTimeMillis())
+                .put("expiretimems", BeanDelegator.nullable(expireMs)).build()),
+        fields);
+  }
+
+  @VisibleForTesting
   ProxyUri createProxyUri(GadgetsHandlerApi.ProxyRequest request) {
     ProxyUriManager.ProxyUri proxyUri = new ProxyUriManager.ProxyUri(request.getRefresh(),
         request.getDebug(), request.getIgnoreCahce(), request.getContainer(),

Modified: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerServiceTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerServiceTest.java?rev=1034245&r1=1034244&r2=1034245&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerServiceTest.java (original)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerServiceTest.java Fri Nov 12 02:04:22 2010
@@ -30,9 +30,11 @@ import org.apache.shindig.auth.SecurityT
 import org.apache.shindig.auth.SecurityTokenCodec;
 import org.apache.shindig.auth.SecurityTokenException;
 import org.apache.shindig.common.EasyMockTestCase;
+import org.apache.shindig.common.servlet.HttpUtil;
 import org.apache.shindig.common.uri.Uri;
 import org.apache.shindig.common.util.FakeTimeSource;
 import org.apache.shindig.gadgets.GadgetException;
+import org.apache.shindig.gadgets.RenderingContext;
 import org.apache.shindig.gadgets.GadgetException.Code;
 import org.apache.shindig.gadgets.features.FeatureRegistry;
 import org.apache.shindig.gadgets.http.HttpResponse;
@@ -40,6 +42,7 @@ import org.apache.shindig.gadgets.http.H
 import org.apache.shindig.gadgets.process.ProcessingException;
 import org.apache.shindig.gadgets.uri.JsUriManager;
 import org.apache.shindig.gadgets.uri.ProxyUriManager;
+import org.apache.shindig.gadgets.uri.JsUriManager.JsUri;
 import org.apache.shindig.gadgets.uri.ProxyUriManager.ProxyUri;
 import org.apache.shindig.protocol.conversion.BeanDelegator;
 import org.apache.shindig.protocol.conversion.BeanFilter;
@@ -75,6 +78,7 @@ public class GadgetsHandlerServiceTest e
   private final ProxyUriManager proxyUriManager = mock(ProxyUriManager.class);
   private final JsUriManager jsUriManager = mock(JsUriManager.class);
   private final ProxyHandler proxyHandler = mock(ProxyHandler.class);
+  private final JsHandler jsHandler = mock(JsHandler.class);
 
   private FakeSecurityTokenCodec tokenCodec;
   private GadgetsHandlerService gadgetHandler;
@@ -83,7 +87,7 @@ public class GadgetsHandlerServiceTest e
   public void setUp() {
     tokenCodec = new FakeSecurityTokenCodec();
     gadgetHandler = new GadgetsHandlerService(timeSource, processor, urlGenerator,
-        tokenCodec, proxyUriManager, jsUriManager, proxyHandler,
+        tokenCodec, proxyUriManager, jsUriManager, proxyHandler, jsHandler,
         SPEC_REFRESH_INTERVAL_MS, new BeanFilter());
   }
 
@@ -260,6 +264,71 @@ public class GadgetsHandlerServiceTest e
   }
 
   @Test
+  public void testCreateJsResponse() throws Exception {
+    Uri jsUri = Uri.parse("http://www.shindig.com/js");
+    String content = "content";
+    GadgetsHandlerApi.JsResponse jsResponse =
+        gadgetHandler.createJsResponse(null, jsUri, content, ImmutableSet.of("*"), null);
+    BeanDelegator.validateDelegator(jsResponse);
+  }
+
+  @Test
+  public void testGetJsUri() throws Exception {
+    List<String> fields = ImmutableList.of("jsurl");
+    List<String> features = ImmutableList.of("rpc");
+    Uri resUri = Uri.parse("server.com/gadgets/js/rpc");
+    GadgetsHandlerApi.JsRequest request =
+        createJsRequest(null, CONTAINER, fields, features);
+    Capture<JsUri> uriCapture = new Capture<JsUri>();
+    expect(jsUriManager.makeExternJsUri(capture(uriCapture))).andReturn(resUri);
+    replay();
+
+    GadgetsHandlerApi.JsResponse response = gadgetHandler.getJs(request);
+    JsUri expectedUri = new JsUri(null, false, false, CONTAINER, null,
+        features, null, false, RenderingContext.GADGET);
+    assertEquals(expectedUri, uriCapture.getValue());
+    assertEquals(resUri, response.getJsUrl());
+    assertNull(response.getJsContent());
+    assertNull(response.getExpireTimeMs());
+    verify();
+  }
+
+  @Test(expected = ProcessingException.class)
+  public void testJsNoContainer() throws Exception {
+    List<String> fields = ImmutableList.of("*");
+    GadgetsHandlerApi.JsRequest request =
+        createJsRequest(null, null, fields, ImmutableList.of("rpc"));
+    GadgetsHandlerApi.JsResponse response = gadgetHandler.getJs(request);
+  }
+
+  @Test
+  public void testGetJsData() throws Exception {
+    List<String> fields = ImmutableList.of("*");
+    List<String> features = ImmutableList.of("rpc");
+    Uri resUri = Uri.parse("http://server.com/gadgets/js/rpc");
+    Capture<JsUri> uriCapture = new Capture<JsUri>();
+    String jsContent = "var a;";
+    String onload = "do this";
+    expect(jsUriManager.makeExternJsUri(capture(uriCapture))).andReturn(resUri);
+    expect(jsHandler.getJsContent(EasyMock.isA(JsUri.class), EasyMock.eq("server.com")))
+        .andReturn(new JsHandler.Response(new StringBuilder(jsContent), true));
+    GadgetsHandlerApi.JsRequest request =
+        createJsRequest(FakeProcessor.SPEC_URL.toString(), CONTAINER, fields, features);
+    expect(request.getOnload()).andStubReturn(onload);
+    expect(request.getContext()).andStubReturn(GadgetsHandlerApi.RenderingContext.CONTAINER);
+    replay();
+
+    GadgetsHandlerApi.JsResponse response = gadgetHandler.getJs(request);
+    JsUri expectedUri = new JsUri(null, false, false, CONTAINER, FakeProcessor.SPEC_URL.toString(),
+        features, onload, false, RenderingContext.CONTAINER);
+    assertEquals(expectedUri, uriCapture.getValue());
+    assertEquals(resUri, response.getJsUrl());
+    assertEquals(jsContent, response.getJsContent());
+    assertEquals(timeSource.currentTimeMillis() + HttpUtil.getDefaultTtl() * 1000,
+        response.getExpireTimeMs().longValue());
+    verify();
+  }
+  @Test
   public void testCreateProxyUri() throws Exception {
     GadgetsHandlerApi.ImageParams image = mock(GadgetsHandlerApi.ImageParams.class);
     expect(image.getDoNotExpand()).andStubReturn(true);
@@ -435,6 +504,16 @@ public class GadgetsHandlerServiceTest e
     return request;
   }
 
+  private GadgetsHandlerApi.JsRequest createJsRequest(String gadget, String container,
+      List<String> fields, List<String> features) {
+    GadgetsHandlerApi.JsRequest request = mock(GadgetsHandlerApi.JsRequest.class);
+    EasyMock.expect(request.getFields()).andStubReturn(fields);
+    EasyMock.expect(request.getContainer()).andStubReturn(container);
+    EasyMock.expect(request.getGadget()).andStubReturn(gadget);
+    EasyMock.expect(request.getFeatures()).andStubReturn(features);
+    return request;
+  }
+
   private GadgetsHandlerApi.ProxyRequest createProxyRequest(Uri url, String container,
       List<String> fields) {
     GadgetsHandlerApi.ProxyRequest request = mock(GadgetsHandlerApi.ProxyRequest.class);
@@ -443,6 +522,7 @@ public class GadgetsHandlerServiceTest e
     EasyMock.expect(request.getUrl()).andStubReturn(url);
     return request;
   }
+
   private class FakeSecurityTokenCodec implements SecurityTokenCodec {
     public SecurityToken inputToken = null;
     public SecurityTokenException exc = null;

Modified: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerTest.java?rev=1034245&r1=1034244&r2=1034245&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerTest.java (original)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerTest.java Fri Nov 12 02:04:22 2010
@@ -32,11 +32,13 @@ import org.apache.shindig.common.testing
 import org.apache.shindig.common.testing.TestExecutorService;
 import org.apache.shindig.common.uri.Uri;
 import org.apache.shindig.common.util.FakeTimeSource;
+import org.apache.shindig.gadgets.RenderingContext;
 import org.apache.shindig.gadgets.http.HttpResponse;
 import org.apache.shindig.gadgets.process.ProcessingException;
 import org.apache.shindig.gadgets.spec.GadgetSpec;
 import org.apache.shindig.gadgets.uri.JsUriManager;
 import org.apache.shindig.gadgets.uri.ProxyUriManager;
+import org.apache.shindig.gadgets.uri.JsUriManager.JsUri;
 import org.apache.shindig.gadgets.uri.ProxyUriManager.ProxyUri;
 import org.apache.shindig.protocol.DefaultHandlerRegistry;
 import org.apache.shindig.protocol.HandlerExecutionListener;
@@ -74,6 +76,7 @@ public class GadgetsHandlerTest extends 
   private final ProxyUriManager proxyUriManager = mock(ProxyUriManager.class);
   private final JsUriManager jsUriManager = mock(JsUriManager.class);
   private final ProxyHandler proxyHandler = mock(ProxyHandler.class);
+  private final JsHandler jsHandler = mock(JsHandler.class);
 
   private Injector injector;
   private BeanJsonConverter converter;
@@ -91,7 +94,7 @@ public class GadgetsHandlerTest extends 
   private void registerGadgetsHandler(SecurityTokenCodec codec) {
     BeanFilter beanFilter = new BeanFilter();
     GadgetsHandlerService service = new GadgetsHandlerService(timeSource, processor,
-        urlGenerator, codec, proxyUriManager, jsUriManager, proxyHandler,
+        urlGenerator, codec, proxyUriManager, jsUriManager, proxyHandler, jsHandler,
         SPEC_REFRESH_INTERVAL, beanFilter);
     GadgetsHandler handler =
         new GadgetsHandler(new TestExecutorService(), service, beanFilter);
@@ -381,6 +384,109 @@ public class GadgetsHandlerTest extends 
     verify();
   }
 
+  private JSONObject makeSimpleJsRequest(String fields, List<String> features)
+      throws JSONException {
+    JSONObject params = new JSONObject().put("gadget", GADGET1_URL)
+        .put("container", CONTAINER).put("features", features);
+    if (fields != null) {
+      params.put("fields", fields);
+    }
+    JSONObject req =
+        new JSONObject().put("method", "gadgets.js").put("id", "req1").put("params", params);
+    return req;
+  }
+
+  @Test
+  public void testJsSimple() throws Exception {
+    registerGadgetsHandler(null);
+    List<String> features = ImmutableList.of("rpc","io");
+    Uri jsUri = Uri.parse("http://shindig.com/gadgets/js/rpc:io");
+    JSONObject request = makeSimpleJsRequest(null, features);
+    Capture<JsUri> captureUri = new Capture<JsUri>();
+    EasyMock.expect(jsUriManager.makeExternJsUri(EasyMock.capture(captureUri)))
+        .andReturn(jsUri);
+    replay();
+
+    RpcHandler operation = registry.getRpcHandler(request);
+    Object responseObj = operation.execute(emptyFormItems, token, converter).get();
+    JSONObject results = new JSONObject(converter.convertToString(responseObj));
+    assertEquals(jsUri.toString(), results.getString("jsUrl"));
+    JsUri expectedUri = new JsUri(null, false, false, CONTAINER, GADGET1_URL,
+        features, null, false, RenderingContext.GADGET);
+    assertEquals(expectedUri, captureUri.getValue());
+    assertFalse(results.has("error"));
+    assertFalse(results.has("jsContent"));
+    verify();
+  }
+
+  private JSONObject makeComplexJsRequest(List<String> features, String onload)
+      throws JSONException {
+    JSONObject params = new JSONObject().put("gadget", GADGET1_URL)
+        .put("container", CONTAINER).put("features", features)
+        .put("fields", "*").put("refresh", "123").put("debug", "1")
+        .put("ignoreCache", "1").put("onload",onload)
+        .put("c", "1");
+    JSONObject request =
+        new JSONObject().put("method", "gadgets.js").put("id", "req1").put("params", params);
+    return request;
+  }
+
+  @Test
+  public void testJsData() throws Exception {
+    registerGadgetsHandler(null);
+    List<String> features = ImmutableList.of("rpc","io");
+    Uri jsUri = Uri.parse("http://shindig.com/gadgets/js/rpc:io");
+    String onload = "do \"this\";";
+
+    JSONObject request = makeComplexJsRequest(features, onload);
+
+    Capture<JsUri> captureUri = new Capture<JsUri>();
+    EasyMock.expect(jsUriManager.makeExternJsUri(EasyMock.capture(captureUri)))
+        .andReturn(jsUri);
+    String jsContent = "var b=\"123\";";
+    EasyMock.expect(jsHandler.getJsContent(
+        EasyMock.isA(JsUri.class), EasyMock.eq(jsUri.getAuthority())))
+        .andReturn(new JsHandler.Response(new StringBuilder(jsContent), true));
+    replay();
+
+    RpcHandler operation = registry.getRpcHandler(request);
+    Object responseObj = operation.execute(emptyFormItems, token, converter).get();
+    JSONObject results = new JSONObject(converter.convertToString(responseObj));
+    assertEquals(jsUri.toString(), results.getString("jsUrl"));
+    JsUri expectedUri = new JsUri(123, true, true, CONTAINER, GADGET1_URL,
+        features, onload, false, RenderingContext.CONTAINER);
+    assertEquals(expectedUri, captureUri.getValue());
+    assertFalse(results.has("error"));
+    assertEquals(jsContent, results.getString("jsContent"));
+    verify();
+  }
+
+  @Test
+  public void testJsFailure() throws Exception {
+    registerGadgetsHandler(null);
+    List<String> features = ImmutableList.of("rpc2");
+    Uri jsUri = Uri.parse("http://shindig.com/gadgets/js/rpc:io");
+    String onload = "do \"this\";";
+
+    JSONObject request = makeComplexJsRequest(features, onload);
+
+    Capture<JsUri> captureUri = new Capture<JsUri>();
+    EasyMock.expect(jsUriManager.makeExternJsUri(EasyMock.capture(captureUri)))
+        .andReturn(jsUri);
+    EasyMock.expect(jsHandler.getJsContent(
+        EasyMock.isA(JsUri.class), EasyMock.eq(jsUri.getAuthority())))
+        .andReturn(new JsHandler.Response(new StringBuilder(""), true));
+    replay();
+
+    RpcHandler operation = registry.getRpcHandler(request);
+    Object responseObj = operation.execute(emptyFormItems, token, converter).get();
+    JSONObject results = new JSONObject(converter.convertToString(responseObj));
+    assertFalse(results.has("jsUrl"));
+    assertEquals(HttpResponse.SC_NOT_FOUND, results.getJSONObject("error").getInt("code"));
+    assertTrue(results.getJSONObject("error").getString("message").contains("not found"));
+    verify();
+  }
+
   @Test
   public void testSimpleProxyData() throws Exception {
     registerGadgetsHandler(null);