You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shindig.apache.org by mh...@apache.org on 2011/03/29 04:10:01 UTC

svn commit: r1086466 - in /shindig/trunk/java/gadgets/src: main/java/org/apache/shindig/gadgets/features/ main/java/org/apache/shindig/gadgets/js/ main/java/org/apache/shindig/gadgets/rewrite/js/ main/java16/org/apache/shindig/gadgets/rewrite/js/ test/...

Author: mhermanto
Date: Tue Mar 29 02:10:01 2011
New Revision: 1086466

URL: http://svn.apache.org/viewvc?rev=1086466&view=rev
Log:
Filter-out to-be-marked-cajole FeatureBundle.
http://codereview.appspot.com/4316046/

Added:
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/CajoleJsSubtractingProcessor.java
    shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/js/CajoleJsSubtractingProcessorTest.java
Modified:
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/features/BrowserSpecificFeatureResource.java
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/features/FeatureRegistry.java
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/features/FeatureResource.java
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/features/FeatureResourceLoader.java
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/JsContent.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/java16/org/apache/shindig/gadgets/rewrite/js/ClosureJsCompiler.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/rewrite/js/DefaultJsCompilerTest.java
    shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/js/ExportJsCompilerTest.java

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/features/BrowserSpecificFeatureResource.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/features/BrowserSpecificFeatureResource.java?rev=1086466&r1=1086465&r2=1086466&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/features/BrowserSpecificFeatureResource.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/features/BrowserSpecificFeatureResource.java Tue Mar 29 02:10:01 2011
@@ -100,6 +100,10 @@ public class BrowserSpecificFeatureResou
     return delegate.getName();
   }
   
