Author: awiner
Date: Mon Jun 15 23:10:48 2009
New Revision: 785020

URL: http://svn.apache.org/viewvc?rev=785020&view=rev
Log:
Support multiple feature values per param
- Gadget Features are now a Multimap.  Feature.getParam() aids in existing 
get-a-single-param cases
- Templates now support multiple template libraries per gadget
- The content rewriting feature has *not* been updated to be 0.9 compliant, but 
that's now possible

Modified:
    
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/parse/nekohtml/NekoSimplifiedHtmlParser.java
    
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriter.java
    
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ContentRewriterFeature.java
    
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/TemplateRewriter.java
    
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/Feature.java
    
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriterTest.java
    
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/spec/FeatureTest.java

Modified: 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/parse/nekohtml/NekoSimplifiedHtmlParser.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/parse/nekohtml/NekoSimplifiedHtmlParser.java?rev=785020&r1=785019&r2=785020&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/parse/nekohtml/NekoSimplifiedHtmlParser.java
 (original)
+++ 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/parse/nekohtml/NekoSimplifiedHtmlParser.java
 Mon Jun 15 23:10:48 2009
@@ -33,7 +33,6 @@
 import org.apache.xerces.xni.parser.XMLDocumentSource;
 import org.apache.xerces.xni.parser.XMLInputSource;
 import org.cyberneko.html.HTMLConfiguration;
-import org.cyberneko.html.HTMLElements;
 import org.cyberneko.html.HTMLEntities;
 import org.cyberneko.html.HTMLScanner;
 import org.cyberneko.html.HTMLTagBalancer;

Modified: 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriter.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriter.java?rev=785020&r1=785019&r2=785020&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriter.java
 (original)
+++ 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriter.java
 Mon Jun 15 23:10:48 2009
@@ -397,9 +397,22 @@
     // Add gadgets.util support. This is calculated dynamically based on 
request inputs.
     ModulePrefs prefs = gadget.getSpec().getModulePrefs();
     Collection<Feature> features = prefs.getFeatures().values();
-    Map<String, Map<String, String>> featureMap = 
Maps.newHashMapWithExpectedSize(features.size());
+    Map<String, Map<String, Object>> featureMap = 
Maps.newHashMapWithExpectedSize(features.size());
     for (Feature feature : features) {
-      featureMap.put(feature.getName(), feature.getParams());
+      
+      // Flatten out the multimap a bit for backwards compatibility:  map keys
+      // with just 1 value into the string, treat others as arrays
+      Map<String, Object> paramFeaturesInConfig = Maps.newHashMap();
+      for (String paramName : feature.getParams().keySet()) {
+        Collection<String> paramValues = feature.getParams().get(paramName);
+        if (paramValues.size() == 1) {
+          paramFeaturesInConfig.put(paramName, paramValues.iterator().next());
+        } else {
+          paramFeaturesInConfig.put(paramName, paramValues);
+        }
+      }
+      
+      featureMap.put(feature.getName(), paramFeaturesInConfig);
     }
     config.put("core.util", featureMap);
   }

Modified: 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ContentRewriterFeature.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ContentRewriterFeature.java?rev=785020&r1=785019&r2=785020&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ContentRewriterFeature.java
 (original)
+++ 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ContentRewriterFeature.java
 Mon Jun 15 23:10:48 2009
