Author: johnh
Date: Fri Feb 25 23:17:55 2011
New Revision: 1074745

URL: http://svn.apache.org/viewvc?rev=1074745&view=rev
Log:
Support <all> tag in feature.xml files.

Files themselves simplified once PHP version is committed.


Modified:
    
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/RenderingContext.java
    
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/features/FeatureRegistry.java
    
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/features/FeatureRegistryTest.java

Modified: 
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/RenderingContext.java
URL: 
http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/RenderingContext.java?rev=1074745&r1=1074744&r2=1074745&view=diff
==============================================================================
--- 
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/RenderingContext.java
 (original)
+++ 
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/RenderingContext.java
 Fri Feb 25 23:17:55 2011
@@ -37,7 +37,13 @@ public enum RenderingContext {
   // Used when retrieving metadata about a gadget. Processing is generally
   // identical to processing under GADGET, but some operations may be safely
   // skipped, such as preload processing.
-  METADATA(null, null, null);
+  METADATA(null, null, null),
+  
+  // Allows specification of feature JS with an <all> tag. Specially handled in
+  // FeatureRegistry: content specified in an <all> tag is chosen if there are
+  // no <gadget> or <container> sections. This avoids, for many libs where the 
JS
+  // is equivalent, copying sections all over the place.
+  ALL("all", "3", true);
 
   private final String featureBundleTag;
   private final String paramValue;

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=1074745&r1=1074744&r2=1074745&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
 Fri Feb 25 23:17:55 2011
@@ -38,12 +38,14 @@ import org.apache.shindig.common.uri.Uri
 import org.apache.shindig.common.util.ResourceLoader;
 import org.apache.shindig.gadgets.GadgetContext;
 import org.apache.shindig.gadgets.GadgetException;
+import org.apache.shindig.gadgets.RenderingContext;
 
 import java.io.File;
 import java.io.IOException;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
@@ -207,25 +209,22 @@ public class FeatureRegistry {
         getTransitiveDeps(needed, unsupported) : getRequestedNodes(needed, 
unsupported);
 
 
-    String targetBundleType = ctx.getRenderingContext().getFeatureBundleTag();
     ImmutableList.Builder<FeatureBundle> bundlesBuilder =
         new ImmutableList.Builder<FeatureBundle>();
 
     for (FeatureNode entry : featureNodes) {
       boolean specificContainerMatched = false;
       List<FeatureBundle> noContainerBundles = Lists.newLinkedList();
-      for (FeatureBundle bundle : entry.getBundles()) {
-        if (bundle.getType().equals(targetBundleType)) {
-          String containerAttrib = bundle.getAttribs().get("container");
-          if (containerAttrib != null) {
-            if (containerMatch(containerAttrib, ctx.getContainer())) {
-              bundlesBuilder.add(bundle);
-              specificContainerMatched = true;
-            }
-          } else {
-            // Applies only if there were no specific container matches.
-            noContainerBundles.add(bundle);
+      for (FeatureBundle bundle : entry.getBundles(ctx.getRenderingContext())) 
{
+        String containerAttrib = bundle.getAttribs().get("container");
+        if (containerAttrib != null) {
+          if (containerMatch(containerAttrib, ctx.getContainer())) {
+            bundlesBuilder.add(bundle);
+            specificContainerMatched = true;
           }
+        } else {
+          // Applies only if there were no specific container matches.
+          noContainerBundles.add(bundle);
         }
       }
       if (!specificContainerMatched) {
@@ -588,8 +587,57 @@ public class FeatureRegistry {
       this.calculatedDepsStale = false;
     }
 
-    public List<FeatureBundle> getBundles() {
-      return bundles;
+    /**
+     * Returns all bundles matching the given rendering context.
+     * If there's >= 1 bundle matching a non-ALL context, return it.
+     * Otherwise, return any ALL bundles.
+     * @param rctx
+     * @return
+     */
+    public Iterable<FeatureBundle> getBundles(RenderingContext rctx) {
+      String tagMatch = null;
+      String directTag = rctx.getFeatureBundleTag();
+      for (FeatureBundle bundle : bundles) {
+        if (directTag.equalsIgnoreCase(bundle.getType())) {
+          tagMatch = directTag;
+        }
+      }
+      if (tagMatch == null) {
+        tagMatch = RenderingContext.ALL.getFeatureBundleTag();
+      }
+      final String useForMatching = tagMatch;
+      
+      // Return an Iterator rather than coping a new
+      // list containing the types over which to iterate.
+      return new Iterable<FeatureBundle>() {
+        public Iterator<FeatureBundle> iterator() {
+          return new Iterator<FeatureBundle>() {
+            private FeatureBundle next;
+            private Iterator<FeatureBundle> it = bundles.iterator();
+            
+            public boolean hasNext() {
+              while (next == null && it.hasNext()) {
+                FeatureBundle candidate = it.next();
+                if (useForMatching.equalsIgnoreCase(candidate.getType())) {
+                  next = candidate;
+                }
+              }
+              return next != null;
+            }
+
+            public FeatureBundle next() {
+              hasNext();
+              FeatureBundle ret = next;
+              next = null;
+              return ret;
+            }
+
+            public void remove() {
+              throw new UnsupportedOperationException("Can't remove from 
bundle iterator");
+            }
+          };
+        }
+      };
     }
 
     public List<String> getRawDeps() {

Modified: 
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/features/FeatureRegistryTest.java
URL: 
http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/features/FeatureRegistryTest.java?rev=1074745&r1=1074744&r2=1074745&view=diff
==============================================================================
--- 
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/features/FeatureRegistryTest.java
 (original)
+++ 
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/features/FeatureRegistryTest.java
 Fri Feb 25 23:17:55 2011
@@ -611,6 +611,57 @@ public class FeatureRegistryTest {
     assertEquals("attrib-three", lastAttribs.get("three"));
   }
   
+  @Test
+  public void testGetGadgetFromMixedRegistry() throws Exception {
+    setupMixedFullRegistry();
+
+    GadgetContext ctx = getCtx(RenderingContext.GADGET, null);
+    List<String> needed = Lists.newArrayList("top");
+    List<String> unsupported = Lists.newLinkedList();
+    
+    List<FeatureResource> resources = registry.getFeatureResources(ctx, 
needed, unsupported).getResources();
+    
+    assertEquals(4, resources.size());
+    assertEquals("bottom();all();", resources.get(0).getContent());
+    assertEquals("mid_b();gadget();", resources.get(1).getContent());
+    assertEquals("mid_a();all();", resources.get(2).getContent());
+    assertEquals("top();gadget();", resources.get(3).getContent());
+  }
+  
+  @Test
+  public void testGetContainerFromMixedRegistry() throws Exception {
+    setupMixedFullRegistry();
+
+    GadgetContext ctx = getCtx(RenderingContext.CONTAINER, null);
+    List<String> needed = Lists.newArrayList("top");
+    List<String> unsupported = Lists.newLinkedList();
+    
+    List<FeatureResource> resources = registry.getFeatureResources(ctx, 
needed, unsupported).getResources();
+    
+    assertEquals(4, resources.size());
+    assertEquals("bottom();all();", resources.get(0).getContent());
+    assertEquals("mid_b();container();", resources.get(1).getContent());
+    assertEquals("mid_a();container();", resources.get(2).getContent());
+    assertEquals("top();all();", resources.get(3).getContent());
+  }
+  
+  @Test
+  public void testGetConfiguredGadgetFromMixedRegistry() throws Exception {
+    setupMixedFullRegistry();
+
+    GadgetContext ctx = getCtx(RenderingContext.CONFIGURED_GADGET, null);
+    List<String> needed = Lists.newArrayList("top");
+    List<String> unsupported = Lists.newLinkedList();
+    
+    List<FeatureResource> resources = registry.getFeatureResources(ctx, 
needed, unsupported).getResources();
+    
+    assertEquals(4, resources.size());
+    assertEquals("bottom();all();", resources.get(0).getContent());
+    assertEquals("mid_b();gadget();", resources.get(1).getContent());
+    assertEquals("mid_a();all();", resources.get(2).getContent());
+    assertEquals("top();gadget();", resources.get(3).getContent());
+  }
+  
   private GadgetContext getCtx(final RenderingContext rctx, final String 
container) {
     return getCtx(rctx, container, false);
   }
@@ -635,6 +686,64 @@ public class FeatureRegistryTest {
     };
   }
   
+  private void setupMixedFullRegistry() throws Exception {
+    // Sets up a "full" gadget feature registry with several features 
registered in linear
+    // dependency order: top -> mid_a -> mid_b -> bottom
+    // The content registered for each is equal to the feature's name, for 
simplicity.
+    // Also, all content is loaded as inline, also for simplicity.
+    TestFeatureRegistry.Builder builder = TestFeatureRegistry.newBuilder();
+    
+    Uri topUri = builder.expectResource(
+      "<feature>" +
+        "<name>top</name>" +
+        "<dependency>mid_a</dependency>" +
+        "<dependency>mid_b</dependency>" +
+        "<gadget>" +
+        "  <script>top();gadget();</script>" +
+        "</gadget>" +
+        "<all>" +
+        "  <script>top();all();</script>" +
+        "</all>" +
+      "</feature>"
+    );
+    Uri midAUri = builder.expectResource(
+      "<feature>" +
+        "<name>mid_a</name>" +
+        "<dependency>mid_b</dependency>" +
+        "<container>" +
+        "  <script>mid_a();container();</script>" +
+        "</container>" +
+        "<all>" +
+        "  <script>mid_a();all();</script>" +
+        "</all>" +
+      "</feature>"
+    );
+    Uri midBUri = builder.expectResource(
+      "<feature>" +
+        "<name>mid_b</name>" +
+        "<dependency>bottom</dependency>" +
+        "<container>" +
+        "  <script>mid_b();container();</script>" +
+        "</container>" +
+        "<gadget>" +
+        "  <script>mid_b();gadget();</script>" +
+        "</gadget>" +
+      "</feature>"
+    );
+    Uri bottomUri = builder.expectResource(
+        "<feature>" +
+          "<name>bottom</name>" +
+          "<all>" +
+          "  <script>bottom();all();</script>" +
+          "</all>" +
+        "</feature>"
+      );
+    Uri txtFile = builder.expectResource(topUri.toString() + '\n' +
+        midAUri.toString() + '\n' + midBUri.toString() + '\n' + 
bottomUri.toString(), ".txt");
+    
+    registry = builder.build(txtFile.toString());
+  }
+  
   private void setupFullRegistry(String type, String containers) throws 
Exception {
     // Sets up a "full" gadget feature registry with several features 
registered:
     // nodep - has no deps on anything else


Reply via email to