+  public Map<String, String> getAttribs() {
+    return delegate.getAttribs();
+  }
+
   private boolean browserMatches() {
     if (browserMatch.isEmpty()) {
       // Not browser-sensitive.

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/features/FeatureRegistry.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/features/FeatureRegistry.java?rev=1086466&r1=1086465&r2=1086466&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/features/FeatureRegistry.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/features/FeatureRegistry.java Tue Mar 29 02:10:01 2011
@@ -466,7 +466,9 @@ public class FeatureRegistry {
       List<FeatureResource> resources = Lists.newArrayList();
       for (FeatureParser.ParsedFeature.Resource parsedResource : parsedBundle.getResources()) {
         if (parsedResource.getSource() == null) {
-          resources.add(new InlineFeatureResource(parsed.getName() + ":inline.js", parsedResource.getContent()));
+          
+          resources.add(new InlineFeatureResource(parsed.getName() + ":inline.js",
+              parsedResource.getContent(), parsedResource.getAttribs()));
         } else {
           // Load using resourceLoader
           resources.add(resourceLoader.load(parsedResource.getSource(),
@@ -500,11 +502,12 @@ public class FeatureRegistry {
         .putAll(resourceAttribs).build();
   }
 
-  private static final class InlineFeatureResource extends FeatureResource.Default {
+  private static final class InlineFeatureResource extends FeatureResource.Attribute {
     private final String name;
     private final String content;
 
-    private InlineFeatureResource(String name, String content) {
+    private InlineFeatureResource(String name, String content, Map<String, String> attribs) {
+      super(attribs);
       this.content = content;
       this.name = name;
     }

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/features/FeatureResource.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/features/FeatureResource.java?rev=1086466&r1=1086465&r2=1086466&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/features/FeatureResource.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/features/FeatureResource.java Tue Mar 29 02:10:01 2011
@@ -17,6 +17,10 @@
  */
 package org.apache.shindig.gadgets.features;
 
+import com.google.common.collect.ImmutableMap;
+
+import java.util.Map;
+
 /**
  * Interface yielding content/code for JS features.
  */
@@ -47,6 +51,11 @@ public interface FeatureResource {
   String getName();
   
   /**
+   * @return XML-defined attributes associated with this for resource selection/inclusion.
+   */
+  Map<String, String> getAttribs();
+  
+  /**
    * Helper base class to avoid having to implement rarely-overridden isExternal/isProxyCacheable
    * functionality in FeatureResource.
    */
@@ -58,6 +67,23 @@ public interface FeatureResource {
     public boolean isProxyCacheable() {
       return true;
     }
+    
+    public Map<String, String> getAttribs() {
+      return ImmutableMap.<String, String>of();
+    }
+  }
+  
+  public abstract class Attribute extends Default {
+    private final Map<String, String> attribs;
+
+    public Attribute(Map<String, String> attribs) {
+      this.attribs = attribs;
+    }
+
+    @Override
+    public Map<String, String> getAttribs() {
+      return attribs;
+    }
   }
   
   public class Simple extends Default {    
@@ -70,7 +96,7 @@ public interface FeatureResource {
       this.debugContent = debugContent;
       this.name = name;
     }
-    
+
     public String getContent() {
       return content;
     }

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/features/FeatureResourceLoader.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/features/FeatureResourceLoader.java?rev=1086466&r1=1086465&r2=1086466&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/features/FeatureResourceLoader.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/features/FeatureResourceLoader.java Tue Mar 29 02:10:01 2011
@@ -94,7 +94,7 @@ public class FeatureResourceLoader {
   }
   
   protected FeatureResource loadFile(String path, Map<String, String> attribs) throws IOException {
-    return new DualModeFileResource(getOptPath(path), path);
+    return new DualModeFileResource(getOptPath(path), path, attribs);
   }
   
   protected String getFileContent(File file) {
@@ -119,7 +119,7 @@ public class FeatureResourceLoader {
     } catch (IOException e) {
       // See above; OK for debugContent to be null.
     }
-    return new DualModeStaticResource(path, optContent, debugContent);
+    return new DualModeStaticResource(path, optContent, debugContent, attribs);
   }
   
   public String getResourceContent(String resource) throws IOException {
@@ -129,7 +129,9 @@ public class FeatureResourceLoader {
   protected FeatureResource loadUri(Uri uri, Map<String, String> attribs) {
     String inline = attribs.get("inline");
     inline = inline != null ? inline : "";
-    return new UriResource(fetcher, uri, "1".equals(inline) || "true".equalsIgnoreCase(inline));
+    return new UriResource(fetcher, uri,
+        "1".equals(inline) || "true".equalsIgnoreCase(inline),
+        attribs);
   }
   
   protected String getOptPath(String orig) {
@@ -144,12 +146,14 @@ public class FeatureResourceLoader {
     return file.lastModified() > lastModified;
   }
   
-  private class DualModeFileResource extends FeatureResource.Default {
+  private class DualModeFileResource extends FeatureResource.Attribute {
     private final FileContent optContent;
     private final FileContent dbgContent;
     private final String fileName;
     
-    protected DualModeFileResource(String optFilePath, String dbgFilePath) {
+    protected DualModeFileResource(String optFilePath, String dbgFilePath,
+        Map<String, String> attribs) {
+      super(attribs);
       this.optContent = new FileContent(optFilePath);
       this.dbgContent = new FileContent(dbgFilePath);
       this.fileName = dbgFilePath;
@@ -213,12 +217,13 @@ public class FeatureResourceLoader {
     }
   }
   
-  private static final class DualModeStaticResource extends FeatureResource.Default {
+  private static final class DualModeStaticResource extends FeatureResource.Attribute {
     private final String content;
     private final String debugContent;
     private final String path;
     
-    private DualModeStaticResource(String path, String content, String debugContent) {
+    private DualModeStaticResource(String path, String content, String debugContent, Map<String, String> attribs) {
+      super(attribs);
       this.content = content != null ? content : debugContent;
       this.debugContent = debugContent != null ? debugContent : content;
       this.path = path;
@@ -238,14 +243,16 @@ public class FeatureResourceLoader {
     }
   }
   
-  private static final class UriResource implements FeatureResource {
+  private static final class UriResource extends FeatureResource.Attribute {
     private final HttpFetcher fetcher;
     private final Uri uri;
     private final boolean isInline;
     private String content;
     private long lastLoadTryMs;
     
-    private UriResource(HttpFetcher fetcher, Uri uri, boolean isInline) {
+    private UriResource(HttpFetcher fetcher, Uri uri, boolean isInline,
+        Map<String, String> attribs) {
+      super(attribs);
       this.fetcher = fetcher;
       this.uri = uri;
       this.isInline = isInline;
@@ -293,10 +300,12 @@ public class FeatureResourceLoader {
       return getContent();
     }
 
+    @Override
     public boolean isExternal() {
       return !isInline;
     }
-    
+
+    @Override
     public boolean isProxyCacheable() {
       return content != null;
     }
@@ -304,5 +313,6 @@ public class FeatureResourceLoader {
     public String getName() {
       return uri.toString();
     }
+
   }
 }

Added: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/CajoleJsSubtractingProcessor.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/CajoleJsSubtractingProcessor.java?rev=1086466&view=auto
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/CajoleJsSubtractingProcessor.java (added)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/CajoleJsSubtractingProcessor.java Tue Mar 29 02:10:01 2011
@@ -0,0 +1,62 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+
+package org.apache.shindig.gadgets.js;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableList;
+
+import org.apache.shindig.gadgets.features.FeatureRegistry.FeatureBundle;
+import org.apache.shindig.gadgets.features.FeatureResource;
+
+import java.util.Map;
+
+/*
+ * 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.
+ */
+public class CajoleJsSubtractingProcessor implements JsProcessor {
+
+  @VisibleForTesting
+  static final String CAJOLE_ATTRIB_KEY = "cajole";
+
+  @VisibleForTesting
+  static final String CAJOLE_ATTRIB_VALUE = "1";
+
+  public boolean process(JsRequest jsRequest, JsResponseBuilder builder) {
+    if (!jsRequest.getJsUri().cajoleContent()) {
+      ImmutableList.Builder<JsContent> listBuilder = ImmutableList.builder();
+      for (JsContent js : builder.build().getAllJsContent()) {
+        if (!isCajole(js)) {
+          listBuilder.add(js);
+        }
+      }
+      builder.clearJs().appendAllJs(listBuilder.build());
+    }
+    return true;
+  }
+
+  private boolean isCajole(JsContent js) {
+    FeatureResource resource = js.getFeatureResource();
+    if (resource != null) {
+      Map<String, String> attribs = resource.getAttribs();
+      if (attribs != null) {
+        String attrib = attribs.get(CAJOLE_ATTRIB_KEY);
+        return CAJOLE_ATTRIB_VALUE.equals(attrib);
+      }
+    }
+    return false;
+  }
+}

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/JsContent.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/JsContent.java?rev=1086466&r1=1086465&r2=1086466&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/JsContent.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/js/JsContent.java Tue Mar 29 02:10:01 2011
@@ -17,6 +17,8 @@
  */
 package org.apache.shindig.gadgets.js;
 
+import org.apache.shindig.gadgets.features.FeatureResource;
+
 /**
  * Wrapper around JavaScript providing a way to track its provenance.
  * Other metadata may be added as well, such as annotations regarding compilation,
@@ -26,26 +28,39 @@ public class JsContent {
   private final String content;
   private final String source;
   private final String feature;
-  
-  public JsContent(String content, String source) {
-    this(content, source, "[builtin]");
+  private final FeatureResource resource;
+
+  public static JsContent fromText(String content, String source) {
+    return new JsContent(content, source, "[built-in]", null);
+  }
+
+  // TODO: Consider replacing String feature with FeatureBundle.
+  public static JsContent fromFeature(String content, String source, String feature,
+      FeatureResource resource) {
+    return new JsContent(content, source, feature, resource);
   }
   
-  public JsContent(String content, String source, String feature) {
+  private JsContent(String content, String source, String feature,
+      FeatureResource resource) {
     this.content = content;
     this.source = source;
     this.feature = feature;
+    this.resource = resource;
   }
-  
+
   public String get() {
     return content;
   }
-  
+
   public String getSource() {
     return source;
   }
-  
+
   public String getFeature() {
     return feature;
   }
+  
+  public FeatureResource getFeatureResource() {
+    return resource;
+  }
 }

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=1086466&r1=1086465&r2=1086466&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 Tue Mar 29 02:10:01 2011
@@ -67,7 +67,7 @@ public class JsResponseBuilder {
    * Helper to append JS to the response w/ a name.
    */
   public JsResponseBuilder appendJs(String content, String name) {
-    return appendJs(new JsContent(content, name));
+    return appendJs(JsContent.fromText(content, name));
   }
 
   /**
@@ -84,7 +84,7 @@ public class JsResponseBuilder {
    * Prepends JS to the output.
    */
   public JsResponseBuilder prependJs(String content, String name) {
-    jsCode.addFirst(new JsContent(content, name));
+    jsCode.addFirst(JsContent.fromText(content, name));
     return this;
   }
 

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=1086466&r1=1086465&r2=1086466&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 Tue Mar 29 02:10:01 2011
@@ -24,6 +24,7 @@ import org.apache.shindig.gadgets.js.JsR
 import org.apache.shindig.gadgets.js.JsResponseBuilder;
 import org.apache.shindig.gadgets.uri.JsUriManager.JsUri;
 
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Lists;
 
 import java.util.List;
@@ -40,12 +41,14 @@ public class DefaultJsCompiler implement
       content = (content != null) ? content : "";
       if (resource.isExternal()) {
         // Support external/type=url feature serving through document.write()
-        jsContent.add(new JsContent("document.write('<script src=\"" + content + "\"></script>')",
-            "[external:" + content + "]", bundle.getName()));
+        jsContent.add(JsContent.fromFeature("document.write('<script src=\"" + content + "\"></script>')",
+            "[external:" + content + "]", bundle.getName(), resource));
       } else {
-        jsContent.add(new JsContent(content, resource.getName(), bundle.getName()));
+        jsContent.add(JsContent.fromFeature(content, resource.getName(), bundle.getName(),
+            resource));
       }
-      jsContent.add(new JsContent(";\n", "[separator]", bundle.getName()));
+      jsContent.add(JsContent.fromFeature(";\n", "[separator]", bundle.getName(),
+          resource));
     }
     return jsContent;
   }

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=1086466&r1=1086465&r2=1086466&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 Tue Mar 29 02:10:01 2011
@@ -62,14 +62,14 @@ public class ExportJsCompiler extends De
   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()));
+    jsContent.add(JsContent.fromFeature("\n/* [start] feature=" + bundle.getName() +
+        " */\n", "[comment-marker-start]", bundle.getName(), null));
     for (JsContent jsc : super.getJsContent(jsUri, bundle)) {
       jsContent.add(jsc);
     }
     jsContent.add(getExportsForFeature(jsUri, bundle));
-    jsContent.add(new JsContent("\n/* [end] feature=" + bundle.getName() +
-        " */\n", "[comment-marker-end]", bundle.getName()));
+    jsContent.add(JsContent.fromFeature("\n/* [end] feature=" + bundle.getName() +
+        " */\n", "[comment-marker-end]", bundle.getName(), null));
     return jsContent;
   }
 
@@ -101,8 +101,9 @@ public class ExportJsCompiler extends De
     for (Input input : generateInputs(exports)) {
       sb.append(input.toExportStatement());
     }
-    
-    return new JsContent(sb.toString(), "[generated-symbol-exports]", bundle.getName());
+
+    return JsContent.fromFeature(sb.toString(), "[generated-symbol-exports]",
+        bundle.getName(), null);
   }
 
   private void appendExportJs(JsResponseBuilder builder, GadgetContext context) {
@@ -110,8 +111,9 @@ public class ExportJsCompiler extends De
         ImmutableList.of(FEATURE_NAME), null);
     for (FeatureBundle bundle : lookup.getBundles()) {
       for (FeatureResource resource : bundle.getResources()) {
-        builder.appendJs(new JsContent(
-            resource.getDebugContent(), resource.getName(), bundle.getName()));
+        builder.appendJs(JsContent.fromFeature(
+            resource.getDebugContent(), resource.getName(),
+            bundle.getName(), null));
       }
     }
   }

Modified: shindig/trunk/java/gadgets/src/main/java16/org/apache/shindig/gadgets/rewrite/js/ClosureJsCompiler.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java16/org/apache/shindig/gadgets/rewrite/js/ClosureJsCompiler.java?rev=1086466&r1=1086465&r2=1086466&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java16/org/apache/shindig/gadgets/rewrite/js/ClosureJsCompiler.java (original)
+++ shindig/trunk/java/gadgets/src/main/java16/org/apache/shindig/gadgets/rewrite/js/ClosureJsCompiler.java Tue Mar 29 02:10:01 2011
@@ -62,7 +62,7 @@ import java.util.Map;
 public class ClosureJsCompiler implements JsCompiler {
   // Based on Closure Library's goog.exportSymbol implementation.
   private static final JsContent EXPORTSYMBOL_CODE =
-      new JsContent("var goog=goog||{};goog.exportSymbol=function(name,obj){"
+      JsContent.fromText("var goog=goog||{};goog.exportSymbol=function(name,obj){"
               + "var parts=name.split('.'),cur=window,part;"
               + "for(;parts.length&&(part=parts.shift());){if(!parts.length){"
               + "cur[part]=obj;}else{cur=cur[part]||(cur[part]={})}}};", "[goog.exportSymbol]");
@@ -251,7 +251,8 @@ public class ClosureJsCompiler implement
       String prevExport = null;
       for (String export : exports) {
         if (!export.equals(prevExport)) {
-          builder.add(new JsContent("goog.exportSymbol('" + StringEscapeUtils.escapeJavaScript(export) +
+          builder.add(JsContent.fromText(
+              "goog.exportSymbol('" + StringEscapeUtils.escapeJavaScript(export) +
               "', " + export + ");\n", "[export-symbol]"));
           prevExport = export;
         }
@@ -336,16 +337,16 @@ public class ClosureJsCompiler implement
           codePos++;
           if (nextMapping != curMapping && curMapping != -1) {
             JsContent sourceJs = orig.get(getRootSrc(mappings[curMapping]));
-            compiledOut.add(new JsContent(compiled.substring(codeStart, codePos),
-                sourceJs.getSource(), sourceJs.getFeature()));
+            compiledOut.add(JsContent.fromFeature(compiled.substring(codeStart, codePos),
+                sourceJs.getSource(), sourceJs.getFeature(), null));
             codeStart = codePos;
           }
           curMapping = nextMapping;
         }
       }
       JsContent lastSource = orig.get(getRootSrc(mappings[curMapping]));
-      compiledOut.add(new JsContent(compiled.substring(codeStart, codePos + 1),
-          lastSource.getSource(), lastSource.getFeature()));
+      compiledOut.add(JsContent.fromFeature(compiled.substring(codeStart, codePos + 1),
+          lastSource.getSource(), lastSource.getFeature(), null));
       return compiledOut;
     }
     

Added: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/js/CajoleJsSubtractingProcessorTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/js/CajoleJsSubtractingProcessorTest.java?rev=1086466&view=auto
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/js/CajoleJsSubtractingProcessorTest.java (added)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/js/CajoleJsSubtractingProcessorTest.java Tue Mar 29 02:10:01 2011
@@ -0,0 +1,122 @@
+/*
+ * 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.apache.shindig.gadgets.js.CajoleJsSubtractingProcessor.CAJOLE_ATTRIB_KEY;
+import static org.apache.shindig.gadgets.js.CajoleJsSubtractingProcessor.CAJOLE_ATTRIB_VALUE;
+import static org.easymock.EasyMock.createControl;
+import static org.easymock.EasyMock.expect;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+
+import org.apache.shindig.gadgets.features.FeatureRegistry.FeatureBundle;
+import org.apache.shindig.gadgets.features.FeatureResource;
+import org.apache.shindig.gadgets.uri.JsUriManager.JsUri;
+import org.easymock.IMocksControl;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.List;
+import java.util.Map;
+
+public class CajoleJsSubtractingProcessorTest {
+
+  private static final List<String> ERRORS = ImmutableList.<String>of();
+
+  private static final String NORMAL_CONTENT_JS = "normal";
+  private static final String CAJOLE_CONTENT_JS = "cajole";
+
+  private IMocksControl control;
+  private List<JsContent> contents = Lists.newArrayList();
+  private JsResponse response;
+  private JsResponseBuilder builder;
+  
+  private CajoleJsSubtractingProcessor processor;
+
+  @Before
+  public void setUp() {
+    control = createControl();
+
+    contents = Lists.newArrayList();
+    contents.add(JsContent.fromFeature(NORMAL_CONTENT_JS, null, null, null));
+    contents.add(JsContent.fromFeature(NORMAL_CONTENT_JS, null, null,
+        mockFeatureResource(null)));
+    contents.add(JsContent.fromFeature(NORMAL_CONTENT_JS, null, null,
+        mockFeatureResource(ImmutableMap.of(CAJOLE_ATTRIB_KEY, "blah"))));
+    contents.add(JsContent.fromFeature(CAJOLE_CONTENT_JS, null, "feature",
+        mockFeatureResource(ImmutableMap.of(CAJOLE_ATTRIB_KEY, CAJOLE_ATTRIB_VALUE))));
+    
+    response = new JsResponse(contents, -1, -1, false, ERRORS, null);
+    builder = new JsResponseBuilder(response);
+    
+    processor = new CajoleJsSubtractingProcessor();
+  }
+
+  @Test
+  @SuppressWarnings("unchecked")
+  public void noCajoleRequest() throws Exception {
+    JsUri uri = mockJsUri(false);
+    JsRequest request = mockJsRequest(uri);
+
+    control.replay();
+    boolean actualReturn = processor.process(request, builder);
+    JsResponse actualResponse = builder.build();
+
+    control.verify();
+    assertTrue(actualReturn);
+    assertEquals(Strings.repeat(NORMAL_CONTENT_JS, 3), actualResponse.toJsString());
+  }
+
+  @Test
+  public void cajoleRequest() throws Exception {
+    JsUri uri = mockJsUri(true);
+    JsRequest request = mockJsRequest(uri);
+
+    control.replay();
+    boolean actualReturn = processor.process(request, builder);
+    JsResponse actualResponse = builder.build();
+
+    control.verify();
+    assertTrue(actualReturn);
+    assertEquals(Strings.repeat(NORMAL_CONTENT_JS, 3) + CAJOLE_CONTENT_JS,
+        actualResponse.toJsString());
+  }
+
+  private FeatureResource mockFeatureResource(Map<String, String> map) {
+    FeatureResource result = control.createMock(FeatureResource.class);
+    expect(result.getAttribs()).andReturn(map).anyTimes();
+    return result;
+  }
+
+  private JsUri mockJsUri(boolean cajole) {
+    JsUri uri = control.createMock(JsUri.class);
+    expect(uri.cajoleContent()).andReturn(cajole).anyTimes();
+    return uri;
+  }
+
+  private JsRequest mockJsRequest(JsUri uri) {
+    JsRequest request = control.createMock(JsRequest.class);
+    expect(request.getJsUri()).andReturn(uri).anyTimes();
+    return request;
+  }
+}

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=1086466&r1=1086465&r2=1086466&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 Tue Mar 29 02:10:01 2011
@@ -48,7 +48,7 @@ import com.google.common.collect.Lists;
 public class GetJsContentProcessorTest {
   private static final String JS_CODE1 = "some JS data";
   private static final String JS_CODE2 = "some JS data";
-  
+
   private IMocksControl control;
   private FeatureRegistry registry;
   private JsCompiler compiler;
@@ -67,7 +67,7 @@ public class GetJsContentProcessorTest {
     response = new JsResponseBuilder();
     processor = new GetJsContentProcessor(registry, compiler);
   }
-  
+
   @Test
   public void testPopulatesResponseForUnversionedRequest() throws Exception {
     setExpectations(true, UriStatus.VALID_UNVERSIONED);
@@ -113,7 +113,7 @@ public class GetJsContentProcessorTest {
     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);
@@ -121,11 +121,13 @@ public class GetJsContentProcessorTest {
     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")));
+        .andReturn(ImmutableList.<JsContent>of(
+            JsContent.fromFeature(JS_CODE1, "source1", "feature1", null)));
     expect(compiler.getJsContent(jsUri, bundles.get(1)))
-        .andReturn(ImmutableList.<JsContent>of(new JsContent(JS_CODE2, "source2", "feature2")));
+        .andReturn(ImmutableList.<JsContent>of(
+            JsContent.fromFeature(JS_CODE2, "source2", "feature2", null)));
   }
-  
+
   private List<FeatureBundle> mockBundles(boolean proxyCacheable) {
     FeatureBundle bundle1 = control.createMock(FeatureBundle.class);
     expect(bundle1.getName()).andReturn("feature1");
@@ -133,7 +135,7 @@ public class GetJsContentProcessorTest {
     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);
@@ -143,9 +145,8 @@ public class GetJsContentProcessorTest {
     }
     List<FeatureResource> resources2 = Lists.newArrayList(resource2);
     expect(bundle2.getResources()).andReturn(resources2);
-    
-    List<FeatureBundle> bundles = Lists.newArrayList(bundle1, bundle2);
-    return bundles;
+
+    return Lists.newArrayList(bundle1, bundle2);
   }
 
   private void checkResponse(boolean proxyCacheable, int expectedTtl) {

Modified: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/js/DefaultJsCompilerTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/js/DefaultJsCompilerTest.java?rev=1086466&r1=1086465&r2=1086466&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/js/DefaultJsCompilerTest.java (original)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/js/DefaultJsCompilerTest.java Tue Mar 29 02:10:01 2011
@@ -79,7 +79,7 @@ public class DefaultJsCompilerTest {
   @Test
   public void testCompile() throws Exception {
     JsResponse actual = compiler.compile(null, 
-        ImmutableList.of(new JsContent(COMPILE_CONTENT, "js")), null);
+        ImmutableList.of(JsContent.fromText(COMPILE_CONTENT, "js")), null);
     assertEquals(COMPILE_CONTENT, actual.toJsString());
     assertEquals(0, actual.getErrors().size());
   }

Modified: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/js/ExportJsCompilerTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/js/ExportJsCompilerTest.java?rev=1086466&r1=1086465&r2=1086466&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/js/ExportJsCompilerTest.java (original)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/js/ExportJsCompilerTest.java Tue Mar 29 02:10:01 2011
@@ -176,7 +176,7 @@ public class ExportJsCompilerTest {
     JsUri jsUri = mockJsUri(JsCompileMode.ALL_RUN_TIME);
 
     JsResponse actual = compiler.compile(jsUri,
-        ImmutableList.of(new JsContent(COMPILE_CONTENT, "js")), EXTERNS);
+        ImmutableList.of(JsContent.fromText(COMPILE_CONTENT, "js")), EXTERNS);
     assertEquals(EXPORT_JS_DEB + COMPILE_CONTENT, actual.toJsString());
   }
 
@@ -184,7 +184,7 @@ public class ExportJsCompilerTest {
   public void testCompileEmpty() throws Exception {
     JsUri jsUri = mockJsUri(JsCompileMode.ALL_RUN_TIME);
     JsResponse actual = compiler.compile(jsUri,
-        ImmutableList.of(new JsContent("", "js")), EXTERNS);
+        ImmutableList.of(JsContent.fromText("", "js")), EXTERNS);
     assertEquals(EXPORT_JS_DEB, actual.toJsString());
   }