You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shindig.apache.org by jo...@apache.org on 2011/03/25 00:24:41 UTC

svn commit: r1085191 - in /shindig/trunk/java/gadgets/src: main/java/org/apache/shindig/gadgets/js/ main/java/org/apache/shindig/gadgets/rewrite/js/ main/java/org/apache/shindig/gadgets/servlet/ test/java/org/apache/shindig/gadgets/js/ test/java/org/ap...

Author: johnh
Date: Thu Mar 24 23:24:40 2011
New Revision: 1085191

URL: http://svn.apache.org/viewvc?rev=1085191&view=rev
Log:
This CL removes JsHandler in favor of replacement processors:
1. GetJsContentProcessor, which formerly delegated to JsHandler. It now does
more clearly what it says: retrieves the raw JS content for the request. It
still uses the injected JsCompiler.getJsContent() to do so.
2. InjectConfigProcessor, which injects gadgets.config.init(...) calls.
3. CompilationProcessor, which actually performs compilation of JS.
4. JsWrapperProcessor, which wraps JS in an anonymous function closure (vs. the
compiler impl itself doing so).

The purpose of the CL is to move to a less-monolithic processing model, as well
as to complete the move to a situation where compiled/optimized JS is exactly
equivalent to debug JS, only compiled (no additional injection/processing).

Small bits of cleanup work remain after this CL, as it means there will no
longer be a strong reason for hard-coded JS injection (eg. JsInfo) to be obscure
in representation on input.



Added:
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/AnonFuncWrappingProcessor.java
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/CompilationProcessor.java
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/ConfigInjectionProcessor.java
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/JsGadgetContext.java
    shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/js/AnonFuncWrappingProcessorTest.java
    shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/js/CompilationProcessorTest.java
    shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/js/ConfigInjectionProcessorTest.java
Removed:
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/JsHandler.java
    shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/JsHandlerTest.java
Modified:
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/GetJsContentProcessor.java
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/JavascriptModule.java
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/JsRequestBuilder.java
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/JsResponseBuilder.java
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/js/DefaultJsCompiler.java
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/js/ExportJsCompiler.java
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/js/JsCompiler.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/js/DefaultJsProcessorRegistryTest.java
    shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/js/GetJsContentProcessorTest.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
    shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/JsServletTest.java

Added: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/AnonFuncWrappingProcessor.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/AnonFuncWrappingProcessor.java?rev=1085191&view=auto
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/AnonFuncWrappingProcessor.java (added)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/AnonFuncWrappingProcessor.java Thu Mar 24 23:24:40 2011
@@ -0,0 +1,29 @@
+/*
+ * 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.js;
+
+public class AnonFuncWrappingProcessor implements JsProcessor {
+
+  public boolean process(JsRequest jsRequest, JsResponseBuilder builder)
+      throws JsException {
+    builder.prependJs("(function() {\n", "[js-anon-wrapper]");
+    builder.appendJs("\n})();", "[js-anon-wrapper]");
+    return true;
+  }
+
+}

Added: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/CompilationProcessor.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/CompilationProcessor.java?rev=1085191&view=auto
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/CompilationProcessor.java (added)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/CompilationProcessor.java Thu Mar 24 23:24:40 2011
@@ -0,0 +1,49 @@
+/*
+ * 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.js;
+
+import java.util.List;
+
+import org.apache.shindig.gadgets.rewrite.js.JsCompiler;
+
+import com.google.common.collect.ImmutableList;
+import com.google.inject.Inject;
+
+public class CompilationProcessor implements JsProcessor {
+  private final JsCompiler compiler;
+  
+  @Inject
+  public CompilationProcessor(JsCompiler compiler) {
+    this.compiler = compiler;
+  }
+      
+  /**
+   * Compile content in the inbound JsResponseBuilder.
+   * TODO: Re-add support for externs here if they're ever used.
+   * TODO: Convert JsCompiler to take JsResponseBuilder directly rather than Iterable<JsContent>
+   */
+  public boolean process(JsRequest request, JsResponseBuilder builder)
+      throws JsException {
+    List<String> externs = ImmutableList.of();
+    JsResponse result = compiler.compile(request.getJsUri(),
+        builder.build().getAllJsContent(), externs);
+    builder.clearJs().appendAllJs(result.getAllJsContent());
+    return true;
+  }
+
+}

