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 2010/07/14 20:31:25 UTC

svn commit: r964125 - in /shindig/trunk/java: common/src/main/java/org/apache/shindig/common/ gadgets/src/main/java/org/apache/shindig/gadgets/ gadgets/src/main/java/org/apache/shindig/gadgets/render/ gadgets/src/main/java/org/apache/shindig/gadgets/se...

Author: johnh
Date: Wed Jul 14 18:31:24 2010
New Revision: 964125

URL: http://svn.apache.org/viewvc?rev=964125&view=rev
Log:
JSON-RPC Gadgets Handler

Implemented by Paul Lindner; committing to get the ball rolling and set the stage for further cleanups and enhancements.


Added:
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandler.java
    shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/FakeIframeUriManager.java
    shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/FakeProcessor.java
    shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerTest.java
Modified:
    shindig/trunk/java/common/src/main/java/org/apache/shindig/common/JsonSerializer.java
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/DefaultGuiceModule.java
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriter.java
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/JsonRpcHandler.java
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/GadgetSpec.java
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/DefaultIframeUriManager.java
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/variables/UserPrefSubstituter.java
    shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/HttpRequestHandlerTest.java
    shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/JsonRpcHandlerTest.java
    shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/spec/GadgetSpecTest.java
    shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/uri/UriManagerTestBase.java

Modified: shindig/trunk/java/common/src/main/java/org/apache/shindig/common/JsonSerializer.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/JsonSerializer.java?rev=964125&r1=964124&r2=964125&view=diff
==============================================================================
--- shindig/trunk/java/common/src/main/java/org/apache/shindig/common/JsonSerializer.java (original)
+++ shindig/trunk/java/common/src/main/java/org/apache/shindig/common/JsonSerializer.java Wed Jul 14 18:31:24 2010
@@ -19,6 +19,7 @@
 package org.apache.shindig.common;
 
 import org.apache.shindig.common.util.DateUtil;
+import org.apache.shindig.common.uri.Uri;
 import org.joda.time.DateTime;
 import org.json.JSONArray;
 import org.json.JSONObject;
@@ -31,6 +32,7 @@ import java.lang.reflect.Method;
 import java.util.Collection;
 import java.util.Date;
 import java.util.Iterator;
+import java.util.Locale;
 import java.util.Map;
 
 /**
@@ -150,6 +152,8 @@ public final class JsonSerializer {
       buf.append(value.toString());
     } else if (value instanceof CharSequence ||
                value instanceof DateTime ||
+               value instanceof Locale ||
+               value instanceof Uri ||
                value.getClass().isEnum()) {
       // String-like Primitives
       appendString(buf, value.toString());
@@ -284,7 +288,7 @@ public final class JsonSerializer {
    *
    * @throws IOException If {@link Appendable#append(char)} throws an exception.
    */
