Ziv,

Sorry meant to send the patch.  Would really like to get feedback on what
the original design intention/implementation plan was for feature params.

What is your proto buffer api doing?  Are you looking to allow features to
extend the spec through feature params?

--Andrew

On Fri, Jan 28, 2011 at 8:37 PM, Ziv Horesh <[email protected]> wrote:

> Yes, the parameter were not implemented in GadgetHandler because we didn't
> need them at that point, and we would add them when needed.
> I am curious to see your patch to support multimap (I will need figure out
> a
> way to support in my proto buffer api that inherit this).
>
>
>
> On Fri, Jan 28, 2011 at 2:19 PM, Matthew G Marum <[email protected]>
> wrote:
>
> >  Hi Andrew,
> >
> > I've been looking around that part of the code lately as I was working on
> > View level features (http://codereview.appspot.com/4077043/). I haven't
> > dug into your patch yet, but I think it will probably affect you.
> >
> > I don't know if not implementing it in the gadget metadata service is a
> bug
> > necessarily, it's possible that nobody needed it until now. For example,
> > Locales aren't exposed by this service either. Remember, there is a JS
> API
> > for gadgets needing to access feature parameters that is part of the Core
> > Gadget spec called "gadgets.util.getFeatureParameters()".
> >
> >
> >
> http://opensocial-resources.googlecode.com/svn/spec/1.1/Core-Gadget.xml#gadgets.util.getFeatureParameters
> >
> > Matt Marum
> >
> > [image: Inactive hide details for Andrew Davis ---01/28/2011 03:14:25
> > PM---We have been looking at using feature params in the current]Andrew
> > Davis ---01/28/2011 03:14:25 PM---We have been looking at using feature
> > params in the current implementation of shindig.
> >
> >
> > From:
> > Andrew Davis <[email protected]>
> > To:
> > [email protected]
> > Cc:
> > [email protected]
> > Date:
> > 01/28/2011 03:14 PM
> > Subject:
> > Feature Param support in Gadgets meta-data requests, Features support
> > extensible XML contributions?
> > ------------------------------
> >
> >
> >
> > We have been looking at using feature params in the current
> > implementation of shindig.
> > Currently we have a patch(attatched) that fixes the  GadgetHandlerAPI
> > to return feature params, and fixing BeanConverter to support
> > MultiMap.
> > For a feature declaration like this:
> > <Optional feature="open-search">
> >      <Param name="search-atom">
> > http://www.intertwingly.net/blog/index.atom?q={searchTerms}</Param>
> > </Optional>
> > The meta date request returns this(with our patch)
> >
> > "features":{"open-search":{"params":{"search-atom":["
> > http://www.intertwingly.net/blog/index.atom?q=
> > {searchTerms}"]},"name":"open-search","required":false}
> >
> > Basically any thing inside the <Param> can be returned as in the meta
> > data request
> >
> > So this may be a spec question, but given where the implementation is
> > today, first wanted to check on shindig dev what the intention of
> > feature params are.
> >
> > Conceptually has anyone considered a generic mechanism to allow
> > features to contribute arbitrary XML, and easily integrate existing
> > standards? In this example open search description.
> >
> > <Optional feature="open-search">
> >      <Param name="description">
> >          <OpenSearchDescription xmlns="
> > http://a9.com/-/spec/opensearch/1.1/";>
> >             <ShortName>Web Search</ShortName>
> >             <Description>Use Example.com to search the Web.</Description>
> >             <Tags>example web</Tags>
> >             <Contact>[email protected]</Contact>
> >             <Url type="application/rss+xml"
> > template="http://example.com/?q=
> > {searchTerms}&amp;pw={startPage?}&amp;format=rss"/>
> >
> >           </OpenSearchDescription>
> > </Param>
> > </Optional>
> >
> > We can with our patch, escape the XML of course like this:
> >
> > <Param name="action3"><![CDATA]></Param>
> >
> >
> > and the XML will be returned as a string in the gadget meta-data
> > request, but then we have XML on the client/container page to parse.
> >
> > Has anyone considered leveraging metadata request to transform
> > arbitrary XML into corresponding JSON?
> >
> > Was not implementing feature params just a bug or done specifically
> > for performance reasons?  MetaData request parsing extremely large
> > feature contributed XML could increase load on the server, but would
> > be a clean extensible mechanism for features to extend the
> > specification within the schema and allow the container to access
> > those extensions as JSON.
> >
> > Thoughts?
> >
> > --Andrew Davis
> >
> >
> >
>
### Eclipse Workspace Patch 1.0
#P shindig-common
Index: src/main/java/org/apache/shindig/protocol/conversion/BeanDelegator.java
===================================================================
--- src/main/java/org/apache/shindig/protocol/conversion/BeanDelegator.java     
(revision 3472)
+++ src/main/java/org/apache/shindig/protocol/conversion/BeanDelegator.java     
(working copy)
@@ -21,8 +21,10 @@
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMultimap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Maps;
+import com.google.common.collect.Multimap;
 
 import org.apache.shindig.common.uri.Uri;
 
@@ -160,6 +162,21 @@
       }
     }
 
+    // Proxy each item in a map (map key is not proxied)
+    if (source instanceof Multimap<?, ?>) {
+      Multimap<?, ?> mapSource = (Multimap<?, ?>) source;
+      if (!mapSource.isEmpty() && delegatedClasses.containsKey(
+          mapSource.values().iterator().next().getClass())) {
+        // Convert Map:
+        ImmutableMultimap.Builder<Object, Object> mapBuilder = 
ImmutableMultimap.builder();
+        for (Map.Entry<?, ?> entry : mapSource.entries()) {
+          mapBuilder.put(entry.getKey(), createDelegator(entry.getValue(), 
apiInterface));
+        }
+        return (T) mapBuilder.build();
+      } else {
+        return (T) source;
+      }
+    }
     // Proxy each item in a list
     if (source instanceof List<?>) {
       List<?> listSource = (List<?>) source;
@@ -249,6 +266,8 @@
         type = paramType.getActualTypeArguments()[0];
       } else if (Map.class.isAssignableFrom((Class<?>) 
paramType.getRawType())) {
         type = paramType.getActualTypeArguments()[1];
+      } else if (Multimap.class.isAssignableFrom((Class<?>) 
paramType.getRawType())) {
+        type = paramType.getActualTypeArguments()[1];
       }
     }
     return (Class<?>) type;
@@ -312,6 +331,18 @@
         interfaceType = interfaceParamType.getActualTypeArguments()[1];
         return validateTypes(dataType, interfaceType);
       }
+      
+      if (Multimap.class.isAssignableFrom((Class<?>) 
dataParamType.getRawType()) &&
+              Multimap.class.isAssignableFrom((Class<?>) 
interfaceParamType.getRawType())) {
+            Type dataKeyType = dataParamType.getActualTypeArguments()[0];
+            Type interfaceKeyType = 
interfaceParamType.getActualTypeArguments()[0];
+            if (dataKeyType != interfaceKeyType || 
!PRIMITIVE_TYPE_CLASSES.contains(dataKeyType)) {
+              return false;
+            }
+            dataType = dataParamType.getActualTypeArguments()[1];
+            interfaceType = interfaceParamType.getActualTypeArguments()[1];
+            return validateTypes(dataType, interfaceType);
+          }
       // Only support Map and List generics
       return false;
     }
#P shindig-gadgets
         
Index: src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerApi.java
===================================================================
--- src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerApi.java     
(revision 3472)
+++ src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerApi.java     
(working copy)
@@ -20,6 +20,8 @@
 
 import org.apache.shindig.common.uri.Uri;
 import org.apache.shindig.protocol.conversion.BeanFilter.Unfiltered;
+
+import com.google.common.collect.Multimap;
 // Keep imports clean, so it is clear what is used by API
 
 import java.util.List;
@@ -164,7 +166,7 @@
     public String getName();
     public boolean getRequired();
     // TODO: Handle multi map if params are needed
-    // public Multimap<String, String> getParams();
+  public Multimap<String, String> getParams();
   }
 
   public interface LinkSpec {

Reply via email to