Added: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/ConfigInjectionProcessor.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/ConfigInjectionProcessor.java?rev=1085191&view=auto
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/ConfigInjectionProcessor.java (added)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/ConfigInjectionProcessor.java Thu Mar 24 23:24:40 2011
@@ -0,0 +1,88 @@
+/*
+ * 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.js;
+
+import java.util.Map;
+
+import org.apache.shindig.common.JsonSerializer;
+import org.apache.shindig.config.ContainerConfig;
+import org.apache.shindig.gadgets.GadgetContext;
+import org.apache.shindig.gadgets.RenderingContext;
+import org.apache.shindig.gadgets.config.ConfigContributor;
+import org.apache.shindig.gadgets.features.FeatureRegistry;
+import org.apache.shindig.gadgets.uri.JsUriManager.JsUri;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Maps;
+import com.google.inject.Inject;
+
+public class ConfigInjectionProcessor implements JsProcessor {
+  private static final String CONFIG_INIT_ID = "[config-injection]";
+  @VisibleForTesting
+  static final String GADGETS_FEATURES_KEY = "gadgets.features";
+
+  private final FeatureRegistry registry;
+  private final ContainerConfig containerConfig;
+  private final Map<String, ConfigContributor> configContributors;
+  
+  @Inject
+  public ConfigInjectionProcessor(
+      FeatureRegistry registry,
+      ContainerConfig containerConfig,
+      Map<String, ConfigContributor> configContributors) {
+    this.registry = registry;
+    this.containerConfig = containerConfig;
+    this.configContributors = configContributors;
+  }
+
+  public boolean process(JsRequest request, JsResponseBuilder builder)
+      throws JsException {
+    JsUri jsUri = request.getJsUri();
+    GadgetContext ctx = new JsGadgetContext(jsUri);
+
+    // Append gadgets.config initialization if not in standard gadget mode.
+    if (ctx.getRenderingContext() != RenderingContext.GADGET) {
+      String container = ctx.getContainer();
+
+      // Append some container specific things
+      Map<String, Object> features = containerConfig.getMap(container, GADGETS_FEATURES_KEY);
+
+      if (features != null) {
+        Map<String, Object> config =
+            Maps.newHashMapWithExpectedSize(features.size() + 2);
+        
+        // Discard what we don't care about.
+        for (String name : registry.getFeatures(jsUri.getLibs())) {
+          Object conf = features.get(name);
+          // Add from containerConfig.
+          if (conf != null) {
+            config.put(name, conf);
+          }
+          ConfigContributor contributor = configContributors.get(name);
+          if (contributor != null) {
+            contributor.contribute(config, container, request.getHost());
+          }
+        }
+        builder.appendJs(
+            "gadgets.config.init(" + JsonSerializer.serialize(config) + ");\n", CONFIG_INIT_ID);
+      }
+    }
+    return true;
+  }
+
+}

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/GetJsContentProcessor.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/GetJsContentProcessor.java?rev=1085191&r1=1085190&r2=1085191&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/GetJsContentProcessor.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/GetJsContentProcessor.java Thu Mar 24 23:24:40 2011
@@ -18,9 +18,19 @@
 
 package org.apache.shindig.gadgets.js;
 
+import java.util.Collection;
+import java.util.List;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
 import com.google.inject.Inject;
 
-import org.apache.shindig.gadgets.servlet.JsHandler;
+import org.apache.shindig.gadgets.GadgetContext;
+import org.apache.shindig.gadgets.features.FeatureRegistry;
+import org.apache.shindig.gadgets.features.FeatureResource;
+import org.apache.shindig.gadgets.http.HttpResponse;
+import org.apache.shindig.gadgets.rewrite.js.JsCompiler;
 import org.apache.shindig.gadgets.uri.JsUriManager.JsUri;
 import org.apache.shindig.gadgets.uri.UriStatus;
 
@@ -28,22 +38,60 @@ import org.apache.shindig.gadgets.uri.Ur
  * Retrieves the requested Javascript code using a {@link JsHandler}.
  */
 public class GetJsContentProcessor implements JsProcessor {
+  private static final Collection<String> EMPTY_SET = Sets.newHashSet();
+  private static final Joiner UNKNOWN_FEATURE_ERR = Joiner.on(", ");
 
-  private final JsHandler jsHandler;
+  private final FeatureRegistry registry;
+  private final JsCompiler compiler;
 
   @Inject
-  public GetJsContentProcessor(JsHandler jsHandler) {
-    this.jsHandler = jsHandler;
+  public GetJsContentProcessor(
+      FeatureRegistry registry,
+      JsCompiler compiler) {
+    this.registry = registry;
+    this.compiler = compiler;
   }
-  
+
+  /**
+   * Get the content of the feature resources and push it to jsData.
+   *
+   * @param jsUri A JsUri object that describes the resources to get.
+   * @param host The name of the host the request was directed to.
+   * @return JsHandlerResponse object that contains JavaScript data and cacheable flag.
+   */
   public boolean process(JsRequest request, JsResponseBuilder builder) throws JsException {
     // Get JavaScript content from features aliases request.
     JsUri jsUri = request.getJsUri();
-    JsResponse handlerResponse =
-        jsHandler.getJsContent(jsUri, request.getHost());
-    builder.setProxyCacheable(handlerResponse.isProxyCacheable());    
+    GadgetContext ctx = new JsGadgetContext(jsUri);
+    Collection<String> needed = jsUri.getLibs();
+
+    List<String> unsupported = Lists.newLinkedList();
+    FeatureRegistry.LookupResult lookup = registry.getFeatureResources(ctx, needed, unsupported);
+    if (!unsupported.isEmpty()) {
+      throw new JsException(HttpResponse.SC_BAD_REQUEST,
+          "Unknown feature(s): " + UNKNOWN_FEATURE_ERR.join(unsupported));
+    }
+
+    // Quick-and-dirty implementation of incremental JS loading.
+    Collection<String> alreadyLoaded = EMPTY_SET;
+    Collection<String> alreadyHaveLibs = jsUri.getLoadedLibs();
+    if (!alreadyHaveLibs.isEmpty()) {
+      alreadyLoaded = registry.getFeatures(alreadyHaveLibs);
+    }
+
+    // Collate all JS desired for the current request.
+    boolean isProxyCacheable = true;
+
+    // Pre-process each feature.
+    for (FeatureRegistry.FeatureBundle bundle : lookup.getBundles()) {
+      if (alreadyLoaded.contains(bundle.getName())) continue;
+      builder.appendAllJs(compiler.getJsContent(jsUri, bundle));
+      for (FeatureResource featureResource : bundle.getResources()) {
+        isProxyCacheable = isProxyCacheable && featureResource.isProxyCacheable();
+      }
+    }
+    builder.setProxyCacheable(isProxyCacheable);
     setResponseCacheTtl(builder, jsUri.getStatus());
-    builder.appendJs(handlerResponse.getAllJsContent());
     return true;
   }
 
@@ -70,5 +118,4 @@ public class GetJsContentProcessor imple
         break;
     }
   }
-
 }

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/JavascriptModule.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/JavascriptModule.java?rev=1085191&r1=1085190&r2=1085191&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/JavascriptModule.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/JavascriptModule.java Thu Mar 24 23:24:40 2011
@@ -34,18 +34,23 @@ public class JavascriptModule extends Ab
   protected void configure() {
     // nothing to configure here
   }
-
+  
   @Provides
   @Inject
   public List<JsProcessor> provideProcessors(
       InjectJsInfoVariableProcessor injectJsInfoVariableProcessor,
-      JsLoadProcessor jsLoaderGeneratorProcessor, IfModifiedSinceProcessor ifModifiedSinceProcessor,
+      JsLoadProcessor jsLoaderGeneratorProcessor,
+      IfModifiedSinceProcessor ifModifiedSinceProcessor,
       GetJsContentProcessor getJsContentProcessor,
+      ConfigInjectionProcessor configInjectionProcessor,
       AddOnloadFunctionProcessor addOnloadFunctionProcessor,
-      AddJsLoadCallbackProcessor addJsLoadCallbackProcessor) {
+      AddJsLoadCallbackProcessor addJsLoadCallbackProcessor,
+      //AnonFuncWrappingProcessor jsWrapperProcessor,
+      CompilationProcessor compilationProcessor) {
     return ImmutableList.of(injectJsInfoVariableProcessor, jsLoaderGeneratorProcessor,
-        ifModifiedSinceProcessor, getJsContentProcessor, addOnloadFunctionProcessor,
-        addJsLoadCallbackProcessor);
+        ifModifiedSinceProcessor, getJsContentProcessor, configInjectionProcessor,
+        addOnloadFunctionProcessor, addJsLoadCallbackProcessor, /*jsWrapperProcessor,*/
+        compilationProcessor);
   }
   
 }