@@ -84,15 +84,15 @@
     List<String> expiresOptions = Lists.newArrayListWithCapacity(3);
     if (f != null) {
       if (f.getParams().containsKey(INCLUDE_URLS)) {
-        includeRegex = normalizeParam(f.getParams().get(INCLUDE_URLS), 
includeRegex);
+        includeRegex = normalizeParam(f.getParam(INCLUDE_URLS), includeRegex);
       }
 
       // Note use of default for exclude as null here to allow clearing value 
in the
       // presence of a container default.
       if (f.getParams().containsKey(EXCLUDE_URLS)) {
-        excludeRegex = normalizeParam(f.getParams().get(EXCLUDE_URLS), null);
+        excludeRegex = normalizeParam(f.getParam(EXCLUDE_URLS), null);
       }
-      String includeTagList = f.getParams().get(INCLUDE_TAGS);
+      String includeTagList = f.getParam(INCLUDE_TAGS);
       if (includeTagList != null) {
         Set<String> tags = Sets.newTreeSet();
         for (String tag : includeTagList.split(",")) {
@@ -104,7 +104,7 @@
       }
 
       if (f.getParams().containsKey(EXPIRES)) {
-        expiresOptions.add(normalizeParam(f.getParams().get(EXPIRES), null));
+        expiresOptions.add(normalizeParam(f.getParam(EXPIRES), null));
       }
     }
 

Modified: 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/TemplateRewriter.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/TemplateRewriter.java?rev=785020&r1=785019&r2=785020&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/TemplateRewriter.java
 (original)
+++ 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/TemplateRewriter.java
 Mon Jun 15 23:10:48 2009
@@ -52,6 +52,7 @@
 import org.w3c.dom.Node;
 
 import java.io.IOException;
+import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -82,13 +83,13 @@
   public final static Set<String> TAGS = ImmutableSet.of("script");
 
   /** Set to true to block auto-processing of templates */
-  static final Object DISABLE_AUTO_PROCESSING_PARAM = "disableAutoProcessing";
+  static final String DISABLE_AUTO_PROCESSING_PARAM = "disableAutoProcessing";
   
   /** Specifies what template libraries to load */
-  static final Object REQUIRE_LIBRARY_PARAM = "requireLibrary";
+  static final String REQUIRE_LIBRARY_PARAM = "requireLibrary";
   
   /** Enable client support? **/
-  static final Object CLIENT_SUPPORT_PARAM = "client";  
+  static final String CLIENT_SUPPORT_PARAM = "client";  
 
   static private final Logger logger = 
Logger.getLogger(TemplateRewriter.class.getName());
   
@@ -171,7 +172,7 @@
    * </pre>
    */
   private boolean isServerTemplatingEnabled(Feature f) {
-    return 
(!"true".equalsIgnoreCase(f.getParams().get(DISABLE_AUTO_PROCESSING_PARAM)));
+    return 
(!"true".equalsIgnoreCase(f.getParam(DISABLE_AUTO_PROCESSING_PARAM)));
   }
 
   private void rewriteImpl(Gadget gadget, Feature f, MutableContent content)
@@ -211,7 +212,7 @@
 
     // Check if a feature param overrides  our guess at whether the 
client-side    
     // feature is needed.                                                  
-    String clientOverride = f.getParams().get(CLIENT_SUPPORT_PARAM);           
 
+    String clientOverride = f.getParam(CLIENT_SUPPORT_PARAM);            
     if ("true".equalsIgnoreCase(clientOverride)) {                             
 
       needsFeature = true;                                                     
 
     } else if ("false".equalsIgnoreCase(clientOverride)) {                     
 
@@ -264,19 +265,20 @@
 
   private void loadTemplateLibraries(GadgetContext context,
       Feature f, List<TagRegistry> registries, List<TemplateLibrary> 
libraries)  throws GadgetException {
-    // TODO: Support multiple values when Shindig does
-    String url = f.getParams().get(REQUIRE_LIBRARY_PARAM);
-    if (url != null) {
-      Uri uri = Uri.parse(url.trim());
-      uri = context.getUrl().resolve(uri);
-      
-      try {
-        TemplateLibrary library = libraryFactory.loadTemplateLibrary(context, 
uri);
-        registries.add(library.getTagRegistry());
-        libraries.add(library);
-      } catch (TemplateParserException te) {
-        // Suppress exceptions due to malformed template libraries
-        logger.log(Level.WARNING, null, te);
+    Collection<String> urls = f.getParams().get(REQUIRE_LIBRARY_PARAM); 
+    if (urls != null) {
+      for (String url : urls) {
+        Uri uri = Uri.parse(url.trim());
+        uri = context.getUrl().resolve(uri);
+        
+        try {
+          TemplateLibrary library = 
libraryFactory.loadTemplateLibrary(context, uri);
+          registries.add(library.getTagRegistry());
+          libraries.add(library);
+        } catch (TemplateParserException te) {
+          // Suppress exceptions due to malformed template libraries
+          logger.log(Level.WARNING, null, te);
+        }
       }
     }
   }

Modified: 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/Feature.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/Feature.java?rev=785020&r1=785019&r2=785020&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/Feature.java
 (original)
+++ 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/Feature.java
 Mon Jun 15 23:10:48 2009
@@ -17,16 +17,16 @@
  */
 package org.apache.shindig.gadgets.spec;
 
-import com.google.common.collect.ImmutableMap;
-
 import org.apache.shindig.common.xml.XmlUtil;
-
 import org.w3c.dom.Element;
 import org.w3c.dom.NodeList;
 
-import java.util.Collections;
+import java.util.Collection;
 import java.util.Map;
 
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.Multimap;
+
 /**
  * Represents a Require or Optional tag.
  * No substitutions on any fields.
@@ -48,10 +48,23 @@
    * Flattened into a map where pa...@name is the key and Param content is
    * the value.
    */
-  private final Map<String, String> params;
-  public Map<String, String> getParams() {
+  private final Multimap<String, String> params;
+  public Multimap<String, String> getParams() {
     return params;
   }
+  
+  /**
+   * Returns the first value for any feature parameter, or null
+   * if the parameter does not exist.
+   */
+  public String getParam(String key) {
+    Collection<String> values = params.get(key);
+    if (values == null || values.isEmpty()) {
+      return null;
+    }
+    
+    return values.iterator().next();
+  }
 
   /**
    * Whether this is a Require or an Optional feature.
@@ -71,7 +84,7 @@
        .append(" feature=\"")
        .append(name)
        .append("\">");
-    for (Map.Entry<String, String> entry : params.entrySet()) {
+    for (Map.Entry<String, Collection<String>> entry : 
params.asMap().entrySet()) {
       buf.append("\n<Param name=\"")
          .append(entry.getKey())
          .append("\">")
@@ -98,7 +111,7 @@
     this.name = name;
     NodeList children = feature.getElementsByTagName("Param");
     if (children.getLength() > 0) {
-      ImmutableMap.Builder<String, String> params = ImmutableMap.builder();
+      ImmutableMultimap.Builder<String, String> params = 
ImmutableMultimap.builder();
 
       for (int i = 0, j = children.getLength(); i < j; ++i) {
         Element param = (Element)children.item(i);
@@ -110,7 +123,7 @@
       }
       this.params = params.build();
     } else {
-      this.params = Collections.emptyMap();
+      this.params = ImmutableMultimap.of();
     }
   }
 }

Modified: 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriterTest.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriterTest.java?rev=785020&r1=785019&r2=785020&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriterTest.java
 (original)
+++ 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriterTest.java
 Mon Jun 15 23:10:48 2009
@@ -25,6 +25,7 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
+import org.apache.shindig.common.JsonAssert;
 import org.apache.shindig.common.PropertiesModule;
 import org.apache.shindig.common.uri.Uri;
 import org.apache.shindig.common.xml.XmlUtil;
@@ -497,6 +498,10 @@
       "  <Require feature='foo'>" +
       "    <Param name='bar'>baz</Param>" +
       "  </Require>" +
+      "  <Require feature='foo2'>" +
+      "    <Param name='bar'>baz</Param>" +
+      "    <Param name='bar'>bop</Param>" +
+      "  </Require>" +
       "</ModulePrefs>" +
       "<Content type='html'/>" +
       "</Module>";
@@ -504,6 +509,7 @@
     Gadget gadget = makeGadgetWithSpec(gadgetXml);
 
     featureRegistry.addInline("foo", "");
+    featureRegistry.addInline("foo2", "");
     config.data.put(FEATURES_KEY, ImmutableMap.of("foo", "blah"));
 
     String rewritten = rewrite(gadget, "");
@@ -514,6 +520,9 @@
     JSONObject util = json.getJSONObject("core.util");
     JSONObject foo = util.getJSONObject("foo");
     assertEquals("baz", foo.get("bar"));
+    JSONObject foo2 = util.getJSONObject("foo2");
+    JsonAssert.assertObjectEquals(ImmutableList.of("baz", "bop"),
+        foo2.get("bar"));
   }
 
   // TODO: Test for auth token stuff.

Modified: 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/spec/FeatureTest.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/spec/FeatureTest.java?rev=785020&r1=785019&r2=785020&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/spec/FeatureTest.java
 (original)
+++ 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/spec/FeatureTest.java
 Mon Jun 15 23:10:48 2009
@@ -23,7 +23,8 @@
 
 import junit.framework.TestCase;
 
-import java.util.Map;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Multimap;
 
 public class FeatureTest extends TestCase {
   public void testRequire() throws Exception {
@@ -47,9 +48,33 @@
                  "  <Param name=\"" + key + "\">" + value + "</Param>" +
                  "</Require>";
     Feature feature = new Feature(XmlUtil.parse(xml));
-    Map<String, String> params = feature.getParams();
+    Multimap<String, String> params = feature.getParams();
     assertEquals(1, params.size());
-    assertEquals(value, params.get(key));
+    assertEquals(ImmutableList.of(value), params.get(key));
+  }
+
+  public void testMultiParams() throws Exception {
+    String key = "bar";
+    String key2 = "bar2";
+    String value = "Hello, World!";
+    String value2 = "Goodbye, World!";
+    // Verify that multiple parameters are supported, and are returned in-order
+    String xml = "<Require feature=\"foo\">" +
+                 "  <Param name=\"" + key + "\">" + value + "</Param>" +
+                 "  <Param name=\"" + key + "\">" + value2 + "</Param>" +
+                 "  <Param name=\"" + key2 + "\">" + value2 + "</Param>" +
+                 "  <Param name=\"" + key2 + "\">" + value + "</Param>" +
+                 "</Require>";
+    Feature feature = new Feature(XmlUtil.parse(xml));
+    Multimap<String, String> params = feature.getParams();
+    assertEquals(2, params.keySet().size());
+    assertEquals(ImmutableList.of(value, value2), params.get(key));
+    assertEquals(value, feature.getParam(key));
+    assertEquals(ImmutableList.of(value2, value), params.get(key2));
+    assertEquals(value2, feature.getParam(key2));
+    
+    assertEquals(ImmutableList.of(), params.get("foobar"));
+    assertNull(feature.getParam("foobar"));
   }
 
   public void testDoesNotLikeUnnamedFeatures() throws Exception {


Reply via email to