-  public static void appendMap(Appendable buf, Map<String, ?> map) throws IOException {
+  public static void appendMap(final Appendable buf, final Map<String, ?> map) throws IOException {
     buf.append('{');
     boolean firstDone = false;
     for (Map.Entry<String, ?> entry : map.entrySet()) {
@@ -295,7 +299,9 @@ public final class JsonSerializer {
         } else {
           firstDone = true;
         }
-        appendString(buf, entry.getKey());
+        Object key = entry.getKey();
+
+        appendString(buf, key.toString());
         buf.append(':');
         append(buf, value);
       }
@@ -309,7 +315,7 @@ public final class JsonSerializer {
    * @throws IOException If {@link Appendable#append(char)} throws an exception.
    */
   public static void appendMultimap(Appendable buf, Multimap<String, Object> map) throws IOException {
-	appendMap(buf, map.asMap());
+    appendMap(buf, map.asMap());
   }
   
   /**

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/DefaultGuiceModule.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/DefaultGuiceModule.java?rev=964125&r1=964124&r2=964125&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/DefaultGuiceModule.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/DefaultGuiceModule.java Wed Jul 14 18:31:24 2010
@@ -41,6 +41,7 @@ import org.apache.shindig.gadgets.parse.
 import org.apache.shindig.gadgets.preload.PreloadModule;
 import org.apache.shindig.gadgets.render.RenderModule;
 import org.apache.shindig.gadgets.rewrite.RewriteModule;
+import org.apache.shindig.gadgets.servlet.GadgetsHandler;
 import org.apache.shindig.gadgets.servlet.HttpRequestHandler;
 import org.apache.shindig.gadgets.templates.TemplateModule;
 import org.apache.shindig.gadgets.uri.UriModule;
@@ -101,6 +102,7 @@ public class DefaultGuiceModule extends 
     Multibinder<Object> handlerBinder = Multibinder.newSetBinder(binder(), Object.class, Names.named("org.apache.shindig.handlers"));
     handlerBinder.addBinding().to(InvalidationHandler.class);
     handlerBinder.addBinding().to(HttpRequestHandler.class);
+    handlerBinder.addBinding().to(GadgetsHandler.class);
   }
 
   protected void registerConfigContributors() {

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriter.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriter.java?rev=964125&r1=964124&r2=964125&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriter.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriter.java Wed Jul 14 18:31:24 2010
@@ -48,6 +48,7 @@ import org.w3c.dom.NodeList;
 import org.w3c.dom.Text;
 
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -390,7 +391,7 @@ public class RenderingGadgetRewriter imp
    * Injects default values for user prefs into the gadget output.
    */
   protected void injectDefaultPrefs(Gadget gadget, Node scriptTag) {
-    List<UserPref> prefs = gadget.getSpec().getUserPrefs();
+    Collection<UserPref> prefs = gadget.getSpec().getUserPrefs().values();
     Map<String, String> defaultPrefs = Maps.newHashMapWithExpectedSize(prefs.size());
     for (UserPref up : prefs) {
       defaultPrefs.put(up.getName(), up.getDefaultValue());

Added: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandler.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandler.java?rev=964125&view=auto
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandler.java (added)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandler.java Wed Jul 14 18:31:24 2010
@@ -0,0 +1,355 @@
+/*
+ * 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.servlet;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+import com.google.inject.Inject;
+import org.apache.shindig.auth.SecurityToken;
+import org.apache.shindig.common.uri.Uri;
+import org.apache.shindig.gadgets.Gadget;
+import org.apache.shindig.gadgets.GadgetContext;
+import org.apache.shindig.gadgets.RenderingContext;
+import org.apache.shindig.gadgets.UserPrefs;
+import org.apache.shindig.gadgets.process.Processor;
+import org.apache.shindig.gadgets.spec.GadgetSpec;
+import org.apache.shindig.gadgets.spec.ModulePrefs;
+import org.apache.shindig.gadgets.spec.UserPref;
+import org.apache.shindig.gadgets.spec.View;
+import org.apache.shindig.gadgets.uri.IframeUriManager;
+import org.apache.shindig.protocol.BaseRequestItem;
+import org.apache.shindig.protocol.Operation;
+import org.apache.shindig.protocol.ProtocolException;
+import org.apache.shindig.protocol.RequestItem;
+import org.apache.shindig.protocol.Service;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CompletionService;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorCompletionService;
+import java.util.concurrent.ExecutorService;
+
+@Service(name = "gadgets")
+public class GadgetsHandler {
+  Set<String> ALL_METADATA_FIELDS = ImmutableSet.of("iframeUrl", "userPrefs", "modulePrefs", "views", "views.name", "views.type",
+      "views.type", "views.href", "views.quirks", "views.content", "views.preferredHeight", "views.preferredWidth",
+      "views.needsUserPrefsSubstituted", "views.attributes");
+  Set<String> DEFAULT_METADATA_FIELDS = ImmutableSet.of("iframeUrl", "userPrefs", "modulePrefs", "views");
+
+  protected final ExecutorService executor;
+  protected final Processor processor;
+  protected final IframeUriManager iframeUriManager;
+
+  @Inject
+  public GadgetsHandler(ExecutorService executor, Processor processor, IframeUriManager iframeUriManager) {
+    this.executor = executor;
+    this.processor = processor;
+    this.iframeUriManager = iframeUriManager;
+  }
+
+  @Operation(httpMethods = {"POST","GET"}, path = "/metadata/{view}")
+  public Map<String,MetadataGadgetSpec> metadata(BaseRequestItem request) throws ProtocolException {
+    Set<String> gadgetUrls = ImmutableSet.copyOf(request.getListParameter("ids"));
+
+    if (gadgetUrls.isEmpty())
+      return ImmutableMap.of();
+
+    Set<String> fields = request.getFields(DEFAULT_METADATA_FIELDS);
+
+    CompletionService<MetadataGadgetSpec> completionService =  new ExecutorCompletionService<MetadataGadgetSpec>(executor);
+
+    for (String gadgetUri : gadgetUrls) {
+      completionService.submit(createNewJob(new MetadataGadgetContext(gadgetUri,request), fields));
+    }
+
+    int numJobs = gadgetUrls.size();
+    Map<String,MetadataGadgetSpec> response = Maps.newHashMap();
+
+    while (numJobs > 0) {
+      try {
+        MetadataGadgetSpec spec = completionService.take().get();
+        response.put(spec.getUrl(), spec);
+      } catch (InterruptedException e) {
+        throw new ProtocolException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Processing interrupted", e);
+      } catch (ExecutionException ee) {
+        if (!(ee.getCause() instanceof RpcException)) {
+          throw new ProtocolException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Processing error", ee);
+        }
+        RpcException e = (RpcException)ee.getCause();
+        // Just one gadget failed; mark it as such.
+        GadgetContext context = e.getContext();
+        if (context != null) {
+          response.put(context.getUrl().toString(), new MetadataGadgetSpec().setError(e.getCause().getLocalizedMessage()));
+        }
+      } finally {
+        numJobs--;
+      }
+    }
+    return response;
+  }
+
+  @Operation(httpMethods = "GET", path="/@supportedFields")
+  public Set<String> supportedFields(RequestItem request) {
+    return ALL_METADATA_FIELDS;
+  }
+
+  protected MetadataJob createNewJob(GadgetContext context, Set<String> fields) {
+    return new MetadataJob(context, fields);
+  }
+
+  protected class MetadataJob implements Callable<MetadataGadgetSpec> {
+    protected final GadgetContext context;
+    protected final Set<String> fields;
+
+    public MetadataJob(GadgetContext context, Set<String> fields) {
+      this.context = context;
+      this.fields = fields;
+    }
+
+    public MetadataGadgetSpec call() throws RpcException {
+      try {
+        Gadget gadget = processor.process(context);
+        String iframeUrl =  fields.contains("iframeUrl") ? iframeUriManager.makeRenderingUri(gadget).toString() : null;
+
+        FilteringGadgetSpec spec = new FilteringGadgetSpec(gadget.getSpec(), iframeUrl, fields);
+        spec.setUrl(context.getUrl().toString());
+        return spec;
+      } catch (Exception e) {
+        throw new RpcException(context, e);
+      }
+    }
+  }
+
+  /**
+   * Localized implementation of GadgetContext that uses information from the request.
+   */
+  private static class MetadataGadgetContext extends GadgetContext {
+    final BaseRequestItem request;
+    final Uri uri;
+    final Locale locale;
+    final boolean ignoreCache;
+    final boolean debug;
+    final String container;
+
+    public MetadataGadgetContext(String uri, BaseRequestItem request) {
+      this.request = Preconditions.checkNotNull(request);
+      this.uri = Uri.parse(Preconditions.checkNotNull(uri));
+
+      String lang = request.getParameter("language");
+      String country = request.getParameter("country");
+
+      this.locale = (lang != null && country != null) ? new Locale(lang,country) :
+                    (lang != null) ? new Locale(lang) :
+                    GadgetSpec.DEFAULT_LOCALE;
+
+      this.ignoreCache = Boolean.valueOf(request.getParameter("ignoreCache"));
+      this.debug = Boolean.valueOf(request.getParameter("debug"));
+      this.container = request.getToken().getContainer();
+    }
+
+    @Override
+    public Uri getUrl() {
+      return uri;
+    }
+
+    @Override
+    public int getModuleId() {
+      return 1; // TODO calculate?
+    }
+
+    @Override
+    public Locale getLocale() {
+      return locale;
+    }
+
+    @Override
+    public RenderingContext getRenderingContext() {
+      return RenderingContext.METADATA;
+    }
+
+    @Override
+    public boolean getIgnoreCache() {
+      return ignoreCache;
+    }
+
+    @Override
+    public String getContainer() {
+      return container;
+    }
+
+    @Override
+    public boolean getDebug() {
+      return debug;
+    }
+
+    @Override
+    public String getView() {
+      return request.getParameter("view", "default");
+    }
+
+    @Override
+    public UserPrefs getUserPrefs() {
+            // TODO
+      return new UserPrefs(Maps.<String,String>newHashMap());
+    }
+
+    @Override
+    public SecurityToken getToken() {
+      return request.getToken();
+    }
+  }
+
+
+  // has to be public for reflection to work.
+  public static final class FilteringView {
+    private final View view;
+    private final Set<String> fields;
+
+    /**
+     * Return the actual item if the requested fields contains "views" or param
+     * @param item any item
+     * @param param a field to test for
+     * @param <T> any type
+     * @return Returns item if fields contains "views" or param
+     */
+    private <T> T filter(T item, String param) {
+      return (fields.contains("views") || fields.contains(param)) ? item : null;
+    }
+
+    public FilteringView(View view, Set<String> fields) {
+      this.view = view;
+      this.fields = fields;
+    }
+
+    public String getName() {
+      return filter(view.getName(), "views.name");
+    }
+
+    public View.ContentType getType() {
+      return filter(view.getType(), "views.type");
+    }
+
+    public Uri getHref() {
+      return filter(view.getHref(), "views.href");
+    }
+
+    public Boolean getQuirks() {
+      return filter(view.getQuirks(), "views.quirks");
+    }
+
+    public String getContent() {
+      return fields.contains("views.content") ? view.getContent() : null;
+    }
+
+    public Integer getPreferredHeight() {
+      return filter(view.getPreferredHeight(), "views.preferredHeight");
+    }
+
+    public Integer getPreferredWidth() {
+      return filter(view.getPreferredWidth(), "views.preferredWidth");
+    }
+
+    public Boolean needsUserPrefSubstitution() {
+      return filter(view.needsUserPrefSubstitution(), "views.needsUserPrefSubstitution");
+    }
+
+    public Map<String, String> getAttributes() {
+      return filter(view.getAttributes(), "views.attributes");
+    }
+  }
+
+  // has to be public for reflection to work..
+  public static class MetadataGadgetSpec {
+    private String msg = null;
+    private String url = null;
+
+    public MetadataGadgetSpec setError(String msg) {
+      this.msg = msg;
+      return this;
+    }
+    public MetadataGadgetSpec setUrl(String url) {
+      this.url = url;
+      return this;
+    }
+    public String getError() {
+      return msg;  
+    }
+    public String getUrl() {
+      return url;
+    }
+  }
+  
+  // has to be public for reflection to work.
+  public static final class FilteringGadgetSpec extends MetadataGadgetSpec {
+    private final GadgetSpec spec;
+    private final String iframeUrl;
+    private final Map<String,FilteringView> views;
+    private final Set<String> fields;
+
+    public FilteringGadgetSpec(GadgetSpec spec, String iframeUrl, Set<String> fields) {
+      this.spec = Preconditions.checkNotNull(spec);
+      this.iframeUrl = iframeUrl; // can be null
+      this.fields = Preconditions.checkNotNull(fields);
+
+      // Do we need view data?
+      boolean viewsRequested = fields.contains("views");
+      for (String f: fields) {
+        if (f.startsWith("views")) {
+          viewsRequested = true;
+        }
+      }
+      if (viewsRequested) {
+        ImmutableMap.Builder<String,FilteringView> builder = ImmutableMap.builder();
+        for (Map.Entry<String,View> entry : spec.getViews().entrySet()) {
+          builder.put(entry.getKey(), new FilteringView(entry.getValue(), fields));
+        }
+        views = builder.build();
+      } else {
+        views = null;
+      }
+    }
+
+    public String getIframeUrl() {
+      return fields.contains("iframeUrl") ? iframeUrl : null;
+    }
+
+    public String getChecksum() {
+      return fields.contains("checksum") ? spec.getChecksum() : null;
+    }
+
+    public ModulePrefs getModulePrefs() {
+      return fields.contains("modulePrefs") ? spec.getModulePrefs() : null;
+    }
+
+    public Map<String,UserPref> getUserPrefs() {
+      return fields.contains("userPrefs") ? spec.getUserPrefs() : null;
+    }
+
+    public Map<String, FilteringView> getViews() {
+      return views;
+    }
+  }
+}
\ No newline at end of file

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/JsonRpcHandler.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/JsonRpcHandler.java?rev=964125&r1=964124&r2=964125&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/JsonRpcHandler.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/JsonRpcHandler.java Wed Jul 14 18:31:24 2010
@@ -182,7 +182,7 @@ public class JsonRpcHandler {
         JSONObject userPrefs = new JSONObject();
 
         // User pref specs
-        for (UserPref pref : spec.getUserPrefs()) {
+        for (UserPref pref : spec.getUserPrefs().values()) {
           JSONObject up = new JSONObject()
               .put("displayName", pref.getDisplayName())
               .put("type", pref.getDataType().toString().toLowerCase())

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/GadgetSpec.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/GadgetSpec.java?rev=964125&r1=964124&r2=964125&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/GadgetSpec.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/GadgetSpec.java Wed Jul 14 18:31:24 2010
@@ -64,7 +64,7 @@ public class GadgetSpec {
     NodeList children = doc.getChildNodes();
 
     ModulePrefs modulePrefs = null;
-    List<UserPref> userPrefs = Lists.newLinkedList();
+    ImmutableMap.Builder<String,UserPref> prefsBuilder = ImmutableMap.builder();
     Map<String, List<Element>> views = Maps.newHashMap();
     for (int i = 0, j = children.getLength(); i < j; ++i) {
       Node child = children.item(i);
@@ -82,7 +82,7 @@ public class GadgetSpec {
       }
       if ("UserPref".equals(name)) {
         UserPref pref = new UserPref(element);
-        userPrefs.add(pref);
+        prefsBuilder.put(pref.getName(), pref);
       }
       if ("Content".equals(name)) {
         String viewNames = XmlUtil.getAttribute(element, "view", "default");
@@ -114,11 +114,7 @@ public class GadgetSpec {
       }
       this.views = ImmutableMap.copyOf(tmpViews);
     }
-    if (userPrefs.isEmpty()) {
-      this.userPrefs = Collections.emptyList();
-    } else {
-      this.userPrefs = ImmutableList.copyOf(userPrefs);
-    }
+    this.userPrefs = prefsBuilder.build();
   }
 
   /**
@@ -165,8 +161,8 @@ public class GadgetSpec {
   /**
    * UserPref
    */
-  private List<UserPref> userPrefs;
-  public List<UserPref> getUserPrefs() {
+  private Map<String,UserPref> userPrefs;
+  public Map<String,UserPref> getUserPrefs() {
     return userPrefs;
   }
 
@@ -222,13 +218,13 @@ public class GadgetSpec {
     spec.modulePrefs = modulePrefs.substitute(substituter);
 
     if (userPrefs.isEmpty()) {
-      spec.userPrefs = Collections.emptyList();
+      spec.userPrefs = ImmutableMap.of();
     } else {
-      List<UserPref> prefs = Lists.newArrayListWithCapacity(userPrefs.size());
-      for (UserPref pref : userPrefs) {
-        prefs.add(pref.substitute(substituter));
+      ImmutableMap.Builder<String,UserPref> prefs = ImmutableMap.builder();
+      for (UserPref pref : this.userPrefs.values()) {
+        prefs.put(pref.getName(), pref.substitute(substituter));
       }
-      spec.userPrefs = ImmutableList.copyOf(prefs);
+      spec.userPrefs = prefs.build();
     }
 
     ImmutableMap.Builder<String, View> viewMap = ImmutableMap.builder();
@@ -245,7 +241,7 @@ public class GadgetSpec {
     StringBuilder buf = new StringBuilder();
     buf.append("<Module>\n")
        .append(modulePrefs).append('\n');
-    for (UserPref pref : userPrefs) {
+    for (UserPref pref : userPrefs.values()) {
       buf.append(pref).append('\n');
     }
     for (Map.Entry<String, View> view : views.entrySet()) {

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/DefaultIframeUriManager.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/DefaultIframeUriManager.java?rev=964125&r1=964124&r2=964125&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/DefaultIframeUriManager.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/DefaultIframeUriManager.java Wed Jul 14 18:31:24 2010
@@ -139,7 +139,7 @@ public class DefaultIframeUriManager imp
     
     // Add all UserPrefs
     UserPrefs prefs = context.getUserPrefs();
-    for (UserPref up : gadget.getSpec().getUserPrefs()) {
+    for (UserPref up : gadget.getSpec().getUserPrefs().values()) {
       String name = up.getName();
       String data = prefs.getPref(name);
       if (data == null) {

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/variables/UserPrefSubstituter.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/variables/UserPrefSubstituter.java?rev=964125&r1=964124&r2=964125&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/variables/UserPrefSubstituter.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/variables/UserPrefSubstituter.java Wed Jul 14 18:31:24 2010
@@ -31,7 +31,7 @@ public class UserPrefSubstituter impleme
   public void addSubstitutions(Substitutions substituter, GadgetContext context, GadgetSpec spec) {
     UserPrefs values = context.getUserPrefs();
     
-    for (UserPref pref : spec.getUserPrefs()) {
+    for (UserPref pref : spec.getUserPrefs().values()) {
       String name = pref.getName();
       String value = values.getPref(name);
       if (value == null) {

Added: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/FakeIframeUriManager.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/FakeIframeUriManager.java?rev=964125&view=auto
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/FakeIframeUriManager.java (added)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/FakeIframeUriManager.java Wed Jul 14 18:31:24 2010
@@ -0,0 +1,44 @@
+/*
+ * 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.servlet;
+
+import org.apache.shindig.common.uri.Uri;
+import org.apache.shindig.gadgets.Gadget;
+import org.apache.shindig.gadgets.uri.IframeUriManager;
+import org.apache.shindig.gadgets.uri.UriStatus;
+
+public class FakeIframeUriManager implements IframeUriManager {
+  protected boolean throwRandomFault = false;
+  public static final Uri DEFAULT_IFRAME_URI = Uri.parse("http://example.org/gadgets/foo-does-not-matter");
+  protected Uri iframeUrl = DEFAULT_IFRAME_URI;
+
+  FakeIframeUriManager() { }
+
+  public Uri makeRenderingUri(Gadget gadget) {
+    if (throwRandomFault) {
+      throw new RuntimeException("BROKEN");
+    }
+    return iframeUrl;
+  }
+
+  public UriStatus validateRenderingUri(Uri uri) {
+    throw new UnsupportedOperationException();
+  }
+}

Added: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/FakeProcessor.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/FakeProcessor.java?rev=964125&view=auto
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/FakeProcessor.java (added)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/FakeProcessor.java Wed Jul 14 18:31:24 2010
@@ -0,0 +1,92 @@
+/*
+ * 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.servlet;
+
+import com.google.common.collect.Maps;
+import org.apache.shindig.common.uri.Uri;
+import org.apache.shindig.gadgets.Gadget;
+import org.apache.shindig.gadgets.GadgetContext;
+import org.apache.shindig.gadgets.GadgetException;
+import org.apache.shindig.gadgets.process.ProcessingException;
+import org.apache.shindig.gadgets.process.Processor;
+import org.apache.shindig.gadgets.spec.GadgetSpec;
+import org.apache.shindig.gadgets.spec.View;
+
+import java.util.Map;
+
+public class FakeProcessor extends Processor {
+  protected final Map<Uri, ProcessingException> exceptions = Maps.newHashMap();
+  protected final Map<Uri, String> gadgets = Maps.newHashMap();
+  public static final Uri SPEC_URL = Uri.parse("http://example.org/g.xml");
+  public static final Uri SPEC_URL2 = Uri.parse("http://example.org/g2.xml");
+  public static final String SPEC_TITLE = "JSON-TEST";
+  public static final String SPEC_TITLE2 = "JSON-TEST2";
+  public static final int PREFERRED_HEIGHT = 100;
+  public static final int PREFERRED_WIDTH = 242;
+  public static final String LINK_REL = "rel";
+  public static final String LINK_HREF = "http://example.org/foo";
+  public static final String SPEC_XML =
+      "<Module>" +
+      "<ModulePrefs title=\"" + SPEC_TITLE + "\">" +
+      "  <Link rel='" + LINK_REL + "' href='" + LINK_HREF + "'/>" +
+      "</ModulePrefs>" +
+      "<UserPref name=\"up_one\">" +
+      "  <EnumValue value=\"val1\" display_value=\"disp1\"/>" +
+      "  <EnumValue value=\"abc\" display_value=\"disp2\"/>" +
+      "  <EnumValue value=\"z_xabc\" display_value=\"disp3\"/>" +
+      "  <EnumValue value=\"foo\" display_value=\"disp4\"/>" +
+      "</UserPref>" +
+      "<Content type=\"html\"" +
+      " preferred_height = \"" + PREFERRED_HEIGHT + '\"' +
+      " preferred_width = \"" + PREFERRED_WIDTH + '\"' +
+      ">Hello, world</Content>" +
+      "</Module>";
+
+  public static final String SPEC_XML2 =
+          "<Module>" +
+          "<ModulePrefs title=\"" + SPEC_TITLE2 + "\"/>" +
+          "<Content type=\"html\">Hello, world</Content>" +
+          "</Module>";
+
+  public FakeProcessor() {
+    super(null, null, null, null, null);
+    this.gadgets.put(FakeProcessor.SPEC_URL, FakeProcessor.SPEC_XML);
+    this.gadgets.put(FakeProcessor.SPEC_URL2, FakeProcessor.SPEC_XML2);
+  }
+
+  @Override
+  public Gadget process(GadgetContext context) throws ProcessingException {
+
+    ProcessingException exception = exceptions.get(context.getUrl());
+    if (exception != null) {
+      throw exception;
+    }
+
+    try {
+      GadgetSpec spec = new GadgetSpec(Uri.parse("#"), gadgets.get(context.getUrl()));
+      View view = spec.getView(context.getView());
+      return new Gadget()
+          .setContext(context)
+          .setSpec(spec)
+          .setCurrentView(view);
+    } catch (GadgetException e) {
+      throw new RuntimeException(e);
+    }
+  }
+}

Added: 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=964125&view=auto
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerTest.java (added)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerTest.java Wed Jul 14 18:31:24 2010
@@ -0,0 +1,224 @@
+/*
+ * 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.servlet;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import org.apache.shindig.common.EasyMockTestCase;
+import org.apache.shindig.common.JsonAssert;
+import org.apache.shindig.common.testing.FakeGadgetToken;
+import org.apache.shindig.common.testing.TestExecutorService;
+import org.apache.shindig.common.uri.Uri;
+import org.apache.shindig.gadgets.http.HttpRequest;
+import org.apache.shindig.gadgets.http.RequestPipeline;
+import org.apache.shindig.gadgets.process.ProcessingException;
+import org.apache.shindig.gadgets.spec.GadgetSpec;
+import org.apache.shindig.protocol.DefaultHandlerRegistry;
+import org.apache.shindig.protocol.HandlerExecutionListener;
+import org.apache.shindig.protocol.HandlerRegistry;
+import org.apache.shindig.protocol.RpcHandler;
+import org.apache.shindig.protocol.conversion.BeanJsonConverter;
+import org.apache.shindig.protocol.multipart.FormDataItem;
+import org.easymock.EasyMock;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executors;
+
+import static org.easymock.EasyMock.expect;
+
+public class GadgetsHandlerTest extends EasyMockTestCase {
+  private final RequestPipeline pipeline = mock(RequestPipeline.class);
+  private final FakeProcessor processor = new FakeProcessor();
+  private final FakeIframeUriManager urlGenerator = new FakeIframeUriManager();
+  private final Map<String,FormDataItem> emptyFormItems = Collections.emptyMap();
+
+  private BeanJsonConverter converter;
+  private HandlerRegistry registry;
+  private FakeGadgetToken token;
+
+
+  @Before
+  public void setUp() throws Exception {
+    Injector injector = Guice.createInjector();
+    converter = new BeanJsonConverter(injector);
+
+    GadgetsHandler gadgetsHandler = new GadgetsHandler(new TestExecutorService(),
+        processor,
+        urlGenerator);
+
+    registry = new DefaultHandlerRegistry(injector, converter,
+        new HandlerExecutionListener.NoOpHandler());
+    registry.addHandlers(ImmutableSet.<Object>of(gadgetsHandler));
+
+    token = new FakeGadgetToken();
+    token.setAppUrl("http://www.example.com/gadget.xml");
+
+  }
+
+  private JSONObject createContext(String lang, String country)
+      throws JSONException {
+    return new JSONObject().put("language", lang).put("country", country);
+  }
+
+  private JSONObject makeMetadataRequest(String lang, String country, Collection<String> uris) throws JSONException {
+    JSONObject req = new JSONObject()
+        .put("method", "gadgets.metadata")
+        .put("id", "req1")
+        .put("params", new JSONObject().put("ids", uris));
+
+    if (lang != null) req.put("language", lang);
+    if (country != null) req.put("country", country);
+    return req;
+  }
+  
+  @Test
+  public void testMetadataEmptyRequest() throws Exception {
+    JSONObject emptyrequest = makeMetadataRequest(null, null, Collections.<String>emptyList());
+
+    RpcHandler operation = registry.getRpcHandler(emptyrequest);
+
+    Object empty = operation.execute(emptyFormItems, token, converter).get();
+    JsonAssert.assertJsonEquals("{}", converter.convertToString(empty));
+  }
+
+  @Test(expected=ExecutionException.class)
+  public void testMetadataInvalidUrl() throws Exception {
+    JSONObject invalidRequest = makeMetadataRequest(null, null, ImmutableList.of("[moo]"));
+
+    RpcHandler operation = registry.getRpcHandler(invalidRequest);
+
+    Object empty = operation.execute(emptyFormItems, token, converter).get();
+  }
+
+  @Test
+  public void testMetadataOneGadget() throws Exception {
+    JSONObject oneGadget = makeMetadataRequest(null, null, ImmutableList.of(FakeProcessor.SPEC_URL.toString()));
+
+    RpcHandler operation = registry.getRpcHandler(oneGadget);
+
+    Object responseObj = operation.execute(emptyFormItems, token, converter).get();
+    JSONObject response = new JSONObject(converter.convertToString(responseObj));
+
+    JSONObject gadget = response.getJSONObject(FakeProcessor.SPEC_URL.toString());
+    assertEquals(FakeIframeUriManager.DEFAULT_IFRAME_URI.toString(), gadget.getString("iframeUrl"));
+    assertEquals(FakeProcessor.SPEC_TITLE, gadget.getJSONObject("modulePrefs").getString("title"));
+
+    JSONObject view = gadget.getJSONObject("views").getJSONObject(GadgetSpec.DEFAULT_VIEW);
+    assertEquals(FakeProcessor.PREFERRED_HEIGHT, view.getInt("preferredHeight"));
+    assertEquals(FakeProcessor.PREFERRED_WIDTH, view.getInt("preferredWidth"));
+    assertEquals(FakeProcessor.LINK_HREF, gadget.getJSONObject("modulePrefs").getJSONObject("links")
+        .getJSONObject(FakeProcessor.LINK_REL).getString("href"));
+
+    JSONObject userPrefs = gadget.getJSONObject("userPrefs");
+    assertNotNull(userPrefs);
+
+    JSONObject userPrefData = userPrefs.getJSONObject("up_one");
+    assertNotNull(userPrefData);
+
+    JSONObject upEnums = userPrefData.getJSONObject("enumValues");
+    assertNotNull(upEnums);
+    assertEquals("disp1", upEnums.get("val1"));
+    assertEquals("disp2", upEnums.get("abc"));
+    assertEquals("disp3", upEnums.get("z_xabc"));
+    assertEquals("disp4", upEnums.get("foo"));
+
+    JSONArray orderedEnums = userPrefData.getJSONArray("orderedEnumValues");
+    assertNotNull(orderedEnums);
+    assertEquals(4, orderedEnums.length());
+    assertEquals("val1", orderedEnums.getJSONObject(0).getString("value"));
+    assertEquals("abc", orderedEnums.getJSONObject(1).getString("value"));
+    assertEquals("z_xabc", orderedEnums.getJSONObject(2).getString("value"));
+    assertEquals("foo", orderedEnums.getJSONObject(3).getString("value"));
+  }
+
+  @Test
+  public void testMetadataUnexpectedError() throws Exception {
+    JSONObject oneGadget = makeMetadataRequest(null, null, ImmutableList.of(FakeProcessor.SPEC_URL.toString()));
+
+    urlGenerator.throwRandomFault = true;
+
+    RpcHandler operation = registry.getRpcHandler(oneGadget);
+    Object responseObj = operation.execute(emptyFormItems, token, converter).get();
+    JSONObject response = new JSONObject(converter.convertToString(responseObj));
+
+    String actual = response.getJSONObject(FakeProcessor.SPEC_URL.toString()).getString("error");
+    assertEquals("BROKEN", actual);
+  }
+
+  @Test
+  public void testMultipleGadgets() throws Exception {
+    JSONObject metadataRequest = makeMetadataRequest("en", "US",
+        ImmutableList.of(FakeProcessor.SPEC_URL.toString(),
+                         FakeProcessor.SPEC_URL2.toString()));
+
+    RpcHandler operation = registry.getRpcHandler(metadataRequest);
+    Object responseObj = operation.execute(emptyFormItems, token, converter).get();
+    JSONObject response = new JSONObject(converter.convertToString(responseObj));
+
+    JSONObject gadget;
+
+    // First gadget..
+    gadget = response.getJSONObject(FakeProcessor.SPEC_URL.toString());
+    assertNotNull("got gadget1", gadget);
+    assertEquals(FakeProcessor.SPEC_TITLE, gadget.getJSONObject("modulePrefs").getString("title"));
+
+    gadget = response.getJSONObject(FakeProcessor.SPEC_URL2.toString());
+    assertNotNull("got gadget2", gadget);
+    assertEquals(FakeProcessor.SPEC_TITLE2, gadget.getJSONObject("modulePrefs").getString("title"));
+  }
+
+  @Test
+  public void testMultipleGadgetsWithAnError() throws Exception {
+    JSONObject metadataRequest = makeMetadataRequest("en", "US",
+        ImmutableList.of(FakeProcessor.SPEC_URL.toString(),
+                         FakeProcessor.SPEC_URL2.toString()));
+
+    processor.exceptions.put(FakeProcessor.SPEC_URL2,
+        new ProcessingException("broken", HttpServletResponse.SC_BAD_REQUEST));
+
+    RpcHandler operation = registry.getRpcHandler(metadataRequest);
+    Object responseObj = operation.execute(emptyFormItems, token, converter).get();
+    JSONObject response = new JSONObject(converter.convertToString(responseObj));
+
+    JSONObject gadget;
+
+    // First gadget..
+    gadget = response.getJSONObject(FakeProcessor.SPEC_URL.toString());
+    assertNotNull("got gadget1", gadget);
+    assertEquals(FakeProcessor.SPEC_TITLE, gadget.getJSONObject("modulePrefs").getString("title"));
+
+    gadget = response.getJSONObject(FakeProcessor.SPEC_URL2.toString());
+    assertNotNull("got gadget2", gadget);
+    assertEquals("broken", gadget.getString("error"));
+  }
+}

Modified: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/HttpRequestHandlerTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/HttpRequestHandlerTest.java?rev=964125&r1=964124&r2=964125&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/HttpRequestHandlerTest.java (original)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/HttpRequestHandlerTest.java Wed Jul 14 18:31:24 2010
@@ -80,7 +80,7 @@ public class HttpRequestHandlerTest exte
 
   private HttpResponseBuilder builder;
 
-  private Map<String,FormDataItem> emptyFormItems;
+  private final Map<String,FormDataItem> emptyFormItems = Collections.emptyMap();
 
   @Before
   public void setUp() throws Exception {
@@ -95,7 +95,6 @@ public class HttpRequestHandlerTest exte
         new HandlerExecutionListener.NoOpHandler());
     registry.addHandlers(ImmutableSet.<Object>of(handler));
     builder = new HttpResponseBuilder().setResponseString("CONTENT");
-    emptyFormItems = Collections.emptyMap();
   }
 
   @Test
@@ -114,8 +113,8 @@ public class HttpRequestHandlerTest exte
         (HttpRequestHandler.HttpApiResponse)operation.execute(emptyFormItems, token, converter).get();
     verify();
 
-    JsonAssert.assertJsonEquals(converter.convertToString(httpApiResponse),
-        "{ headers : {}, status : 200, content : 'CONTENT' }}");
+    JsonAssert.assertJsonEquals("{ headers : {}, status : 200, content : 'CONTENT' }}",
+        converter.convertToString(httpApiResponse));
   }
 
   @Test
@@ -153,8 +152,8 @@ public class HttpRequestHandlerTest exte
         (HttpRequestHandler.HttpApiResponse)operation.execute(emptyFormItems, token, converter).get();
     verify();
 
-    JsonAssert.assertJsonEquals(converter.convertToString(httpApiResponse),
-        "{ headers : {}, status : 200, content : 'CONTENT' }}");
+    JsonAssert.assertJsonEquals("{ headers : {}, status : 200, content : 'CONTENT' }}",
+        converter.convertToString(httpApiResponse));
   }
 
   @Test
@@ -178,8 +177,8 @@ public class HttpRequestHandlerTest exte
         (HttpRequestHandler.HttpApiResponse)operation.execute(emptyFormItems, token, converter).get();
     verify();
 
-    JsonAssert.assertJsonEquals(converter.convertToString(httpApiResponse),
-        "{ headers : {}, status : 200, content : 'CONTENT' }}");
+    JsonAssert.assertJsonEquals("{ headers : {}, status : 200, content : 'CONTENT' }}",
+        converter.convertToString(httpApiResponse));
   }
 
   @Test
@@ -304,8 +303,8 @@ public class HttpRequestHandlerTest exte
         (HttpRequestHandler.HttpApiResponse)operation.execute(emptyFormItems, token, converter).get();
     verify();
 
-    JsonAssert.assertJsonEquals(converter.convertToString(httpApiResponse),
-        "{ headers : {}, status : 200, content : {key: 1}}}");
+    JsonAssert.assertJsonEquals("{ headers : {}, status : 200, content : {key: 1}}}",
+        converter.convertToString(httpApiResponse));
   }
 
   @Test
@@ -327,8 +326,8 @@ public class HttpRequestHandlerTest exte
         (HttpRequestHandler.HttpApiResponse)operation.execute(emptyFormItems, token, converter).get();
     verify();
 
-    JsonAssert.assertJsonEquals(converter.convertToString(httpApiResponse),
-        "{ headers : {}, status : 200, content : 'CONTENT' }}");
+    JsonAssert.assertJsonEquals("{ headers : {}, status : 200, content : 'CONTENT' }}",
+        converter.convertToString(httpApiResponse));
 
     assertTrue(rewriter.responseWasRewritten());
   }
@@ -355,8 +354,8 @@ public class HttpRequestHandlerTest exte
         (HttpRequestHandler.HttpApiResponse)operation.execute(emptyFormItems, token, converter).get();
     verify();
 
-    JsonAssert.assertJsonEquals(converter.convertToString(httpApiResponse),
-        "{ headers : {}, status : 200, content : 'CONTENT', token : updated }}");
+    JsonAssert.assertJsonEquals("{ headers : {}, status : 200, content : 'CONTENT', token : updated }}",
+        converter.convertToString(httpApiResponse));
 
     assertTrue(rewriter.responseWasRewritten());
   }
@@ -473,8 +472,8 @@ public class HttpRequestHandlerTest exte
         (HttpRequestHandler.HttpApiResponse)operation.execute(emptyFormItems, token, converter).get();
     verify();
 
-    JsonAssert.assertJsonEquals(converter.convertToString(httpApiResponse),
-        "{ headers : {}, status : 500, content : 'I AM AN ERROR MESSAGE' }}");
+    JsonAssert.assertJsonEquals("{ headers : {}, status : 500, content : 'I AM AN ERROR MESSAGE' }}",
+        converter.convertToString(httpApiResponse));
   }
 
   @Test
@@ -494,8 +493,8 @@ public class HttpRequestHandlerTest exte
         (HttpRequestHandler.HttpApiResponse)operation.execute(emptyFormItems, token, converter).get();
     verify();
 
-    JsonAssert.assertJsonEquals(converter.convertToString(httpApiResponse),
-        "{ headers : {}, status : 200, content : 'CONTENT', metadata : { foo : 'CONTENT' }}");
+    JsonAssert.assertJsonEquals("{ headers : {}, status : 200, content : 'CONTENT', metadata : { foo : 'CONTENT' }}",
+        converter.convertToString(httpApiResponse));
   }
 
   @Test
@@ -516,9 +515,10 @@ public class HttpRequestHandlerTest exte
         (HttpRequestHandler.HttpApiResponse)operation.execute(emptyFormItems, token, converter).get();
     verify();
 
-    JsonAssert.assertJsonEquals(converter.convertToString(httpApiResponse),
+    JsonAssert.assertJsonEquals(
         "{ headers : { 'set-cookie' : ['foo=bar; Secure','name=value'] },"
-            + " status : 200, content : 'CONTENT' }");    
+            + " status : 200, content : 'CONTENT' }",
+        converter.convertToString(httpApiResponse));
   }
 
   @Test
@@ -538,9 +538,9 @@ public class HttpRequestHandlerTest exte
         (HttpRequestHandler.HttpApiResponse)operation.execute(emptyFormItems, token, converter).get();
     verify();
 
-    JsonAssert.assertJsonEquals(converter.convertToString(httpApiResponse),
-        "{ headers : { 'location' : ['here'] },"
-            + " status : 200, content : 'CONTENT' }");
+    JsonAssert.assertJsonEquals("{ headers : { 'location' : ['here'] },"
+            + " status : 200, content : 'CONTENT' }",
+        converter.convertToString(httpApiResponse));
   }
 
   private static HttpRequest eqRequest(HttpRequest request) {

Modified: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/JsonRpcHandlerTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/JsonRpcHandlerTest.java?rev=964125&r1=964124&r2=964125&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/JsonRpcHandlerTest.java (original)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/JsonRpcHandlerTest.java Wed Jul 14 18:31:24 2010
@@ -23,23 +23,12 @@ import static org.junit.Assert.assertNot
 import static org.junit.Assert.assertTrue;
 
 import org.apache.shindig.common.testing.TestExecutorService;
-import org.apache.shindig.common.uri.Uri;
-import org.apache.shindig.gadgets.Gadget;
-import org.apache.shindig.gadgets.GadgetContext;
-import org.apache.shindig.gadgets.GadgetException;
 import org.apache.shindig.gadgets.process.ProcessingException;
-import org.apache.shindig.gadgets.process.Processor;
 import org.apache.shindig.gadgets.spec.GadgetSpec;
-import org.apache.shindig.gadgets.spec.View;
-import org.apache.shindig.gadgets.uri.IframeUriManager;
-import org.apache.shindig.gadgets.uri.UriStatus;
-
-import com.google.common.collect.Maps;
 
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
-import org.junit.Before;
 import org.junit.Test;
 
 import java.util.Collections;
@@ -48,36 +37,6 @@ import java.util.Map;
 import javax.servlet.http.HttpServletResponse;
 
 public class JsonRpcHandlerTest {
-  private static final Uri SPEC_URL = Uri.parse("http://example.org/g.xml");
-  private static final Uri SPEC_URL2 = Uri.parse("http://example.org/g2.xml");
-  private static final String SPEC_TITLE = "JSON-TEST";
-  private static final String SPEC_TITLE2 = "JSON-TEST2";
-  private static final int PREFERRED_HEIGHT = 100;
-  private static final int PREFERRED_WIDTH = 242;
-  private static final String LINK_REL = "rel";
-  private static final String LINK_HREF = "http://example.org/foo";
-  private static final String SPEC_XML =
-      "<Module>" +
-      "<ModulePrefs title=\"" + SPEC_TITLE + "\">" +
-      "  <Link rel='" + LINK_REL + "' href='" + LINK_HREF + "'/>" +
-      "</ModulePrefs>" +
-      "<UserPref name=\"up_one\">" +
-      "  <EnumValue value=\"val1\" display_value=\"disp1\"/>" +
-      "  <EnumValue value=\"abc\" display_value=\"disp2\"/>" +
-      "  <EnumValue value=\"z_xabc\" display_value=\"disp3\"/>" +
-      "  <EnumValue value=\"foo\" display_value=\"disp4\"/>" +
-      "</UserPref>" +
-      "<Content type=\"html\"" +
-      " preferred_height = \"" + PREFERRED_HEIGHT + '\"' +
-      " preferred_width = \"" + PREFERRED_WIDTH + '\"' +
-      ">Hello, world</Content>" +
-      "</Module>";
-  private static final String SPEC_XML2 =
-      "<Module>" +
-      "<ModulePrefs title=\"" + SPEC_TITLE2 + "\"/>" +
-      "<Content type=\"html\">Hello, world</Content>" +
-      "</Module>";
-
   private final FakeProcessor processor = new FakeProcessor();
   private final FakeIframeUriManager urlGenerator = new FakeIframeUriManager();
   private final JsonRpcHandler jsonRpcHandler
@@ -88,12 +47,6 @@ public class JsonRpcHandlerTest {
     return new JSONObject().put("language", lang).put("country", country);
   }
 
-  @Before
-  public void setUp() {
-    processor.gadgets.put(SPEC_URL, SPEC_XML);
-    processor.gadgets.put(SPEC_URL2, SPEC_XML2);
-  }
-
   private JSONObject createGadget(String url, int moduleId, Map<String, String> prefs)
       throws JSONException {
     return new JSONObject()
@@ -105,25 +58,25 @@ public class JsonRpcHandlerTest {
   @Test
   public void testSimpleRequest() throws Exception {
     JSONArray gadgets = new JSONArray()
-        .put(createGadget(SPEC_URL.toString(), 0, null));
+        .put(createGadget(FakeProcessor.SPEC_URL.toString(), 0, null));
     JSONObject input = new JSONObject()
         .put("context", createContext("en", "US"))
         .put("gadgets", gadgets);
 
-    urlGenerator.iframeUrl = SPEC_URL;
+    urlGenerator.iframeUrl = FakeProcessor.SPEC_URL;
 
     JSONObject response = jsonRpcHandler.process(input);
 
     JSONArray outGadgets = response.getJSONArray("gadgets");
     JSONObject gadget = outGadgets.getJSONObject(0);
-    assertEquals(SPEC_URL.toString(), gadget.getString("iframeUrl"));
-    assertEquals(SPEC_TITLE, gadget.getString("title"));
+    assertEquals(FakeProcessor.SPEC_URL.toString(), gadget.getString("iframeUrl"));
+    assertEquals(FakeProcessor.SPEC_TITLE, gadget.getString("title"));
     assertEquals(0, gadget.getInt("moduleId"));
 
     JSONObject view = gadget.getJSONObject("views").getJSONObject(GadgetSpec.DEFAULT_VIEW);
-    assertEquals(PREFERRED_HEIGHT, view.getInt("preferredHeight"));
-    assertEquals(PREFERRED_WIDTH, view.getInt("preferredWidth"));
-    assertEquals(LINK_HREF, gadget.getJSONObject("links").getString(LINK_REL));
+    assertEquals(FakeProcessor.PREFERRED_HEIGHT, view.getInt("preferredHeight"));
+    assertEquals(FakeProcessor.PREFERRED_WIDTH, view.getInt("preferredWidth"));
+    assertEquals(FakeProcessor.LINK_HREF, gadget.getJSONObject("links").getString(FakeProcessor.LINK_REL));
 
     JSONObject userPrefs = gadget.getJSONObject("userPrefs");
     assertNotNull(userPrefs);
@@ -150,7 +103,7 @@ public class JsonRpcHandlerTest {
   @Test
   public void testUnexpectedError() throws Exception {
     JSONArray gadgets = new JSONArray()
-        .put(createGadget(SPEC_URL.toString(), 0, null));
+        .put(createGadget(FakeProcessor.SPEC_URL.toString(), 0, null));
     JSONObject input = new JSONObject()
         .put("context", createContext("en", "US"))
         .put("gadgets", gadgets);
@@ -166,8 +119,8 @@ public class JsonRpcHandlerTest {
   @Test
   public void testMultipleGadgets() throws Exception {
     JSONArray gadgets = new JSONArray()
-        .put(createGadget(SPEC_URL.toString(), 0, null))
-        .put(createGadget(SPEC_URL2.toString(), 1, null));
+        .put(createGadget(FakeProcessor.SPEC_URL.toString(), 0, null))
+        .put(createGadget(FakeProcessor.SPEC_URL2.toString(), 1, null));
     JSONObject input = new JSONObject()
         .put("context", createContext("en", "US"))
         .put("gadgets", gadgets);
@@ -180,12 +133,12 @@ public class JsonRpcHandlerTest {
     boolean second = false;
     for (int i = 0, j = outGadgets.length(); i < j; ++i) {
       JSONObject gadget = outGadgets.getJSONObject(i);
-      if (gadget.getString("url").equals(SPEC_URL.toString())) {
-        assertEquals(SPEC_TITLE, gadget.getString("title"));
+      if (gadget.getString("url").equals(FakeProcessor.SPEC_URL.toString())) {
+        assertEquals(FakeProcessor.SPEC_TITLE, gadget.getString("title"));
         assertEquals(0, gadget.getInt("moduleId"));
         first = true;
       } else {
-        assertEquals(SPEC_TITLE2, gadget.getString("title"));
+        assertEquals(FakeProcessor.SPEC_TITLE2, gadget.getString("title"));
         assertEquals(1, gadget.getInt("moduleId"));
         second = true;
       }
@@ -198,13 +151,13 @@ public class JsonRpcHandlerTest {
   @Test
   public void testMultipleGadgetsWithAnError() throws Exception {
     JSONArray gadgets = new JSONArray()
-        .put(createGadget(SPEC_URL.toString(), 0, null))
-        .put(createGadget(SPEC_URL2.toString(), 1, null));
+        .put(createGadget(FakeProcessor.SPEC_URL.toString(), 0, null))
+        .put(createGadget(FakeProcessor.SPEC_URL2.toString(), 1, null));
     JSONObject input = new JSONObject()
         .put("context", createContext("en", "US"))
         .put("gadgets", gadgets);
 
-    processor.exceptions.put(SPEC_URL2, 
+    processor.exceptions.put(FakeProcessor.SPEC_URL2,
         new ProcessingException("broken", HttpServletResponse.SC_BAD_REQUEST));
 
     JSONObject response = jsonRpcHandler.process(input);
@@ -215,8 +168,8 @@ public class JsonRpcHandlerTest {
     boolean second = false;
     for (int i = 0, j = outGadgets.length(); i < j; ++i) {
       JSONObject gadget = outGadgets.getJSONObject(i);
-      if (gadget.getString("url").equals(SPEC_URL.toString())) {
-        assertEquals(SPEC_TITLE, gadget.getString("title"));
+      if (gadget.getString("url").equals(FakeProcessor.SPEC_URL.toString())) {
+        assertEquals(FakeProcessor.SPEC_TITLE, gadget.getString("title"));
         assertEquals(0, gadget.getInt("moduleId"));
         first = true;
       } else {
@@ -231,50 +184,4 @@ public class JsonRpcHandlerTest {
     assertTrue("Second gadget not returned!", second);
   }
 
-  private static class FakeProcessor extends Processor {
-    protected final Map<Uri, ProcessingException> exceptions = Maps.newHashMap();
-    protected final Map<Uri, String> gadgets = Maps.newHashMap();
-
-    public FakeProcessor() {
-      super(null, null, null, null, null);
-    }
-
-    @Override
-    public Gadget process(GadgetContext context) throws ProcessingException {
-
-      ProcessingException exception = exceptions.get(context.getUrl());
-      if (exception != null) {
-        throw exception;
-      }
-
-      try {
-        GadgetSpec spec = new GadgetSpec(Uri.parse("#"), gadgets.get(context.getUrl()));
-        View view = spec.getView(context.getView());
-        return new Gadget()
-            .setContext(context)
-            .setSpec(spec)
-            .setCurrentView(view);
-      } catch (GadgetException e) {
-        throw new RuntimeException(e);
-      }
-    }
-  }
-
-  protected static class FakeIframeUriManager implements IframeUriManager {
-    protected boolean throwRandomFault = false;
-    protected Uri iframeUrl = Uri.parse("http://example.org/gadgets/foo-does-not-matter");
-
-    protected FakeIframeUriManager() { }
-
-    public Uri makeRenderingUri(Gadget gadget) {
-      if (throwRandomFault) {
-        throw new RuntimeException("BROKEN");
-      }
-      return iframeUrl;
-    }
-
-    public UriStatus validateRenderingUri(Uri uri) {
-      throw new UnsupportedOperationException();
-    }
-  }
 }

Modified: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/spec/GadgetSpecTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/spec/GadgetSpecTest.java?rev=964125&r1=964124&r2=964125&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/spec/GadgetSpecTest.java (original)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/spec/GadgetSpecTest.java Wed Jul 14 18:31:24 2010
@@ -40,7 +40,7 @@ public class GadgetSpecTest extends Asse
     GadgetSpec spec = new GadgetSpec(SPEC_URL, xml);
     assertEquals("title", spec.getModulePrefs().getTitle());
     assertEquals(UserPref.DataType.STRING,
-        spec.getUserPrefs().get(0).getDataType());
+        spec.getUserPrefs().get("foo").getDataType());
     assertEquals("Hello!", spec.getView(GadgetSpec.DEFAULT_VIEW).getContent());
   }
 
@@ -55,7 +55,7 @@ public class GadgetSpecTest extends Asse
     GadgetSpec spec = new GadgetSpec(SPEC_URL, XmlUtil.parse(xml), xml);
     assertEquals("title", spec.getModulePrefs().getTitle());
     assertEquals(UserPref.DataType.STRING,
-        spec.getUserPrefs().get(0).getDataType());
+        spec.getUserPrefs().get("foo").getDataType());
     assertEquals("Hello!", spec.getView(GadgetSpec.DEFAULT_VIEW).getContent());
 
     assertEquals(HashUtil.checksum(xml.getBytes()), spec.getChecksum());

Modified: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/uri/UriManagerTestBase.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/uri/UriManagerTestBase.java?rev=964125&r1=964124&r2=964125&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/uri/UriManagerTestBase.java (original)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/uri/UriManagerTestBase.java Wed Jul 14 18:31:24 2010
@@ -110,15 +110,15 @@ public class UriManagerTestBase {
     expect(gadget.getAllFeatures()).andReturn(features).anyTimes();
     
     // User prefs
-    List<UserPref> specPrefList = Lists.newLinkedList();
+    Map<String,UserPref> specPrefMap = Maps.newLinkedHashMap();
     for (Map.Entry<String, String> specPref : specPrefs.entrySet()) {
       UserPref up = createMock(UserPref.class);
       expect(up.getName()).andReturn(specPref.getKey()).anyTimes();
       expect(up.getDefaultValue()).andReturn(specPref.getValue()).anyTimes();
       replay(up);
-      specPrefList.add(up);
+      specPrefMap.put(up.getName(),up);
     }
-    expect(spec.getUserPrefs()).andReturn(specPrefList).anyTimes();
+    expect(spec.getUserPrefs()).andReturn(specPrefMap).anyTimes();
     UserPrefs ctxPrefs = new UserPrefs(inPrefs);
     expect(context.getUserPrefs()).andReturn(ctxPrefs).anyTimes();
     expect(context.getParameter(Param.REFRESH.getKey())).andReturn(null).anyTimes();