Added: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/JsGadgetContext.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/JsGadgetContext.java?rev=1085191&view=auto
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/JsGadgetContext.java (added)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/JsGadgetContext.java Thu Mar 24 23:24:40 2011
@@ -0,0 +1,52 @@
+/*
+ * 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.js;
+
+import org.apache.shindig.gadgets.GadgetContext;
+import org.apache.shindig.gadgets.RenderingContext;
+import org.apache.shindig.gadgets.uri.JsUriManager.JsUri;
+
+/**
+ * GadgetContext for JsHandler called by FeatureRegistry when fetching the resources.
+ */
+public class JsGadgetContext extends GadgetContext {
+  private final RenderingContext renderingContext;
+  private final String container;
+  private final boolean debug;
+
+  public JsGadgetContext(JsUri ctx) {
+    this.renderingContext = ctx.getContext();
+    this.container = ctx.getContainer();
+    this.debug = ctx.isDebug();
+  }
+
+  @Override
+  public RenderingContext getRenderingContext() {
+    return renderingContext;
+  }
+
+  @Override
+  public String getContainer() {
+    return container;
+  }
+
+  @Override
+  public boolean getDebug() {
+    return debug;
+  }
+}
\ No newline at end of file

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/JsRequestBuilder.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/JsRequestBuilder.java?rev=1085191&r1=1085190&r2=1085191&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/JsRequestBuilder.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/JsRequestBuilder.java Thu Mar 24 23:24:40 2011
@@ -53,4 +53,13 @@ public class JsRequestBuilder {
     return new JsRequest(jsUri, host, inCache);
   }
 
+  /**
+   * Builds a {@link JsRequest} instance for a given JsUri/host pair.
+   * @param jsUri JsUri encapsulating the request.
+   * @param host Host context for the request.
+   * @return The corresponding JsRequest.
+   */
+  public JsRequest build(JsUri jsUri, String host) {
+    return new JsRequest(jsUri, host, false);
+  }
 }

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/JsResponseBuilder.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/JsResponseBuilder.java?rev=1085191&r1=1085190&r2=1085191&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/JsResponseBuilder.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/JsResponseBuilder.java Thu Mar 24 23:24:40 2011
@@ -73,7 +73,7 @@ public class JsResponseBuilder {
   /**
    * Helper to append a bunch of JS.
    */
-  public JsResponseBuilder appendJs(Iterable<JsContent> jsBundle) {
+  public JsResponseBuilder appendAllJs(Iterable<JsContent> jsBundle) {
     for (JsContent content : jsBundle) {
       appendJs(content);
     }
@@ -89,13 +89,6 @@ public class JsResponseBuilder {
   }
 
   /**
-   * Replaces the current JavaScript code with some new code.
-   */
-  public JsResponseBuilder setJs(String newContent, String name) {
-    return clearJs().appendJs(newContent, name);
-  }
-
-  /**
    * Deletes all JavaScript code in the builder.
    */
   public JsResponseBuilder clearJs() {

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/js/DefaultJsCompiler.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/js/DefaultJsCompiler.java?rev=1085191&r1=1085190&r2=1085191&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/js/DefaultJsCompiler.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/js/DefaultJsCompiler.java Thu Mar 24 23:24:40 2011
@@ -51,7 +51,7 @@ public class DefaultJsCompiler implement
   }
 
   public JsResponse compile(JsUri jsUri, Iterable<JsContent> content, List<String> externs) {
-    return new JsResponseBuilder().appendJs(content).build();
+    return new JsResponseBuilder().appendAllJs(content).build();
   }
 
   protected String getFeatureContent(JsUri jsUri, FeatureResource resource) {

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/js/ExportJsCompiler.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/js/ExportJsCompiler.java?rev=1085191&r1=1085190&r2=1085191&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/js/ExportJsCompiler.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/js/ExportJsCompiler.java Thu Mar 24 23:24:40 2011
@@ -61,6 +61,7 @@ public class ExportJsCompiler extends De
   @Override
   public Iterable<JsContent> getJsContent(JsUri jsUri, FeatureBundle bundle) {
     List<JsContent> jsContent = Lists.newLinkedList();
+    // TODO: Convert start/end to processor too.
     jsContent.add(new JsContent("\n/* [start] feature=" + bundle.getName() +
         " */\n", "[comment-marker-start]", bundle.getName()));
     for (JsContent jsc : super.getJsContent(jsUri, bundle)) {
@@ -77,7 +78,7 @@ public class ExportJsCompiler extends De
     GadgetContext ctx = new JsGadgetContext(jsUri);
     JsResponseBuilder builder = new JsResponseBuilder();
     appendExportJs(builder, ctx);
-    builder.appendJs(content);
+    builder.appendAllJs(content);
     // TODO: attach this to a real JS compiler jscomp.Compiler.
     return builder.build();
   }

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/js/JsCompiler.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/js/JsCompiler.java?rev=1085191&r1=1085190&r2=1085191&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/js/JsCompiler.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/js/JsCompiler.java Thu Mar 24 23:24:40 2011
@@ -21,6 +21,7 @@ import com.google.inject.ImplementedBy;
 
 import org.apache.shindig.gadgets.features.FeatureRegistry.FeatureBundle;
 import org.apache.shindig.gadgets.js.JsContent;
+import org.apache.shindig.gadgets.js.JsException;
 import org.apache.shindig.gadgets.js.JsResponse;
 import org.apache.shindig.gadgets.uri.JsUriManager.JsUri;
 
@@ -48,5 +49,6 @@ public interface JsCompiler {
    * @param externs The externs.
    * @return A compilation result object.
    */
-  JsResponse compile(JsUri jsUri, Iterable<JsContent> content, List<String> externs);
+  JsResponse compile(JsUri jsUri, Iterable<JsContent> content, List<String> externs)
+      throws JsException;
 }

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=1085191&r1=1085190&r2=1085191&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 Thu Mar 24 23:24:40 2011
@@ -47,7 +47,9 @@ import org.apache.shindig.gadgets.Gadget
 import org.apache.shindig.gadgets.RenderingContext;
 import org.apache.shindig.gadgets.http.HttpResponse;
 import org.apache.shindig.gadgets.js.JsException;
+import org.apache.shindig.gadgets.js.JsRequestBuilder;
 import org.apache.shindig.gadgets.js.JsResponse;
+import org.apache.shindig.gadgets.js.JsServingPipeline;
 import org.apache.shindig.gadgets.process.ProcessingException;
 import org.apache.shindig.gadgets.process.Processor;
 import org.apache.shindig.gadgets.servlet.CajaContentRewriter.CajoledResult;
@@ -122,7 +124,8 @@ public class GadgetsHandlerService {
   protected final SecurityTokenCodec securityTokenCodec;
   protected final ProxyUriManager proxyUriManager;
   protected final JsUriManager jsUriManager;
-  protected final JsHandler jsHandler;
+  protected final JsServingPipeline jsPipeline;
+  protected final JsRequestBuilder jsRequestBuilder;
   protected final ProxyHandler proxyHandler;
   protected final BeanDelegator beanDelegator;
   protected final long specRefreshInterval;
@@ -133,7 +136,7 @@ public class GadgetsHandlerService {
   public GadgetsHandlerService(TimeSource timeSource, Processor processor,
       IframeUriManager iframeUriManager, SecurityTokenCodec securityTokenCodec,
       ProxyUriManager proxyUriManager, JsUriManager jsUriManager, ProxyHandler proxyHandler,
-      JsHandler jsHandler,
+      JsServingPipeline jsPipeline, JsRequestBuilder jsRequestBuilder,
       @Named("shindig.cache.xml.refreshInterval") long specRefreshInterval,
       BeanFilter beanFilter, CajaContentRewriter cajaContentRewriter) {
     this.timeSource = timeSource;
@@ -143,7 +146,8 @@ public class GadgetsHandlerService {
     this.proxyUriManager = proxyUriManager;
     this.jsUriManager = jsUriManager;
     this.proxyHandler = proxyHandler;
-    this.jsHandler = jsHandler;
+    this.jsPipeline = jsPipeline;
+    this.jsRequestBuilder = jsRequestBuilder;
     this.specRefreshInterval = specRefreshInterval;
     this.beanFilter = beanFilter;
     this.cajaContentRewriter = cajaContentRewriter;
@@ -211,7 +215,7 @@ public class GadgetsHandlerService {
     if (isFieldIncluded(fields, "jsContent")) {
       JsResponse response = null;
       try {
-        response = jsHandler.getJsContent(jsUri, servedUri.getAuthority());
+        response = jsPipeline.execute(jsRequestBuilder.build(jsUri, servedUri.getAuthority()));
       } catch (JsException e) {
         throw new ProcessingException(e.getMessage(), e.getStatusCode());
       }

Added: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/js/AnonFuncWrappingProcessorTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/js/AnonFuncWrappingProcessorTest.java?rev=1085191&view=auto
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/js/AnonFuncWrappingProcessorTest.java (added)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/js/AnonFuncWrappingProcessorTest.java Thu Mar 24 23:24:40 2011
@@ -0,0 +1,40 @@
+/*
+ * 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.js;
+
+import static org.easymock.EasyMock.createControl;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.easymock.IMocksControl;
+
+import org.junit.Test;
+
+public class AnonFuncWrappingProcessorTest {
+  @Test
+  public void wrapCode() throws Exception {
+    IMocksControl control = createControl();
+    JsRequest request = control.createMock(JsRequest.class);
+    JsResponseBuilder builder = new JsResponseBuilder().appendJs("JS_CODE", "source");
+    AnonFuncWrappingProcessor processor = new AnonFuncWrappingProcessor();
+    control.replay();
+    assertTrue(processor.process(request, builder));
+    control.verify();
+    assertEquals("(function() {\nJS_CODE\n})();", builder.build().toJsString());
+  }
+}

Added: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/js/CompilationProcessorTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/js/CompilationProcessorTest.java?rev=1085191&view=auto
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/js/CompilationProcessorTest.java (added)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/js/CompilationProcessorTest.java Thu Mar 24 23:24:40 2011
@@ -0,0 +1,94 @@
+/*
+ * 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.js;
+
+import static org.easymock.EasyMock.createControl;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.same;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.shindig.gadgets.rewrite.js.JsCompiler;
+import org.apache.shindig.gadgets.uri.JsUriManager.JsUri;
+import org.easymock.IMocksControl;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+
+public class CompilationProcessorTest {
+  private IMocksControl control;
+  private JsCompiler compiler;
+  private CompilationProcessor processor;
+  
+  @Before
+  public void setUp() throws Exception {
+    control = createControl();
+    compiler = control.createMock(JsCompiler.class);
+    processor = new CompilationProcessor(compiler);
+  }
+  
+  @Test
+  public void compilerIsRun() throws Exception {
+    JsUri jsUri = control.createMock(JsUri.class);
+    JsResponseBuilder builder =
+        new JsResponseBuilder().setCacheTtlSecs(1234).setStatusCode(200)
+          .appendJs("content1:", "source1").appendJs("content2", "source2");
+    JsResponse outputResponse = new JsResponseBuilder().appendJs("content3", "s3").build();
+    JsRequest request = control.createMock(JsRequest.class);
+    expect(request.getJsUri()).andReturn(jsUri);
+    List<String> emptyList = ImmutableList.of();
+    expect(compiler.compile(same(jsUri), eq(builder.build().getAllJsContent()), eq(emptyList)))
+        .andReturn(outputResponse);
+    
+    control.replay();
+    boolean status = processor.process(request, builder);
+    control.verify();
+    
+    assertTrue(status);
+    JsResponse compResult = builder.build();
+    assertEquals(200, compResult.getStatusCode());
+    assertEquals(1234, compResult.getCacheTtlSecs());
+    assertEquals("content3", compResult.toJsString());
+    Iterator<JsContent> outIterator = compResult.getAllJsContent().iterator();
+    JsContent firstOut = outIterator.next();
+    assertEquals("content3", firstOut.get());
+    assertEquals("s3", firstOut.getSource());
+    assertFalse(outIterator.hasNext());
+  }
+
+  @Test(expected = JsException.class)
+  public void compilerExceptionThrows() throws Exception {
+    JsUri jsUri = control.createMock(JsUri.class);
+    JsResponseBuilder builder =
+        new JsResponseBuilder().setCacheTtlSecs(1234).setStatusCode(200)
+          .appendJs("content1:", "source1").appendJs("content2", "source2");
+    JsRequest request = control.createMock(JsRequest.class);
+    expect(request.getJsUri()).andReturn(jsUri);
+    List<String> emptyList = ImmutableList.of();
+    expect(compiler.compile(same(jsUri), eq(builder.build().getAllJsContent()), eq(emptyList)))
+        .andThrow(new JsException(400, "foo"));
+    control.replay();
+    processor.process(request, builder);
+  }
+}

Added: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/js/ConfigInjectionProcessorTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/js/ConfigInjectionProcessorTest.java?rev=1085191&view=auto
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/js/ConfigInjectionProcessorTest.java (added)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/js/ConfigInjectionProcessorTest.java Thu Mar 24 23:24:40 2011
@@ -0,0 +1,200 @@
+/*
+ * 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.js;
+
+import static org.easymock.EasyMock.capture;
+import static org.easymock.EasyMock.createControl;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.getCurrentArguments;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.shindig.config.ContainerConfig;
+import org.apache.shindig.gadgets.RenderingContext;
+import org.apache.shindig.gadgets.config.ConfigContributor;
+import org.apache.shindig.gadgets.features.FeatureRegistry;
+import org.apache.shindig.gadgets.uri.JsUriManager.JsUri;
+import org.easymock.Capture;
+import org.easymock.IAnswer;
+import org.easymock.IMocksControl;
+import org.json.JSONObject;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Maps;
+
+public class ConfigInjectionProcessorTest {
+  private static final String BASE_CODE = "code\n";
+  private static final String CONTAINER = "container";
+  private IMocksControl control;
+  private JsUri jsUri;
+  private JsRequest request;
+  private FeatureRegistry registry;
+  private ContainerConfig containerConfig;
+  private Map<String, ConfigContributor> configContributors;
+  private ConfigInjectionProcessor processor;
+  
+  @Before
+  public void setUp() throws Exception {
+    control = createControl();
+    jsUri = control.createMock(JsUri.class);
+    request = control.createMock(JsRequest.class);
+    registry = control.createMock(FeatureRegistry.class);
+    containerConfig = control.createMock(ContainerConfig.class);
+    configContributors = Maps.newHashMap();
+    processor = new ConfigInjectionProcessor(registry, containerConfig, configContributors);
+  }
+  
+  @Test
+  public void gadgetGetsNothing() throws Exception {
+    JsResponseBuilder builder = prepareRequestReturnBuilder(RenderingContext.GADGET);
+    control.replay();
+    assertTrue(processor.process(request, builder));
+    control.verify();
+    assertEquals(BASE_CODE, builder.build().toJsString());
+  }
+  
+  @Test
+  public void containerNoFeaturesDoesNothing() throws Exception {
+    checkNoFeaturesDoesNothing(RenderingContext.CONTAINER);
+  }
+  
+  @Test
+  public void configuredNoFeaturesDoesNothing() throws Exception {
+    checkNoFeaturesDoesNothing(RenderingContext.CONFIGURED_GADGET);
+  }
+  
+  private void checkNoFeaturesDoesNothing(RenderingContext ctx) throws Exception {
+    JsResponseBuilder builder = prepareRequestReturnBuilder(ctx);
+    expect(containerConfig.getMap(CONTAINER, ConfigInjectionProcessor.GADGETS_FEATURES_KEY))
+        .andReturn(null);
+    control.replay();
+    assertTrue(processor.process(request, builder));
+    control.verify();
+    assertEquals(BASE_CODE, builder.build().toJsString());
+  }
+  
+  @Test
+  public void containerNoContributorsGetsBase() throws Exception {
+    checkNoContributorsGetsBase(RenderingContext.CONTAINER);
+  }
+  
+  @Test
+  public void configuredNoContributorsGetsBase() throws Exception {
+    checkNoContributorsGetsBase(RenderingContext.CONFIGURED_GADGET);
+  }
+  
+  private void checkNoContributorsGetsBase(RenderingContext ctx) throws Exception {
+    checkInjectConfig(ctx, false);
+  }
+  
+  @Test
+  public void containerModeInjectConfig() throws Exception {
+    checkInjectConfig(RenderingContext.CONTAINER);
+  }
+  
+  @Test
+  public void configuredModeInjectConfig() throws Exception {
+    checkInjectConfig(RenderingContext.CONFIGURED_GADGET);
+  }
+  
+  private void checkInjectConfig(RenderingContext ctx) throws Exception {
+    checkInjectConfig(ctx, true);
+  }
+  
+  private void checkInjectConfig(RenderingContext ctx, boolean extraContrib) throws Exception {
+    JsResponseBuilder builder = prepareRequestReturnBuilder(ctx);
+    Map<String, Object> baseConfig = Maps.newHashMap();
+    baseConfig.put("feature1", "config1");
+    Map<String, String> f2MapConfig = Maps.newHashMap();
+    f2MapConfig.put("key1", "val1");
+    f2MapConfig.put("key2", "val2");
+    baseConfig.put("feature2", f2MapConfig);
+    baseConfig.put("feature3", "contributorListens");
+    baseConfig.put("feature4", "unused");
+    expect(containerConfig.getMap(CONTAINER, ConfigInjectionProcessor.GADGETS_FEATURES_KEY))
+        .andReturn(baseConfig);
+    ImmutableList.Builder<String> libsBuilder =
+        ImmutableList.<String>builder().add("feature1", "feature2");
+    if (extraContrib) {
+      libsBuilder.add("feature3");
+      String host = "myHost";
+      expect(request.getHost()).andReturn(host);
+      ConfigContributor cc = control.createMock(ConfigContributor.class);
+      Capture<Map<String, Object>> captureConfig = new Capture<Map<String, Object>>();
+      cc.contribute(capture(captureConfig), eq(CONTAINER), eq(host));
+      expectLastCall().andAnswer(new IAnswer<Void>() {
+        @SuppressWarnings("unchecked")
+        public Void answer() throws Throwable {
+          Map<String, Object> config = (Map<String, Object>)getCurrentArguments()[0];
+          String f3Value = (String)config.get("feature3");
+          config.put("feature3", f3Value + ":MODIFIED");
+          return null;
+        }
+      });
+      configContributors.put("feature3", cc);
+    }
+    List<String> libs = libsBuilder.build();
+    expect(jsUri.getLibs()).andReturn(libs);
+    expect(registry.getFeatures(libs)).andReturn(libs);
+    
+    control.replay();
+    assertTrue(processor.process(request, builder));
+    control.verify();
+    String jsCode = builder.build().toJsString();
+    String baseMatch = BASE_CODE + "gadgets.config.init(";
+    assertTrue(jsCode.startsWith(baseMatch));
+    String endMatch = ");\n";
+    assertTrue(jsCode.endsWith(endMatch));
+    String injectedConfig = jsCode.substring(baseMatch.length(),
+        jsCode.length() - endMatch.length());
+    
+    // Convert to JSON object to bypass ordering issues.
+    // This is bulky but works. There's probably a better way.
+    JSONObject configObj = new JSONObject(injectedConfig);
+    JSONObject expected = new JSONObject();
+    expected.put("feature1", "config1");
+    JSONObject subConfig = new JSONObject();
+    subConfig.put("key1", "val1");
+    subConfig.put("key2", "val2");
+    expected.put("feature2", subConfig);
+    if (extraContrib) {
+      expected.put("feature3", "contributorListens:MODIFIED");
+    }
+    assertEquals(expected.length(), configObj.length());
+    assertEquals(expected.get("feature1").toString(), configObj.get("feature1").toString());
+    assertEquals(expected.get("feature2").toString(), configObj.get("feature2").toString());
+    if (extraContrib) {
+      assertEquals(expected.get("feature3").toString(), configObj.get("feature3").toString());
+    }
+  }
+  
+  private JsResponseBuilder prepareRequestReturnBuilder(RenderingContext ctx) {
+    expect(jsUri.getContext()).andReturn(ctx);
+    expect(jsUri.getContainer()).andReturn(CONTAINER);
+    expect(jsUri.isDebug()).andReturn(false);
+    expect(request.getJsUri()).andReturn(jsUri);
+    return new JsResponseBuilder().appendJs(BASE_CODE, "source");
+  }
+}

Modified: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/js/DefaultJsProcessorRegistryTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/js/DefaultJsProcessorRegistryTest.java?rev=1085191&r1=1085190&r2=1085191&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/js/DefaultJsProcessorRegistryTest.java (original)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/js/DefaultJsProcessorRegistryTest.java Thu Mar 24 23:24:40 2011
@@ -56,7 +56,7 @@ public class DefaultJsProcessorRegistryT
   public void testProcessorModifiesResponse() throws Exception {
     JsProcessor processor = new JsProcessor() {
       public boolean process(JsRequest request, JsResponseBuilder builder) {
-        builder.setJs(JS_CODE, "js");
+        builder.clearJs().appendJs(JS_CODE, "js");
         return true;
       }
     };

Modified: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/js/GetJsContentProcessorTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/js/GetJsContentProcessorTest.java?rev=1085191&r1=1085190&r2=1085191&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/js/GetJsContentProcessorTest.java (original)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/js/GetJsContentProcessorTest.java Thu Mar 24 23:24:40 2011
@@ -18,44 +18,54 @@
 
 package org.apache.shindig.gadgets.js;
 
+import static org.easymock.EasyMock.createControl;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.isA;
 import static org.junit.Assert.*;
 
-import org.apache.shindig.gadgets.servlet.JsHandler;
+import java.util.List;
+
+import org.apache.shindig.gadgets.RenderingContext;
+import org.apache.shindig.gadgets.features.FeatureRegistry;
+import org.apache.shindig.gadgets.features.FeatureResource;
+import org.apache.shindig.gadgets.features.FeatureRegistry.FeatureBundle;
+import org.apache.shindig.gadgets.features.FeatureRegistry.LookupResult;
+import org.apache.shindig.gadgets.rewrite.js.JsCompiler;
 import org.apache.shindig.gadgets.uri.JsUriManager.JsUri;
 import org.apache.shindig.gadgets.uri.UriStatus;
-import org.easymock.EasyMock;
 import org.easymock.IMocksControl;
 import org.junit.Before;
 import org.junit.Test;
 
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
 
 
 /**
  * Tests for {@link GetJsContentProcessor}.
  */
 public class GetJsContentProcessorTest {
-
-  private static final String HOST = "localhost";
-  private static final String JS_CODE = "some JS data";
+  private static final String JS_CODE1 = "some JS data";
+  private static final String JS_CODE2 = "some JS data";
   
   private IMocksControl control;
-  private JsHandler handler;
+  private FeatureRegistry registry;
+  private JsCompiler compiler;
   private JsUri jsUri;
   private JsRequest request;
-  private JsResponse handlerResponse;
   private JsResponseBuilder response;
   private GetJsContentProcessor processor;
 
   @Before
   public void setUp() {
-    control = EasyMock.createControl();
-    handler = control.createMock(JsHandler.class);
+    control = createControl();
+    registry = control.createMock(FeatureRegistry.class);
+    compiler = control.createMock(JsCompiler.class);
     jsUri = control.createMock(JsUri.class);
     request = control.createMock(JsRequest.class);
-    handlerResponse = control.createMock(JsResponse.class);
     response = new JsResponseBuilder();
-    processor = new GetJsContentProcessor(handler);
+    processor = new GetJsContentProcessor(registry, compiler);
   }
   
   @Test
@@ -95,18 +105,52 @@ public class GetJsContentProcessorTest {
   }
 
   private void setExpectations(boolean proxyCacheable, UriStatus uriStatus) throws JsException {
-    EasyMock.expect(handler.getJsContent(jsUri, HOST)).andReturn(handlerResponse);
-    EasyMock.expect(request.getHost()).andReturn(HOST);
-    EasyMock.expect(request.getJsUri()).andReturn(jsUri);
-    EasyMock.expect(handlerResponse.getAllJsContent()).andReturn(
-        ImmutableList.of(new JsContent(JS_CODE, "source", "feature")));
-    EasyMock.expect(handlerResponse.isProxyCacheable()).andReturn(proxyCacheable);
-    EasyMock.expect(jsUri.getStatus()).andReturn(uriStatus);
+    expect(jsUri.getStatus()).andReturn(uriStatus);
+    List<String> libs = ImmutableList.of("feature1", "feature2");
+    expect(jsUri.getLibs()).andReturn(libs);
+    expect(jsUri.getContainer()).andReturn("container");
+    expect(jsUri.getContext()).andReturn(RenderingContext.CONFIGURED_GADGET);
+    expect(jsUri.isDebug()).andReturn(false);
+    expect(jsUri.getLoadedLibs()).andReturn(ImmutableList.<String>of());
+    expect(request.getJsUri()).andReturn(jsUri);
+    
+    List<FeatureBundle> bundles = mockBundles(proxyCacheable);
+    LookupResult lr = control.createMock(LookupResult.class);
+    expect(lr.getBundles()).andReturn(bundles);
+
+    expect(registry.getFeatureResources(isA(JsGadgetContext.class), eq(libs),
+        eq(ImmutableList.<String>of()))).andReturn(lr);
+    expect(compiler.getJsContent(jsUri, bundles.get(0)))
+        .andReturn(ImmutableList.<JsContent>of(new JsContent(JS_CODE1, "source1", "feature1")));
+    expect(compiler.getJsContent(jsUri, bundles.get(1)))
+        .andReturn(ImmutableList.<JsContent>of(new JsContent(JS_CODE2, "source2", "feature2")));
+  }
+  
+  private List<FeatureBundle> mockBundles(boolean proxyCacheable) {
+    FeatureBundle bundle1 = control.createMock(FeatureBundle.class);
+    expect(bundle1.getName()).andReturn("feature1");
+    FeatureResource resource1 = control.createMock(FeatureResource.class);
+    expect(resource1.isProxyCacheable()).andReturn(proxyCacheable);
+    List<FeatureResource> resources1 = Lists.newArrayList(resource1);
+    expect(bundle1.getResources()).andReturn(resources1);
+    
+    FeatureBundle bundle2 = control.createMock(FeatureBundle.class);
+    expect(bundle2.getName()).andReturn("feature2");
+    FeatureResource resource2 = control.createMock(FeatureResource.class);
+    if (proxyCacheable) {
+      // Only consulted if the first bundle/resource is proxyCacheable.
+      expect(resource2.isProxyCacheable()).andReturn(proxyCacheable);
+    }
+    List<FeatureResource> resources2 = Lists.newArrayList(resource2);
+    expect(bundle2.getResources()).andReturn(resources2);
+    
+    List<FeatureBundle> bundles = Lists.newArrayList(bundle1, bundle2);
+    return bundles;
   }
 
   private void checkResponse(boolean proxyCacheable, int expectedTtl) {
     assertEquals(proxyCacheable, response.isProxyCacheable());
     assertEquals(expectedTtl, response.getCacheTtlSecs());
-    assertEquals(JS_CODE, response.build().toJsString());
+    assertEquals(JS_CODE1 + JS_CODE2, response.build().toJsString());
   }
 }

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=1085191&r1=1085190&r2=1085191&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 Thu Mar 24 23:24:40 2011
@@ -40,7 +40,10 @@ import org.apache.shindig.gadgets.featur
 import org.apache.shindig.gadgets.http.HttpResponse;
 import org.apache.shindig.gadgets.http.HttpResponseBuilder;
 import org.apache.shindig.gadgets.js.JsException;
+import org.apache.shindig.gadgets.js.JsRequest;
+import org.apache.shindig.gadgets.js.JsRequestBuilder;
 import org.apache.shindig.gadgets.js.JsResponseBuilder;
+import org.apache.shindig.gadgets.js.JsServingPipeline;
 import org.apache.shindig.gadgets.process.ProcessingException;
 import org.apache.shindig.gadgets.uri.JsUriManager;
 import org.apache.shindig.gadgets.uri.ProxyUriManager;
@@ -81,7 +84,8 @@ public class GadgetsHandlerServiceTest e
   private final JsUriManager jsUriManager = mock(JsUriManager.class);
   private final ProxyHandler proxyHandler = mock(ProxyHandler.class);
   private final CajaContentRewriter cajaContentRewriter = mock(CajaContentRewriter.class);
-  private final JsHandler jsHandler = mock(JsHandler.class);
+  private final JsServingPipeline jsPipeline = mock(JsServingPipeline.class);
+  private final JsRequestBuilder jsRequestBuilder = new JsRequestBuilder(jsUriManager);
 
   private FakeSecurityTokenCodec tokenCodec;
   private GadgetsHandlerService gadgetHandler;
@@ -90,8 +94,8 @@ public class GadgetsHandlerServiceTest e
   public void setUp() {
     tokenCodec = new FakeSecurityTokenCodec();
     gadgetHandler = new GadgetsHandlerService(timeSource, processor, urlGenerator,
-        tokenCodec, proxyUriManager, jsUriManager, proxyHandler, jsHandler,
-        SPEC_REFRESH_INTERVAL_MS, new BeanFilter(), cajaContentRewriter);
+        tokenCodec, proxyUriManager, jsUriManager, proxyHandler, jsPipeline,
+        jsRequestBuilder, SPEC_REFRESH_INTERVAL_MS, new BeanFilter(), cajaContentRewriter);
   }
 
   // Next test verify that the API data classes are configured correctly.
@@ -319,7 +323,7 @@ public class GadgetsHandlerServiceTest e
     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")))
+    expect(jsPipeline.execute(EasyMock.isA(JsRequest.class)))
         .andReturn(new JsResponseBuilder().appendJs(jsContent, "js").setProxyCacheable(true).build());
     GadgetsHandlerApi.JsRequest request =
         createJsRequest(FakeProcessor.SPEC_URL.toString(), CONTAINER, fields, features);
@@ -345,7 +349,7 @@ public class GadgetsHandlerServiceTest e
     Uri resUri = Uri.parse("http://server.com/gadgets/js/foo");
     Capture<JsUri> uriCapture = new Capture<JsUri>();
     expect(jsUriManager.makeExternJsUri(capture(uriCapture))).andReturn(resUri);
-    expect(jsHandler.getJsContent(EasyMock.isA(JsUri.class), EasyMock.eq("server.com")))
+    expect(jsPipeline.execute(EasyMock.isA(JsRequest.class)))
         .andThrow(new JsException(404, "error"));
     GadgetsHandlerApi.JsRequest request =
         createJsRequest(FakeProcessor.SPEC_URL.toString(), CONTAINER, fields, features);

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=1085191&r1=1085190&r2=1085191&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 Thu Mar 24 23:24:40 2011
@@ -37,7 +37,10 @@ import org.apache.shindig.common.util.Fa
 import org.apache.shindig.gadgets.RenderingContext;
 import org.apache.shindig.gadgets.http.HttpResponse;
 import org.apache.shindig.gadgets.js.JsException;
+import org.apache.shindig.gadgets.js.JsRequest;
+import org.apache.shindig.gadgets.js.JsRequestBuilder;
 import org.apache.shindig.gadgets.js.JsResponseBuilder;
+import org.apache.shindig.gadgets.js.JsServingPipeline;
 import org.apache.shindig.gadgets.process.ProcessingException;
 import org.apache.shindig.gadgets.servlet.CajaContentRewriter.CajoledResult;
 import org.apache.shindig.gadgets.spec.GadgetSpec;
@@ -88,7 +91,8 @@ public class GadgetsHandlerTest extends 
   private final JsUriManager jsUriManager = mock(JsUriManager.class);
   private final ProxyHandler proxyHandler = mock(ProxyHandler.class);
   private final CajaContentRewriter cajaContentRewriter = mock(CajaContentRewriter.class);
-  private final JsHandler jsHandler = mock(JsHandler.class);
+  private final JsServingPipeline jsPipeline = mock(JsServingPipeline.class);
+  private final JsRequestBuilder jsRequestBuilder = new JsRequestBuilder(jsUriManager);
 
   private Injector injector;
   private BeanJsonConverter converter;
@@ -106,8 +110,8 @@ public class GadgetsHandlerTest extends 
   private void registerGadgetsHandler(SecurityTokenCodec codec) {
     BeanFilter beanFilter = new BeanFilter();
     GadgetsHandlerService service = new GadgetsHandlerService(timeSource, processor,
-        urlGenerator, codec, proxyUriManager, jsUriManager, proxyHandler, jsHandler,
-        SPEC_REFRESH_INTERVAL, beanFilter, cajaContentRewriter);
+        urlGenerator, codec, proxyUriManager, jsUriManager, proxyHandler, jsPipeline,
+        jsRequestBuilder, SPEC_REFRESH_INTERVAL, beanFilter, cajaContentRewriter);
     GadgetsHandler handler =
         new GadgetsHandler(new ImmediateExecutorService(), service, beanFilter);
     registry = new DefaultHandlerRegistry(
@@ -599,8 +603,7 @@ public class GadgetsHandlerTest extends 
     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())))
+    EasyMock.expect(jsPipeline.execute(EasyMock.isA(JsRequest.class)))
         .andReturn(new JsResponseBuilder().appendJs(jsContent, "js").build());
     replay();
 
@@ -629,8 +632,7 @@ public class GadgetsHandlerTest extends 
     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())))
+    EasyMock.expect(jsPipeline.execute(EasyMock.isA(JsRequest.class)))
         .andThrow(new JsException(404, "not found"));
     replay();
 

Modified: 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=1085191&r1=1085190&r2=1085191&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/JsServletTest.java (original)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/JsServletTest.java Thu Mar 24 23:24:40 2011
@@ -19,6 +19,7 @@
 package org.apache.shindig.gadgets.servlet;
 
 import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.getCurrentArguments;
 import static org.easymock.EasyMock.isA;
 
 import com.google.caja.util.Lists;
@@ -35,12 +36,14 @@ import org.apache.shindig.gadgets.js.IfM
 import org.apache.shindig.gadgets.js.JsLoadProcessor;
 import org.apache.shindig.gadgets.js.JsProcessor;
 import org.apache.shindig.gadgets.js.JsProcessorRegistry;
+import org.apache.shindig.gadgets.js.JsRequest;
 import org.apache.shindig.gadgets.js.JsRequestBuilder;
 import org.apache.shindig.gadgets.js.JsResponse;
 import org.apache.shindig.gadgets.js.JsResponseBuilder;
 import org.apache.shindig.gadgets.uri.JsUriManager;
 import org.apache.shindig.gadgets.uri.JsUriManager.JsUri;
 import org.apache.shindig.gadgets.uri.UriStatus;
+import org.easymock.IAnswer;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -55,7 +58,7 @@ public class JsServletTest extends Servl
 
   private final JsServlet servlet = new JsServlet();
   private JsServlet.CachingSetter httpUtilMock;
-  private JsHandler jsHandlerMock;
+  private GetJsContentProcessor getJsProcessorMock;
   private JsUriManager jsUriManagerMock;
   private JsLoadProcessor jsLoadProcessor;
   private DefaultJsServingPipeline jsServingPipeline;
@@ -68,13 +71,13 @@ public class JsServletTest extends Servl
     jsUriManagerMock = mock(JsUriManager.class);
     servlet.setJsRequestBuilder(new JsRequestBuilder(jsUriManagerMock));
 
-    jsHandlerMock = mock(JsHandler.class);
+    getJsProcessorMock = mock(GetJsContentProcessor.class);
     
     jsLoadProcessor = new JsLoadProcessor(jsUriManagerMock, 0);
     JsProcessorRegistry jsProcessorRegistry =
         new DefaultJsProcessorRegistry(
             ImmutableList.<JsProcessor>of(jsLoadProcessor, new IfModifiedSinceProcessor(),
-                new GetJsContentProcessor(jsHandlerMock), new AddOnloadFunctionProcessor()));
+               getJsProcessorMock, new AddOnloadFunctionProcessor()));
 
     jsServingPipeline = new DefaultJsServingPipeline(jsProcessorRegistry);
     servlet.setJsServingPipeline(jsServingPipeline);
@@ -134,9 +137,16 @@ public class JsServletTest extends Servl
         null, REFRESH_INTERVAL_SEC, UriStatus.VALID_UNVERSIONED);
     expect(jsUriManagerMock.processExternJsUri(isA(Uri.class))).andReturn(jsUri);
     expect(request.getHeader("If-Modified-Since")).andReturn("12345");
-    JsResponse response = new JsResponseBuilder().appendJs(EXAMPLE_JS_CODE, "js").build();
+    final JsResponse response = new JsResponseBuilder().appendJs(EXAMPLE_JS_CODE, "js").build();
     expect(request.getHeader("Host")).andReturn("localhost");
-    expect(jsHandlerMock.getJsContent(jsUri, "localhost")).andReturn(response);
+    expect(getJsProcessorMock.process(isA(JsRequest.class), isA(JsResponseBuilder.class))).andAnswer(
+        new IAnswer<Boolean>() {
+          public Boolean answer() throws Throwable {
+            JsResponseBuilder builder = (JsResponseBuilder)getCurrentArguments()[1];
+            builder.appendAllJs(response.getAllJsContent());
+            return true;
+          }
+        });
     replay();
 
     servlet.doGet(request, recorder);