You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shindig.apache.org by li...@apache.org on 2010/08/24 16:33:29 UTC

svn commit: r988569 [2/4] - in /shindig/branches/2.0.x: ./ assembly/ assembly/src/main/assembly/ config/ content/container/ extras/ extras/src/main/java/org/apache/shindig/extras/as/opensocial/service/ extras/src/main/javascript/features-extras/ extras...

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/BaseTagRemoverRewriter.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/BaseTagRemoverRewriter.java?rev=988569&r1=988568&r2=988569&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/BaseTagRemoverRewriter.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/BaseTagRemoverRewriter.java Tue Aug 24 14:33:23 2010
@@ -32,7 +32,7 @@ import java.util.logging.Logger;
  * Simple rewriter that deletes the base tag from the html document.
  */
 public class BaseTagRemoverRewriter implements GadgetRewriter, ResponseRewriter {
-  private static Logger logger = Logger.getLogger(BaseTagRemoverRewriter.class.getName());
+  private static final Logger logger = Logger.getLogger(BaseTagRemoverRewriter.class.getName());
 
   public void rewrite(Gadget gadget, MutableContent mc) {
     Document doc = mc.getDocument();

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ConcatVisitor.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ConcatVisitor.java?rev=988569&r1=988568&r2=988569&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ConcatVisitor.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ConcatVisitor.java Tue Aug 24 14:33:23 2010
@@ -144,7 +144,7 @@ public class ConcatVisitor implements Do
       // with new (concat) URI, immediately ahead of the first elem.
       Element firstElem = sourceBatch.get(0);
       Element elemConcat = (Element)firstElem.cloneNode(true);
-      elemConcat.setAttribute(type.getSrcAttrib(), StringUtils.replace(concatUri.getUri().toString(), "&", "&"));
+      elemConcat.setAttribute(type.getSrcAttrib(), concatUri.getUri().toString().replace("&", "&"));
       firstElem.getParentNode().insertBefore(elemConcat, firstElem);
       
       // Now for all Elements, either A) remove them or B) replace each

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/CssResponseRewriter.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/CssResponseRewriter.java?rev=988569&r1=988568&r2=988569&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/CssResponseRewriter.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/CssResponseRewriter.java Tue Aug 24 14:33:23 2010
@@ -207,7 +207,7 @@ public class CssResponseRewriter impleme
     return new UriMaker(wrapped, config);
   }
   
-  public static class UriMaker {
+  public static final class UriMaker {
     private final ProxyUriManager wrapped;
     private final ContentRewriterFeature.Config config;
     

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/DomWalker.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/DomWalker.java?rev=988569&r1=988568&r2=988569&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/DomWalker.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/DomWalker.java Tue Aug 24 14:33:23 2010
@@ -28,7 +28,6 @@ import org.apache.shindig.gadgets.http.H
 import org.apache.shindig.gadgets.http.HttpResponseBuilder;
 import org.apache.shindig.gadgets.spec.GadgetSpec;
 import org.apache.shindig.gadgets.uri.UriCommon.Param;
-import org.apache.commons.lang.StringUtils;
 
 import org.w3c.dom.Document;
 import org.w3c.dom.Node;

Propchange: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/PipelineDataGadgetRewriter.java
            ('svn:mergeinfo' removed)

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ProxyingContentRewriter.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ProxyingContentRewriter.java?rev=988569&r1=988568&r2=988569&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ProxyingContentRewriter.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ProxyingContentRewriter.java Tue Aug 24 14:33:23 2010
@@ -19,7 +19,6 @@
 package org.apache.shindig.gadgets.rewrite;
 
 import com.google.inject.Inject;
-
 import org.apache.shindig.common.uri.Uri;
 import org.apache.shindig.gadgets.Gadget;
 import org.apache.shindig.gadgets.rewrite.DomWalker.Visitor;
@@ -51,6 +50,9 @@ public class ProxyingContentRewriter ext
     return Arrays.<Visitor>asList(
         new ConcatVisitor.Js(config, concatUriManager),
         new ConcatVisitor.Css(config, concatUriManager),
-        new ProxyingVisitor(config, proxyUriManager));
+        new ProxyingVisitor(config, proxyUriManager,
+                            ProxyingVisitor.Tags.SCRIPT,
+                            ProxyingVisitor.Tags.STYLESHEET,
+                            ProxyingVisitor.Tags.EMBEDDED_IMAGES));
   }
 }

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ProxyingVisitor.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ProxyingVisitor.java?rev=988569&r1=988568&r2=988569&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ProxyingVisitor.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ProxyingVisitor.java Tue Aug 24 14:33:23 2010
@@ -20,6 +20,7 @@ package org.apache.shindig.gadgets.rewri
 
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Lists;
+import org.apache.commons.lang.StringUtils;
 import org.apache.shindig.common.Pair;
 import org.apache.shindig.common.uri.Uri;
 import org.apache.shindig.common.uri.Uri.UriException;
@@ -29,6 +30,7 @@ import org.w3c.dom.Attr;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -43,33 +45,75 @@ public class ProxyingVisitor implements 
   private static final Logger logger = Logger.getLogger(
       ProxyUriManager.class.getName());
 
-  public final static Map<String, String> RESOURCE_TAGS =
-    ImmutableMap.of(
-        "body", "background",
-        "img", "src",
-        "input", "src",
-        "link", "href",
-        "script", "src");
+  /**
+   * Enum for resource tags and associated attributes that should be
+   * proxied through shindig.
+   */
+  public enum Tags {
+    // Javascript resources requested by the current page.
+    SCRIPT(ImmutableMap.of("script", "src")),
+
+    // Css stylesheet resources requested by the current page.
+    STYLESHEET(ImmutableMap.of("link", "href")),
+
+    // Other embedded resources requested on the same page.
+    EMBEDDED_IMAGES(ImmutableMap.of("body", "background",
+                                    "img", "src",
+                                    "input", "src")),
+
+    // All resources that possibly be rewritten. Useful for testing.
+    ALL_RESOURCES(ImmutableMap.<String, String>builder()
+        .putAll(SCRIPT.getResourceTags())
+        .putAll(STYLESHEET.getResourceTags())
+        .putAll(EMBEDDED_IMAGES.getResourceTags())
+        .build());
+
+    private Map<String, String> resourceTags;
+    private Tags(Map<String, String> resourceTags) {
+      this.resourceTags = resourceTags;
+    }
 
+    public Map<String, String> getResourceTags() {
+      return resourceTags;
+    }
+  }
+
+  // Map of tag name to attribute of resources to rewrite.
+  private final Map<String, String> resourceTags;
   private final ContentRewriterFeature.Config featureConfig;
   private final ProxyUriManager uriManager;
 
   public ProxyingVisitor(ContentRewriterFeature.Config featureConfig,
-                              ProxyUriManager uriManager) {
+                         ProxyUriManager uriManager,
+                         Tags... resourceTags) {
     this.featureConfig = featureConfig;
     this.uriManager = uriManager;
+
+    this.resourceTags = new HashMap<String, String>();
+    for (Tags r : resourceTags) {
+      this.resourceTags.putAll(r.getResourceTags());
+    }
   }
 
   public VisitStatus visit(Gadget gadget, Node node) throws RewritingException {
     String nodeName = node.getNodeName().toLowerCase();
     if (node.getNodeType() == Node.ELEMENT_NODE &&
-        RESOURCE_TAGS.containsKey(nodeName) &&
+        resourceTags.containsKey(nodeName) &&
         featureConfig.shouldRewriteTag(nodeName)) {
+      if (nodeName.equals("link")) {
+        // Rewrite link only when it is for css.
+        String type = ((Element)node).getAttribute("type");
+        String rel = ((Element)node).getAttribute("rel");
+        if (!"stylesheet".equalsIgnoreCase(rel) || !"text/css".equalsIgnoreCase(type)) {
+          return VisitStatus.BYPASS;
+        }
+      }
+
       Attr attr = (Attr)node.getAttributes().getNamedItem(
-          RESOURCE_TAGS.get(nodeName));
+          resourceTags.get(nodeName));
       if (attr != null) {
         String urlValue = attr.getValue();
-        if (featureConfig.shouldRewriteURL(urlValue)) {
+        if (!StringUtils.isEmpty(urlValue) && featureConfig.shouldRewriteURL(urlValue)) {
           return VisitStatus.RESERVE_NODE;
         }
       }
@@ -87,7 +131,7 @@ public class ProxyingVisitor implements 
       }
       Element element = (Element)proxyPair.one;
       String nodeName = element.getNodeName().toLowerCase();
-      element.setAttribute(RESOURCE_TAGS.get(nodeName), proxyPair.two.toString());
+      element.setAttribute(resourceTags.get(nodeName), proxyPair.two.toString());
       mutated = true;
     }
     
@@ -103,7 +147,7 @@ public class ProxyingVisitor implements 
     for (Node node : nodes) {
       Element element = (Element)node;
       String nodeName = node.getNodeName().toLowerCase();
-      String uriStr = element.getAttribute(RESOURCE_TAGS.get(nodeName)).trim();
+      String uriStr = element.getAttribute(resourceTags.get(nodeName)).trim();
       try {
         ProxyUriManager.ProxyUri proxiedUri = new ProxyUriManager.ProxyUri(
             gadget, Uri.parse(uriStr));

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/image/BaseOptimizer.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/image/BaseOptimizer.java?rev=988569&r1=988568&r2=988569&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/image/BaseOptimizer.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/image/BaseOptimizer.java Tue Aug 24 14:33:23 2010
@@ -25,7 +25,6 @@ import org.apache.shindig.gadgets.http.H
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Maps;
 import com.google.common.base.Objects;
-import com.google.common.base.Preconditions;
 
 import java.awt.image.BufferedImage;
 import java.io.ByteArrayOutputStream;

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandler.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandler.java?rev=988569&r1=988568&r2=988569&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandler.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandler.java Tue Aug 24 14:33:23 2010
@@ -20,25 +20,14 @@ package org.apache.shindig.gadgets.servl
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.inject.Inject;
 
-import org.apache.shindig.auth.SecurityToken;
-import org.apache.shindig.auth.SecurityTokenCodec;
 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.process.Processor;
-import org.apache.shindig.gadgets.spec.Feature;
 import org.apache.shindig.gadgets.spec.GadgetSpec;
-import org.apache.shindig.gadgets.spec.LinkSpec;
-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.spec.UserPref.EnumValuePair;
-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;
@@ -47,6 +36,7 @@ import org.apache.shindig.protocol.Servi
 import org.apache.shindig.protocol.conversion.BeanDelegator;
 import org.apache.shindig.protocol.conversion.BeanFilter;
 
+import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
@@ -65,63 +55,29 @@ public class GadgetsHandler {
   @VisibleForTesting
   static final String FAILURE_TOKEN = "Failed to get gadget token.";
 
-  private static final Set<String> DEFAULT_METADATA_FIELDS =
-      ImmutableSet.of("iframeUrl", "userPrefs.*", "modulePrefs.*", "views.*", "token");
+  private static final List<String> DEFAULT_METADATA_FIELDS =
+      ImmutableList.of("iframeUrl", "userPrefs.*", "modulePrefs.*", "views.*", "token");
+
+  private static final List<String> DEFAULT_TOKEN_FIELDS = ImmutableList.of("token");
 
   protected final ExecutorService executor;
-  protected final Processor processor;
-  protected final IframeUriManager iframeUriManager;
-  protected final SecurityTokenCodec securityTokenCodec;
+  protected final GadgetsHandlerService handlerService;
 
-  protected final BeanDelegator beanDelegator;
   protected final BeanFilter beanFilter;
-
-  // Map shindig data class to API interfaces
-  @VisibleForTesting
-  static final Map<Class<?>, Class<?>> apiClasses =
-      new ImmutableMap.Builder<Class<?>, Class<?>>()
-          .put(BaseResponseData.class, GadgetsHandlerApi.BaseResponse.class)
-          .put(MetadataResponseData.class, GadgetsHandlerApi.MetadataResponse.class)
-          .put(TokenResponseData.class, GadgetsHandlerApi.TokenResponse.class)
-          .put(View.class, GadgetsHandlerApi.View.class)
-          .put(UserPref.class, GadgetsHandlerApi.UserPref.class)
-          .put(EnumValuePair.class, GadgetsHandlerApi.EnumValuePair.class)
-          .put(ModulePrefs.class, GadgetsHandlerApi.ModulePrefs.class)
-          .put(Feature.class, GadgetsHandlerApi.Feature.class)
-          .put(LinkSpec.class, GadgetsHandlerApi.LinkSpec.class)
-          // Enums
-          .put(View.ContentType.class, GadgetsHandlerApi.ViewContentType.class)
-          .put(UserPref.DataType.class, GadgetsHandlerApi.UserPrefDataType.class)
-          .build();
-
-  // Provide mapping for internal enums to api enums
-  @VisibleForTesting
-  static final Map<Enum<?>, Enum<?>> enumConversionMap =
-      new ImmutableMap.Builder<Enum<?>, Enum<?>>()
-          // View.ContentType mapping
-          .putAll(BeanDelegator.createDefaultEnumMap(View.ContentType.class,
-              GadgetsHandlerApi.ViewContentType.class))
-          // UserPref.DataType mapping
-          .putAll(BeanDelegator.createDefaultEnumMap(UserPref.DataType.class,
-              GadgetsHandlerApi.UserPrefDataType.class))
-          .build();
+  protected final BeanDelegator beanDelegator;
 
   @Inject
-  public GadgetsHandler(ExecutorService executor, Processor processor,
-      IframeUriManager iframeUriManager, SecurityTokenCodec securityTokenCodec,
-      BeanFilter beanFilter) {
+  public GadgetsHandler(ExecutorService executor, GadgetsHandlerService handlerService,
+                        BeanFilter beanFilter) {
     this.executor = executor;
-    this.processor = processor;
-    this.iframeUriManager = iframeUriManager;
-    this.securityTokenCodec = securityTokenCodec;
+    this.handlerService = handlerService;
     this.beanFilter = beanFilter;
 
-    // TODO: maybe make this injectable
-    this.beanDelegator = new BeanDelegator(apiClasses, enumConversionMap);
+    this.beanDelegator = new BeanDelegator();
   }
 
   @Operation(httpMethods = {"POST", "GET"}, path = "metadata.get")
-  public Map<String, GadgetsHandlerApi.MetadataResponse> metadata(BaseRequestItem request)
+  public Map<String, GadgetsHandlerApi.BaseResponse> metadata(BaseRequestItem request)
       throws ProtocolException {
     return new AbstractExecutor<GadgetsHandlerApi.MetadataResponse>() {
       @Override
@@ -133,7 +89,7 @@ public class GadgetsHandler {
   }
 
   @Operation(httpMethods = {"POST", "GET"}, path = "token.get")
-  public Map<String, GadgetsHandlerApi.TokenResponse> token(BaseRequestItem request)
+  public Map<String, GadgetsHandlerApi.BaseResponse> token(BaseRequestItem request)
       throws ProtocolException {
     return new AbstractExecutor<GadgetsHandlerApi.TokenResponse>() {
       @Override
@@ -158,7 +114,7 @@ public class GadgetsHandler {
 
   private abstract class AbstractExecutor<R extends GadgetsHandlerApi.BaseResponse> {
     @SuppressWarnings("unchecked")
-    public Map<String, R> execute(BaseRequestItem request) {
+    public Map<String, GadgetsHandlerApi.BaseResponse> execute(BaseRequestItem request) {
       Set<String> gadgetUrls = ImmutableSet.copyOf(request.getListParameter("ids"));
       if (gadgetUrls.isEmpty()) {
         return ImmutableMap.of();
@@ -170,12 +126,12 @@ public class GadgetsHandler {
         completionService.submit(job);
       }
 
-      ImmutableMap.Builder<String, R> builder = ImmutableMap.builder();
+      ImmutableMap.Builder<String, GadgetsHandlerApi.BaseResponse> builder = ImmutableMap.builder();
       for (int numJobs = gadgetUrls.size(); numJobs > 0; numJobs--) {
         R response;
         try {
           response = completionService.take().get();
-          builder.put(response.getUrl(), response);
+          builder.put(response.getUrl().toString(), response);
         } catch (InterruptedException e) {
           throw new ProtocolException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
               "Processing interrupted.", e);
@@ -187,10 +143,10 @@ public class GadgetsHandler {
           RpcException cause = (RpcException) e.getCause();
           GadgetContext context = cause.getContext();
           if (context != null) {
-            String url = context.getUrl().toString();
-            R errorResponse =
-                (R) beanDelegator.createDelegator(new BaseResponseData(url, cause.getMessage()));
-            builder.put(url, errorResponse);
+            Uri url = context.getUrl();
+            GadgetsHandlerApi.BaseResponse errorResponse =
+                handlerService.createBaseResponse(url, cause.getMessage());
+            builder.put(url.toString(), errorResponse);
           }
         }
       }
@@ -203,23 +159,14 @@ public class GadgetsHandler {
   // Hook to override in sub-class.
   protected Callable<GadgetsHandlerApi.MetadataResponse> createMetadataJob(String url,
       BaseRequestItem request) {
-    final GadgetContext context = new MetadataGadgetContext(url, request);
-    final Set<String> fields =
-        beanFilter.processBeanFields(request.getFields(DEFAULT_METADATA_FIELDS));
+    final MetadataRequestData metadataRequest = new MetadataRequestData(url, request);
     return new Callable<GadgetsHandlerApi.MetadataResponse>() {
       public GadgetsHandlerApi.MetadataResponse call() throws Exception {
         try {
-          Gadget gadget = processor.process(context);
-          String iframeUrl =
-              fields.contains("iframeurl") ? iframeUriManager.makeRenderingUri(gadget).toString()
-                  : null;
-          MetadataResponseData response =
-              new MetadataResponseData(context.getUrl().toString(), gadget.getSpec(), iframeUrl);
-          return (GadgetsHandlerApi.MetadataResponse) beanFilter.createFilteredBean(beanDelegator
-              .createDelegator(response), fields);
+          return handlerService.getMetadata(metadataRequest);
         } catch (Exception e) {
-          // Note: this error message is publicly visible in JSON-RPC response.
-          throw new RpcException(context, FAILURE_METADATA, e);
+          sendError(metadataRequest.getUrl(), e, FAILURE_METADATA);
+          return null;
         }
       }
     };
@@ -228,63 +175,87 @@ public class GadgetsHandler {
   // Hook to override in sub-class.
   protected Callable<GadgetsHandlerApi.TokenResponse> createTokenJob(String url,
       BaseRequestItem request) {
-    final TokenGadgetContext context = new TokenGadgetContext(url, request);
-    final Set<String> fields =
-        beanFilter.processBeanFields(request.getFields(DEFAULT_METADATA_FIELDS));
+    final TokenRequestData tokenRequest = new TokenRequestData(url, request);
     return new Callable<GadgetsHandlerApi.TokenResponse>() {
       public GadgetsHandlerApi.TokenResponse call() throws Exception {
         try {
-          String token = securityTokenCodec.encodeToken(context.getToken());
-          TokenResponseData response = new TokenResponseData(context.getUrl().toString(), token);
-          return (GadgetsHandlerApi.TokenResponse) beanFilter.createFilteredBean(beanDelegator
-              .createDelegator(response), fields);
+          return handlerService.getToken(tokenRequest);
         } catch (Exception e) {
-          // Note: this error message is publicly visible in JSON-RPC response.
-          throw new RpcException(context, FAILURE_TOKEN, e);
+          sendError(tokenRequest.getUrl(), e, FAILURE_TOKEN);
+          return null;
         }
       }
     };
   }
 
+  private void sendError(final Uri url, Exception e, String msg)
+      throws RpcException {
+    GadgetContext context = new GadgetContext() {
+      @Override
+      public Uri getUrl() { return url; }
+    };
+    // Note: this error message is publicly visible in JSON-RPC response.
+    throw new RpcException(context, msg, e);
+  }
+
   /**
    * Gadget context classes used to translate JSON BaseRequestItem into a more
    * meaningful model objects that Java can work with.
    */
-
-  private abstract class AbstractGadgetContext extends GadgetContext {
+  private abstract class AbstractRequest implements GadgetsHandlerApi.BaseRequest {
     protected final Uri uri;
     protected final String container;
+    protected final List<String> fields;
     protected final BaseRequestItem request;
 
-    public AbstractGadgetContext(String url, BaseRequestItem request) {
+    public AbstractRequest(String url, BaseRequestItem request, List<String> defaultFields) {
       this.uri = Uri.parse(Preconditions.checkNotNull(url));
       this.request = Preconditions.checkNotNull(request);
       this.container = Preconditions.checkNotNull(request.getParameter("container"));
+      this.fields = processFields(request, defaultFields);
     }
 
-    @Override
     public Uri getUrl() {
       return uri;
     }
 
-    @Override
     public String getContainer() {
       return container;
     }
 
-    @Override
-    public RenderingContext getRenderingContext() {
-      return RenderingContext.METADATA;
+    public List<String> getFields() {
+      return fields;
+    }
+
+    private List<String> processFields(BaseRequestItem request, List<String> defaultList) {
+      List<String> value = request.getListParameter(BaseRequestItem.FIELDS);
+      return ((value == null || value.size() == 0) ? defaultList : value);
     }
   }
 
-  protected class MetadataGadgetContext extends AbstractGadgetContext {
+
+  protected class TokenRequestData extends AbstractRequest
+      implements GadgetsHandlerApi.TokenRequest {
+
+    public TokenRequestData(String url, BaseRequestItem request) {
+      super(url, request, DEFAULT_TOKEN_FIELDS);
+    }
+
+    public GadgetsHandlerApi.TokenData getToken() {
+      return beanDelegator.createDelegator(
+          request.getToken(), GadgetsHandlerApi.TokenData.class);
+    }
+  }
+
+
+  protected class MetadataRequestData extends AbstractRequest
+      implements GadgetsHandlerApi.MetadataRequest {
     protected final Locale locale;
     protected final boolean ignoreCache;
     protected final boolean debug;
 
-    public MetadataGadgetContext(String url, BaseRequestItem request) {
-      super(url, request);
+    public MetadataRequestData(String url, BaseRequestItem request) {
+      super(url, request, DEFAULT_METADATA_FIELDS);
       String lang = request.getParameter("language");
       String country = request.getParameter("country");
       this.locale =
@@ -294,120 +265,29 @@ public class GadgetsHandler {
       this.debug = Boolean.valueOf(request.getParameter("debug"));
     }
 
-    @Override
     public int getModuleId() {
       return 1; // TODO calculate?
     }
 
-    @Override
     public Locale getLocale() {
       return locale;
     }
 
-    @Override
     public boolean getIgnoreCache() {
       return ignoreCache;
     }
 
-    @Override
     public boolean getDebug() {
       return debug;
     }
 
-    @Override
     public String getView() {
       return request.getParameter("view", "default");
     }
 
-    @Override
-    public SecurityToken getToken() {
-      return request.getToken();
-    }
-  }
-
-  protected class TokenGadgetContext extends AbstractGadgetContext {
-    public TokenGadgetContext(String url, BaseRequestItem request) {
-      super(url, request);
-    }
-
-    @Override
-    public SecurityToken getToken() {
-      return request.getToken();
-    }
-  }
-
-  /**
-   * Response classes to represent data structure returned in JSON to common
-   * container JS. They must be public for reflection to work.
-   */
-
-  public static class BaseResponseData {
-    private final String url;
-    private final String error;
-
-    // Call this to indicate an error.
-    public BaseResponseData(String url, String error) {
-      this.url = url;
-      this.error = error;
-    }
-
-    // Have sub-class call this to indicate a success response.
-    protected BaseResponseData(String url) {
-      this(url, null);
-    }
-
-    public String getUrl() {
-      return url;
-    }
-
-    public String getError() {
-      return error;
+    public GadgetsHandlerApi.TokenData getToken() {
+      return beanDelegator.createDelegator(
+        request.getToken(), GadgetsHandlerApi.TokenData.class);
     }
   }
-
-  public static class MetadataResponseData extends BaseResponseData {
-    private final GadgetSpec spec;
-    private final String iframeUrl;
-
-    public MetadataResponseData(String url, GadgetSpec spec, String iframeUrl) {
-      super(url);
-      this.spec = spec;
-      this.iframeUrl = iframeUrl;
-    }
-
-    public String getIframeUrl() {
-      return iframeUrl;
-    }
-
-    public String getChecksum() {
-      return spec.getChecksum();
-    }
-
-    public ModulePrefs getModulePrefs() {
-      return spec.getModulePrefs();
-    }
-
-    public Map<String, UserPref> getUserPrefs() {
-      return spec.getUserPrefs();
-    }
-
-    public Map<String, View> getViews() {
-      return spec.getViews();
-    }
-  }
-
-
-  public static class TokenResponseData extends BaseResponseData {
-    private final String token;
-
-    public TokenResponseData(String url, String token) {
-      super(url);
-      this.token = token;
-    }
-
-    public String getToken() {
-      return token;
-    }
-  }
-
 }

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerApi.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerApi.java?rev=988569&r1=988568&r2=988569&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerApi.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerApi.java Tue Aug 24 14:33:23 2010
@@ -19,10 +19,11 @@
 package org.apache.shindig.gadgets.servlet;
 
 import org.apache.shindig.common.uri.Uri;
-import org.apache.shindig.protocol.conversion.BeanFilter.Required;
+import org.apache.shindig.protocol.conversion.BeanFilter.Unfiltered;
 // Keep imports clean, so it is clear what is used by API
 
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 
 /**
@@ -33,10 +34,33 @@ import java.util.Map;
  */
 public class GadgetsHandlerApi {
 
+  public interface BaseRequest {
+    public Uri getUrl();
+    public String getContainer();
+    public List<String> getFields();
+  }
+
+  public interface MetadataRequest extends BaseRequest {
+    public Locale getLocale();
+    public boolean getIgnoreCache();
+    public boolean getDebug();
+    public String getView();
+    public TokenData getToken();
+  }
+
+  public interface TokenData {
+    public String getOwnerId();
+    public String getViewerId();
+  }
+
+  public interface TokenRequest extends BaseRequest {
+    public TokenData getToken();
+  }
+
   public interface BaseResponse {
-    @Required
-    public String getUrl();
-    @Required
+    @Unfiltered
+    public Uri getUrl();
+    @Unfiltered
     public String getError();
   }
 

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/JsonRpcHandler.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/JsonRpcHandler.java?rev=988569&r1=988568&r2=988569&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/JsonRpcHandler.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/JsonRpcHandler.java Tue Aug 24 14:33:23 2010
@@ -26,9 +26,11 @@ import org.apache.shindig.gadgets.spec.L
 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.spec.Feature;
 import org.apache.shindig.gadgets.uri.IframeUriManager;
 
 import com.google.common.collect.Lists;
+import com.google.common.collect.Multimap;
 import com.google.inject.Inject;
 
 import org.json.JSONArray;
@@ -172,7 +174,23 @@ public class JsonRpcHandler {
         // Features.
         Set<String> feats = prefs.getFeatures().keySet();
         String[] features = feats.toArray(new String[feats.size()]);
-
+        
+        // Feature details
+        // The following renders an object containing feature details, of the form 
+        //   { <featureName>*: { "required": <boolean>, "parameters": { <paramName>*: <string> } } }
+        JSONObject featureDetailList = new JSONObject();
+        for (Feature featureSpec : prefs.getFeatures().values()) {
+          JSONObject featureDetail = new JSONObject();
+          featureDetail.put("required", featureSpec.getRequired());
+          JSONObject featureParameters = new JSONObject();
+          featureDetail.put("parameters", featureParameters);
+          Multimap<String, String> featureParams = featureSpec.getParams();
+          for (String paramName : featureParams.keySet()) {
+            featureParameters.put(paramName, featureParams.get(paramName));
+          }
+          featureDetailList.put(featureSpec.getName(), featureDetail);
+        }
+        
         // Links
         JSONObject links = new JSONObject();
         for (LinkSpec link : prefs.getLinks().values()) {
@@ -202,6 +220,7 @@ public class JsonRpcHandler {
                   .put("titleUrl", prefs.getTitleUrl().toString())
                   .put("views", views)
                   .put("features", features)
+                  .put("featureDetails", featureDetailList)
                   .put("userPrefs", userPrefs)
                   .put("links", links)
 

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/MakeRequestHandler.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/MakeRequestHandler.java?rev=988569&r1=988568&r2=988569&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/MakeRequestHandler.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/MakeRequestHandler.java Tue Aug 24 14:33:23 2010
@@ -123,7 +123,7 @@ public class MakeRequestHandler {
       throw new GadgetException(GadgetException.Code.INVALID_PARAMETER,
           Param.URL.getKey() + " parameter is missing.", HttpResponse.SC_BAD_REQUEST);
     }
-    
+
     Uri url = null;
     try {
       url = ServletUtil.validateUrl(Uri.parse(urlStr));
@@ -137,7 +137,7 @@ public class MakeRequestHandler {
         .setContainer(getContainer(request));
 
     setPostData(request,req);
-    
+
     String headerData = getParameter(request, HEADERS_PARAM, "");
     if (headerData.length() > 0) {
       String[] headerList = StringUtils.split(headerData, '&');
@@ -211,7 +211,7 @@ public class MakeRequestHandler {
       // that we must always honor. For now, we return SC_BAD_REQUEST since
       // the encoding parameter could theoretically be anything.
       throw new GadgetException(Code.HTML_PARSE_ERROR, e, HttpResponse.SC_BAD_REQUEST);
-    }    
+    }
   }
 
   /**
@@ -266,35 +266,41 @@ public class MakeRequestHandler {
   private String processFeed(String url, HttpServletRequest req, String xml)
       throws GadgetException {
     boolean getSummaries = Boolean.parseBoolean(getParameter(req, GET_SUMMARIES_PARAM, "false"));
-    int numEntries = Integer.parseInt(getParameter(req, NUM_ENTRIES_PARAM, DEFAULT_NUM_ENTRIES));
+    int numEntries;
+    try {
+      numEntries = Integer.valueOf(getParameter(req, NUM_ENTRIES_PARAM, DEFAULT_NUM_ENTRIES));
+    } catch (NumberFormatException e) {
+      throw new GadgetException(GadgetException.Code.INVALID_PARAMETER,
+          "numEntries paramater is not a number", HttpResponse.SC_BAD_REQUEST);
+    }
     return new FeedProcessor().process(url, xml, getSummaries, numEntries).toString();
   }
-  
+
   /**
    * Extracts the container name from the request.
    */
   @SuppressWarnings("deprecation")
-  static String getContainer(HttpServletRequest request) {
+  protected static String getContainer(HttpServletRequest request) {
     String container = request.getParameter(Param.CONTAINER.getKey());
     if (container == null) {
       container = request.getParameter(Param.SYND.getKey());
     }
     return container != null ? container : ContainerConfig.DEFAULT_CONTAINER;
   }
-  
+
   /**
    * getParameter helper method, returning default value if param not present.
    */
-  static String getParameter(HttpServletRequest request, String key, String defaultValue) {
+  protected static String getParameter(HttpServletRequest request, String key, String defaultValue) {
     String ret = request.getParameter(key);
     return ret != null ? ret : defaultValue;
   }
-  
+
   /**
    * Sets cache control headers for the response.
    */
   @SuppressWarnings("boxing")
-  static void setResponseHeaders(HttpServletRequest request,
+  protected static void setResponseHeaders(HttpServletRequest request,
       HttpServletResponse response, HttpResponse results) throws GadgetException {
     int refreshInterval = 0;
     if (results.isStrictNoCache() || "1".equals(request.getParameter(UriCommon.Param.NO_CACHE.getKey()))) {
@@ -304,16 +310,16 @@ public class MakeRequestHandler {
         refreshInterval =  Integer.valueOf(request.getParameter(UriCommon.Param.REFRESH.getKey()));
       } catch (NumberFormatException nfe) {
         throw new GadgetException(GadgetException.Code.INVALID_PARAMETER,
-            "refresh parameter is not a number");
+            "refresh parameter is not a number", HttpResponse.SC_BAD_REQUEST);
       }
     } else {
       refreshInterval = Math.max(60 * 60, (int)(results.getCacheTtl() / 1000L));
     }
     HttpUtil.setCachingHeaders(response, refreshInterval, false);
-    
+
     // Always set Content-Disposition header as XSS prevention mechanism.
     response.setHeader("Content-Disposition", "attachment;filename=p.txt");
-    
+
     if (response.getContentType() == null) {
       response.setContentType("application/octet-stream");
     }

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/ProxyHandler.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/ProxyHandler.java?rev=988569&r1=988568&r2=988569&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/ProxyHandler.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/ProxyHandler.java Tue Aug 24 14:33:23 2010
@@ -20,9 +20,9 @@ package org.apache.shindig.gadgets.servl
 
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
-
-import org.apache.commons.io.IOUtils;
+import com.google.inject.name.Named;
 import org.apache.commons.lang.StringUtils;
+import org.apache.commons.io.IOUtils;
 import org.apache.shindig.common.uri.Uri;
 import org.apache.shindig.gadgets.GadgetException;
 import org.apache.shindig.gadgets.http.HttpRequest;
@@ -46,15 +46,19 @@ public class ProxyHandler {
   // TODO: parameterize these.
   static final Integer LONG_LIVED_REFRESH = (365 * 24 * 60 * 60);  // 1 year
   static final Integer DEFAULT_REFRESH = (60 * 60);                // 1 hour
-  
+
   private final RequestPipeline requestPipeline;
   private final ResponseRewriterRegistry contentRewriterRegistry;
+  protected final boolean remapInternalServerError;
 
   @Inject
   public ProxyHandler(RequestPipeline requestPipeline,
-                      ResponseRewriterRegistry contentRewriterRegistry) {
+                      ResponseRewriterRegistry contentRewriterRegistry,
+                      @Named("shindig.proxy.remapInternalServerError")
+                      Boolean remapInternalServerError) {
     this.requestPipeline = requestPipeline;
     this.contentRewriterRegistry = contentRewriterRegistry;
+    this.remapInternalServerError = remapInternalServerError;
   }
 
   /**
@@ -73,11 +77,11 @@ public class ProxyHandler {
     HttpRequest rcr = buildHttpRequest(proxyUri, proxyUri.getResource());
     if (rcr == null) {
       throw new GadgetException(GadgetException.Code.INVALID_PARAMETER,
-          "No url parameter in request", HttpResponse.SC_BAD_REQUEST);      
+          "No url parameter in request", HttpResponse.SC_BAD_REQUEST);
     }
-    
+
     HttpResponse results = requestPipeline.execute(rcr);
-    
+
     if (results.isError()) {
       // Error: try the fallback. Particularly useful for proxied images.
       Uri fallbackUri = proxyUri.getFallbackUri();
@@ -86,63 +90,50 @@ public class ProxyHandler {
         results = requestPipeline.execute(fallbackRcr);
       }
     }
-    
+
     if (contentRewriterRegistry != null) {
       try {
         results = contentRewriterRegistry.rewriteHttpResponse(rcr, results);
       } catch (RewritingException e) {
-        throw new GadgetException(GadgetException.Code.INTERNAL_SERVER_ERROR, e,
-            e.getHttpStatusCode());
+        // Throw exception if the RETURN_ORIGINAL_CONTENT_ON_ERROR param is not
+        // set to "true" or the error is irrecoverable from.
+        if (!proxyUri.shouldReturnOrigOnErr() || !isRecoverable(results)) {
+          throw new GadgetException(GadgetException.Code.INTERNAL_SERVER_ERROR, e,
+              e.getHttpStatusCode());
+        }
       }
     }
-    
+
     HttpResponseBuilder response = new HttpResponseBuilder(results);
-    
+    response.clearAllHeaders();
+
     try {
       ServletUtil.setCachingHeaders(response,
           proxyUri.translateStatusRefresh(LONG_LIVED_REFRESH, DEFAULT_REFRESH), false);
     } catch (GadgetException gex) {
       return ServletUtil.errorResponse(gex);
     }
-    
-    UriUtils.copyResponseHeadersAndStatusCode(results, response, true, true,
+
+    UriUtils.copyResponseHeadersAndStatusCode(results, response, remapInternalServerError, true,
         DisallowedHeaders.CACHING_DIRECTIVES,  // Proxy sets its own caching headers.
         DisallowedHeaders.CLIENT_STATE_DIRECTIVES,  // Overridden or irrelevant to proxy.
         DisallowedHeaders.OUTPUT_TRANSFER_DIRECTIVES
         );
-    
+
     // Set Content-Type and Content-Disposition. Do this after copy results headers,
     // in order to prevent those from overwriting the correct values.
     setResponseContentHeaders(response, results);
-    
-    response.setHeader("Content-Type", getContentType(rcr, response));
-    
+
+    UriUtils.maybeRewriteContentType(rcr, response);
+
     // TODO: replace this with streaming APIs when ready
     ByteArrayOutputStream baos = new ByteArrayOutputStream();
     IOUtils.copy(results.getResponse(), baos);
     response.setResponse(baos.toByteArray());
     return response.create();
   }
-  
-  private String getContentType(HttpRequest rcr, HttpResponseBuilder results) {
-    String contentType = results.getHeader("Content-Type");
-    if (!StringUtils.isEmpty(rcr.getRewriteMimeType())) {
-      String requiredType = rcr.getRewriteMimeType();
-      // Use a 'Vary' style check on the response
-      if (requiredType.endsWith("/*") &&
-          !StringUtils.isEmpty(contentType)) {
-        requiredType = requiredType.substring(0, requiredType.length() - 2);
-        if (!contentType.toLowerCase().startsWith(requiredType.toLowerCase())) {
-          contentType = requiredType;
-        }
-      } else {
-        contentType = requiredType;
-      }
-    }
-    return contentType;
-  }
 
-  private void setResponseContentHeaders(HttpResponseBuilder response, HttpResponse results) {
+  protected void setResponseContentHeaders(HttpResponseBuilder response, HttpResponse results) {
     // We're skipping the content disposition header for flash due to an issue with Flash player 10
     // This does make some sites a higher value phishing target, but this can be mitigated by
     // additional referer checks.
@@ -154,4 +145,19 @@ public class ProxyHandler {
       response.setHeader("Content-Type", "application/octet-stream");
     }
   }
+
+  /**
+   * Returns true in case the error encountered while rewriting the content
+   * is recoverable. The rationale behind it is that errors should be thrown
+   * only in case of serious grave errors (defined to be un recoverable).
+   * It should always be preferred to handle errors and return the original
+   * content at least.
+   *
+   * @param results The result of rewriting.
+   * @return True if the error is recoverable, false otherwise.
+   */
+  public boolean isRecoverable(HttpResponse results) {
+    return !(StringUtils.isEmpty(results.getResponseAsString()) &&
+             results.getHeaders() == null);
+  }
 }

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/ProxyServlet.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/ProxyServlet.java?rev=988569&r1=988568&r2=988569&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/ProxyServlet.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/ProxyServlet.java Tue Aug 24 14:33:23 2010
@@ -18,7 +18,6 @@
  */
 package org.apache.shindig.gadgets.servlet;
 
-import com.google.common.base.Preconditions;
 import org.apache.shindig.common.servlet.InjectedServlet;
 import org.apache.shindig.common.uri.Uri;
 import org.apache.shindig.common.uri.UriBuilder;

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/ServletUtil.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/ServletUtil.java?rev=988569&r1=988568&r2=988569&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/ServletUtil.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/ServletUtil.java Tue Aug 24 14:33:23 2010
@@ -32,26 +32,49 @@ import org.apache.shindig.gadgets.http.H
 import org.apache.shindig.gadgets.http.HttpResponse;
 import org.apache.shindig.gadgets.http.HttpResponseBuilder;
 
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.Enumeration;
 import java.util.Map;
 
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
 public class ServletUtil {
   public static final String REMOTE_ADDR_KEY = "RemoteAddress";
   public static final String DATA_URI_KEY = "dataUri";
-  
+
+  private ServletUtil() {}
+
+  /**
+   * Returns an HttpRequest object encapsulating the servlet request.
+   * NOTE: Request parameters are not explicitly taken care of, instead we copy
+   * the InputStream and query parameters separately.
+   *
+   * @param servletReq The http servlet request.
+   * @return An HttpRequest object with all the information provided by the
+   *   servlet request.
+   * @throws IOException In case of errors.
+   */
   public static HttpRequest fromHttpServletRequest(HttpServletRequest servletReq) throws IOException {
     HttpRequest req = new HttpRequest(new UriBuilder(servletReq).toUri());
+
     Enumeration<?> headerNames = servletReq.getHeaderNames();
     while (headerNames.hasMoreElements()) {
-      String headerName = (String)headerNames.nextElement();
-      req.addHeader(headerName, servletReq.getHeader(headerName));
+      Object obj = headerNames.nextElement();
+      if (obj instanceof String) {
+        String headerName = (String) obj;
+
+        Enumeration<?> headerValues = servletReq.getHeaders(headerName);
+        while (headerValues.hasMoreElements()) {
+          obj = headerValues.nextElement();
+          if (obj instanceof String) {
+            req.addHeader(headerName, (String) obj);
+          }
+        }
+      }
     }
+
     req.setMethod(servletReq.getMethod());
     if ("POST".equalsIgnoreCase(req.getMethod())) {
       req.setPostBody(servletReq.getInputStream());
@@ -158,9 +181,9 @@ public class ServletUtil {
     String contentType = response.getHeader("Content-Type");
     if (contentType == null) {
       contentType = "";
+    } else if (contentType.contains(";")) {
+      contentType = StringUtils.split(contentType, ';')[0].trim();
     }
-    contentType = contentType.split(";")[0].trim();
- 
     // First and most importantly, emit dataUri.
     // Do so in streaming fashion, to avoid needless buffering.
     ByteArrayOutputStream os = new ByteArrayOutputStream();
@@ -193,9 +216,9 @@ public class ServletUtil {
       }
       first = false;
       pw.write("'");
-      pw.write(StringEscapeUtils.escapeJavaScript(metaEntry.getKey()).replaceAll("'", "\\'"));
+      pw.write(StringEscapeUtils.escapeJavaScript(metaEntry.getKey()).replace("'", "\'"));
       pw.write("':'");
-      pw.write(StringEscapeUtils.escapeJavaScript(metaEntry.getValue()).replaceAll("'", "\\'"));
+      pw.write(StringEscapeUtils.escapeJavaScript(metaEntry.getValue()).replace("'", "\'"));
       pw.write("'");
     }
     pw.write("\n}");

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/GadgetSpec.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/GadgetSpec.java?rev=988569&r1=988568&r2=988569&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/GadgetSpec.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/GadgetSpec.java Tue Aug 24 14:33:23 2010
@@ -23,7 +23,6 @@ import org.apache.shindig.common.util.Ha
 import org.apache.shindig.common.xml.XmlUtil;
 import org.apache.shindig.gadgets.variables.Substitutions;
 
-import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Lists;
 import com.google.common.collect.MapMaker;

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/ModulePrefs.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/ModulePrefs.java?rev=988569&r1=988568&r2=988569&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/ModulePrefs.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/ModulePrefs.java Tue Aug 24 14:33:23 2010
@@ -637,7 +637,7 @@ public class ModulePrefs {
   /**
    * Process ModulePrefs/OAuth
    */
-  private class OAuthVisitor implements ElementVisitor {
+  private final class OAuthVisitor implements ElementVisitor {
     private OAuthSpec oauthSpec = null;
     private final MutableBoolean oauthMarker;
     
@@ -665,7 +665,7 @@ public class ModulePrefs {
   /**
    * Processes ModulePrefs/Require and ModulePrefs/Optional
    */
-  private static class FeatureVisitor implements ElementVisitor {
+  private static final class FeatureVisitor implements ElementVisitor {
     private final Map<String, Feature> features = Maps.newHashMap();
     private final MutableBoolean oauthMarker;
     private boolean coreIncluded = false;

Propchange: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/templates/DefaultTemplateProcessor.java
            ('svn:mergeinfo' removed)

Propchange: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/templates/XmlTemplateLibrary.java
            ('svn:mergeinfo' removed)

Propchange: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/templates/tags/AbstractTagHandler.java
            ('svn:mergeinfo' removed)

Propchange: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/templates/tags/AbstractTagRegistry.java
            ('svn:mergeinfo' removed)

Propchange: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/templates/tags/CompositeTagRegistry.java
            ('svn:mergeinfo' removed)

Propchange: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/templates/tags/DefaultTagRegistry.java
            ('svn:mergeinfo' removed)

Propchange: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/templates/tags/FlashTagHandler.java
            ('svn:mergeinfo' removed)

Propchange: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/templates/tags/HtmlTagHandler.java
            ('svn:mergeinfo' removed)

Propchange: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/templates/tags/IfTagHandler.java
            ('svn:mergeinfo' removed)

Propchange: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/templates/tags/RenderTagHandler.java
            ('svn:mergeinfo' removed)

Propchange: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/templates/tags/RepeatTagHandler.java
            ('svn:mergeinfo' removed)

Propchange: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/templates/tags/TagHandler.java
            ('svn:mergeinfo' removed)

Propchange: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/templates/tags/TemplateBasedTagHandler.java
            ('svn:mergeinfo' removed)

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/DefaultProxyUriManager.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/DefaultProxyUriManager.java?rev=988569&r1=988568&r2=988569&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/DefaultProxyUriManager.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/DefaultProxyUriManager.java Tue Aug 24 14:33:23 2010
@@ -26,6 +26,7 @@ import com.google.inject.name.Named;
 import org.apache.commons.lang.StringUtils;
 import org.apache.shindig.common.uri.Uri;
 import org.apache.shindig.common.uri.UriBuilder;
+import org.apache.shindig.common.util.Utf8UrlCoder;
 import org.apache.shindig.config.ContainerConfig;
 import org.apache.shindig.gadgets.GadgetException;
 import org.apache.shindig.gadgets.http.HttpResponse;
@@ -39,22 +40,22 @@ import java.util.Map;
 
 /**
  * Generates URIs for use by the Shindig proxy service.
- * 
+ *
  * URIs are generated on the host specified in ContainerConfig at key
  * "gadgets.uri.proxy.host".
- * 
+ *
  * The remainder of the URL may reference either chained or query-style
  * proxy syntax. The former is used when "gadgets.uri.proxy.path" has token
  * "%chained_params%" in it.
- * 
+ *
  * Chained: Returned URI contains query params in its path, with the proxied
  * resource's URI appended verbatim to the end. This enables proxied SWFs
  * to perform proxied, relative-URI resource loads. Example:
  * http://www.example.com/gadgets/proxy/refresh=1&.../http://www.foo.com/img.gif
- * 
+ *
  * Query param: All params are provided on the query string. Example:
  * http://www.example.com/gadgets/proxy?refresh=1&url=http://www.foo.com/img.gif&...
- * 
+ *
  * This implementation supports batched versioning as well. The old-style "fp"
  * (fingerprint) parameter is not supported any longer; its functionality is assumed
  * to be subsumed into the version param.
@@ -67,30 +68,30 @@ public class DefaultProxyUriManager impl
   private final ContainerConfig config;
   private final Versioner versioner;
   private boolean strictParsing = false;
-  
+
   @Inject
   public DefaultProxyUriManager(ContainerConfig config,
                                 @Nullable Versioner versioner) {
     this.config = config;
     this.versioner = versioner;
   }
-  
+
   @Inject(optional = true)
   public void setUseStrictParsing(@Named("shindig.uri.proxy.use-strict-parsing") boolean useStrict) {
     this.strictParsing = useStrict;
   }
-  
+
   public List<Uri> make(List<ProxyUri> resources, Integer forcedRefresh) {
     if (resources.isEmpty()) {
       return Collections.emptyList();
     }
 
     List<Uri> resourceUris = Lists.newArrayListWithCapacity(resources.size());
-    
+
     for (ProxyUri puc : resources) {
       resourceUris.add(puc.getResource());
     }
-    
+
     Map<Uri, String> versions;
     if (versioner == null) {
       versions = Collections.emptyMap();
@@ -106,12 +107,12 @@ public class DefaultProxyUriManager impl
         }
       }
     }
-    
+
     List<Uri> result = Lists.newArrayListWithCapacity(resources.size());
     for (ProxyUri puc : resources) {
       result.add(makeProxiedUri(puc, forcedRefresh, versions.get(puc.getResource())));
     }
-    
+
     return result;
   }
 
@@ -120,10 +121,8 @@ public class DefaultProxyUriManager impl
 
     String container = puc.getContainer();
     UriBuilder uri = new UriBuilder();
-    // TODO need to decide http vs https
-    uri.setScheme("http");
     uri.setAuthority(getReqConfig(container, PROXY_HOST_PARAM));
-    
+
     // Chained vs. query-style syntax is determined by the presence of CHAINED_PARAMS_TOKEN
     String path = getReqConfig(container, PROXY_PATH_PARAM);
     if (path.contains(CHAINED_PARAMS_TOKEN)) {
@@ -134,20 +133,20 @@ public class DefaultProxyUriManager impl
       String curUri = uriStr + (!uriStr.endsWith("/") ? "/" : "") + puc.getResource().toString();
       return Uri.parse(curUri);
     }
-    
+
     // Query-style syntax. Use path as normal and append query params at the end.
     queryBuilder.addQueryParameter(Param.URL.getKey(), puc.getResource().toString());
     uri.setQuery(queryBuilder.getQuery());
     uri.setPath(path);
-    
+
     return uri.toUri();
   }
-  
+
   @SuppressWarnings("deprecation")
   public ProxyUri process(Uri uriIn) throws GadgetException {
     UriStatus status = UriStatus.BAD_URI;
     Uri uri = null;
-    
+
     // First determine if the URI is chained-syntax or query-style.
     String container = uriIn.getQueryParameter(Param.CONTAINER.getKey());
     if (container == null) {
@@ -165,6 +164,12 @@ public class DefaultProxyUriManager impl
       // Check for chained query string in the path.
       String containerStr = Param.CONTAINER.getKey() + '=';
       String path = uriIn.getPath();
+      // It is possible to get decoded url ('=' converted to %3d)
+      // for example from CssResponseRewriter, so we should support it
+      boolean doDecode = (!path.contains(containerStr));
+      if (doDecode) {
+        path = Utf8UrlCoder.decode(path);
+      }
       int start = path.indexOf(containerStr);
       if (start > 0) {
         start += containerStr.length();
@@ -179,8 +184,9 @@ public class DefaultProxyUriManager impl
         if (container != null) {
           String proxyPath = config.getString(container, PROXY_PATH_PARAM);
           if (proxyPath != null) {
-            String[] chainedChunks = StringUtils.splitByWholeSeparatorPreserveAllTokens(proxyPath, CHAINED_PARAMS_TOKEN);
-            
+            String[] chainedChunks = StringUtils.splitByWholeSeparatorPreserveAllTokens(
+                proxyPath, CHAINED_PARAMS_TOKEN);
+
             // Parse out the URI of the actual resource. This URI is found as the
             // substring of the "full" URI, after the chained proxy prefix. We
             // first search for the pre- and post-fixes of the original /pre/%chained_params%/post
@@ -190,24 +196,28 @@ public class DefaultProxyUriManager impl
             if (chainedChunks.length == 2 && chainedChunks[1].length() > 0) {
               endToken = chainedChunks[1];
             }
-            
+
             // Pull URI out of original inUri's full representation.
             String fullProxyUri = uriIn.toString();
             int startIx = fullProxyUri.indexOf(startToken) + startToken.length();
             int endIx = fullProxyUri.indexOf(endToken, startIx);
             if (startIx > 0 && endIx > 0) {
-              queryUri = new UriBuilder().setQuery(fullProxyUri.substring(startIx,endIx)).toUri();
+              String chainedQuery = fullProxyUri.substring(startIx, endIx);
+              if (doDecode) {
+                chainedQuery = Utf8UrlCoder.decode(chainedQuery);
+              }
+              queryUri = new UriBuilder().setQuery(chainedQuery).toUri();
               uriStr = fullProxyUri.substring(endIx + endToken.length());
               while (uriStr.startsWith("/")) {
                 uriStr = uriStr.substring(1);
               }
-              
+
             }
           }
         }
       }
     }
-    
+
     if (!strictParsing && container != null && StringUtils.isEmpty(uriStr)) {
       // Query-style despite the container being configured for chained style.
       uriStr = uriIn.getQueryParameter(Param.URL.getKey());
@@ -222,7 +232,7 @@ public class DefaultProxyUriManager impl
           (StringUtils.isEmpty(container) ? ' ' + Param.CONTAINER.getKey() : ""),
           HttpResponse.SC_BAD_REQUEST);
     }
-    
+
     String queryHost = config.getString(container, PROXY_HOST_PARAM);
     if (strictParsing) {
       if (queryHost == null || !queryHost.equalsIgnoreCase(uriIn.getAuthority())) {
@@ -230,7 +240,7 @@ public class DefaultProxyUriManager impl
             HttpResponse.SC_BAD_REQUEST);
       }
     }
-    
+
     try {
       uri = Uri.parse(uriStr);
     } catch (Exception e) {
@@ -238,7 +248,7 @@ public class DefaultProxyUriManager impl
       throw new GadgetException(GadgetException.Code.INVALID_PARAMETER,
           "Invalid " + Param.URL.getKey() + ": " + uriStr, HttpResponse.SC_BAD_REQUEST);
     }
-    
+
     // URI is valid.
     status = UriStatus.VALID_UNVERSIONED;
 
@@ -246,7 +256,7 @@ public class DefaultProxyUriManager impl
     if (versioner != null && version != null) {
       status = versioner.validate(uri, container, version);
     }
-    
+
     return new ProxyUri(status, uri, queryUri);
   }
 

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/ProxyUriManager.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/ProxyUriManager.java?rev=988569&r1=988568&r2=988569&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/ProxyUriManager.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/ProxyUriManager.java Tue Aug 24 14:33:23 2010
@@ -18,6 +18,7 @@
  */
 package org.apache.shindig.gadgets.uri;
 
+import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Objects;
 import com.google.common.collect.Lists;
 
@@ -48,6 +49,10 @@ public interface ProxyUriManager {
     private Integer resizeWidth;
     private Integer resizeQuality;
     private boolean resizeNoExpand;
+
+    // If "true" then the original content should be returned to the user
+    // instead of internal server errors.
+    private String returnOriginalContentOnError;
     
     public ProxyUri(Gadget gadget, Uri resource) {
       super(gadget);
@@ -64,6 +69,11 @@ public interface ProxyUriManager {
       super(status, base);
       this.resource = resource;
     }
+
+    @VisibleForTesting
+    public void setReturnOriginalContentOnError(boolean returnOriginalContentOnError) {
+      this.returnOriginalContentOnError = returnOriginalContentOnError ? "1" : null;
+    }
     
     @Override
     public boolean equals(Object obj) {
@@ -80,13 +90,14 @@ public interface ProxyUriManager {
           && Objects.equal(this.resizeHeight, objUri.resizeHeight)
           && Objects.equal(this.resizeWidth, objUri.resizeWidth)
           && Objects.equal(this.resizeQuality, objUri.resizeQuality)
-          && this.resizeNoExpand == objUri.resizeNoExpand);
+          && Objects.equal(this.resizeNoExpand, objUri.resizeNoExpand)
+          && Objects.equal(this.returnOriginalContentOnError, objUri.returnOriginalContentOnError));
     }
 
     @Override
     public int hashCode() {
       return Objects.hashCode(super.hashCode(), resource, fallbackUrl, resizeHeight,
-              resizeWidth, resizeQuality, resizeNoExpand);
+              resizeWidth, resizeQuality, resizeNoExpand, returnOriginalContentOnError);
     }
 
     /* (non-Javadoc)
@@ -101,6 +112,8 @@ public interface ProxyUriManager {
         resizeWidth = getIntegerValue(uri.getQueryParameter(Param.RESIZE_WIDTH.getKey()));
         resizeQuality = getIntegerValue(uri.getQueryParameter(Param.RESIZE_QUALITY.getKey()));
         resizeNoExpand = getBooleanValue(uri.getQueryParameter(Param.NO_EXPAND.getKey()));
+        returnOriginalContentOnError = uri.getQueryParameter(
+            Param.RETURN_ORIGINAL_CONTENT_ON_ERROR.getKey());
       }
     }
 
@@ -135,6 +148,11 @@ public interface ProxyUriManager {
       }
     }
 
+    public boolean shouldReturnOrigOnErr() {
+      return "1".equals(this.returnOriginalContentOnError) ||
+             "true".equalsIgnoreCase(this.returnOriginalContentOnError);
+    }
+
     @Override
     public UriBuilder makeQueryParams(Integer forcedRefresh, String version) {
       UriBuilder builder = super.makeQueryParams(forcedRefresh, version);
@@ -153,6 +171,10 @@ public interface ProxyUriManager {
       if (fallbackUrl != null) {
         builder.addQueryParameter(Param.FALLBACK_URL_PARAM.getKey(), fallbackUrl);
       }
+      if (returnOriginalContentOnError != null) {
+        builder.addQueryParameter(Param.RETURN_ORIGINAL_CONTENT_ON_ERROR.getKey(),
+                                  returnOriginalContentOnError);
+      }
       return builder;
     }
     

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/UriCommon.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/UriCommon.java?rev=988569&r1=988568&r2=988569&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/UriCommon.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/UriCommon.java Tue Aug 24 14:33:23 2010
@@ -48,6 +48,7 @@ public interface UriCommon {
     RESIZE_QUALITY("resize_q"),
     NO_EXPAND("no_expand"),
     FALLBACK_URL_PARAM("fallback_url"),
+    RETURN_ORIGINAL_CONTENT_ON_ERROR("rooe"),
     
     // This is a legacy param, superseded by container.
     @Deprecated

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/UriUtils.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/UriUtils.java?rev=988569&r1=988568&r2=988569&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/UriUtils.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/UriUtils.java Tue Aug 24 14:33:23 2010
@@ -37,6 +37,9 @@ import java.util.Set;
  */
 public class UriUtils {
   private static final Logger LOG = Logger.getLogger(UriUtils.class.getName());
+
+  private UriUtils() {}
+  
   /**
    * Enum of disallowed response headers that should not be passed on as is to
    * the user. The webserver serving out the response should be responsible
@@ -214,7 +217,7 @@ public class UriUtils {
                                      HttpRequest req) throws GadgetException {
     req.setMethod(origRequest.getMethod());
     try {
-      if (origRequest.getMethod().toLowerCase().equals("post")) {
+      if (origRequest.getMethod().equalsIgnoreCase("post")) {
         req.setPostBody(origRequest.getPostBody());
       }
     } catch (IOException e) {

Modified: shindig/branches/2.0.x/java/gadgets/src/test/java/org/apache/shindig/gadgets/features/FeatureRegistryTest.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/test/java/org/apache/shindig/gadgets/features/FeatureRegistryTest.java?rev=988569&r1=988568&r2=988569&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/test/java/org/apache/shindig/gadgets/features/FeatureRegistryTest.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/test/java/org/apache/shindig/gadgets/features/FeatureRegistryTest.java Tue Aug 24 14:33:23 2010
@@ -724,11 +724,11 @@ public class FeatureRegistryTest {
     for (Map.Entry<String, String> entry : resourceAttribs.entrySet()) {
       sbRes.append(entry.getKey()).append("=\"").append(entry.getValue()).append("\" ");
     }
-    return tpl.replaceAll("%type%", type)
-        .replaceAll("%uri%", uri != null ? "src=\"" + uri + '\"' : "")
-        .replaceAll("%content%", content != null ? content : "")
-        .replaceAll("%type_attribs%", sb.toString())
-        .replaceAll("%res_attribs%", sbRes.toString());
+    return tpl.replace("%type%", type)
+        .replace("%uri%", uri != null ? "src=\"" + uri + '\"' : "")
+        .replace("%content%", content != null ? content : "")
+        .replace("%type_attribs%", sb.toString())
+        .replace("%res_attribs%", sbRes.toString());
   }
   
   private static Uri makeFile(String content) throws Exception {

Modified: shindig/branches/2.0.x/java/gadgets/src/test/java/org/apache/shindig/gadgets/parse/AbstractParsingTestBase.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/test/java/org/apache/shindig/gadgets/parse/AbstractParsingTestBase.java?rev=988569&r1=988568&r2=988569&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/test/java/org/apache/shindig/gadgets/parse/AbstractParsingTestBase.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/test/java/org/apache/shindig/gadgets/parse/AbstractParsingTestBase.java Tue Aug 24 14:33:23 2010
@@ -52,7 +52,7 @@ public abstract class AbstractParsingTes
   protected void parseAndCompareBalanced(String content, String expected, GadgetHtmlParser parser)
       throws Exception {
     Document document = parser.parseDom(content);
-    expected = StringUtils.replace(expected, EOL, "\n");
+    expected = expected.replace(EOL, "\n");
     String serialized = HtmlSerialization.serialize(document);
     assertHtmlEquals(expected, serialized);
   }

Propchange: shindig/branches/2.0.x/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriterTest.java
            ('svn:mergeinfo' removed)

Modified: shindig/branches/2.0.x/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/AbsolutePathReferenceVisitorTest.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/AbsolutePathReferenceVisitorTest.java?rev=988569&r1=988568&r2=988569&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/AbsolutePathReferenceVisitorTest.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/AbsolutePathReferenceVisitorTest.java Tue Aug 24 14:33:23 2010
@@ -110,7 +110,32 @@ public class AbsolutePathReferenceVisito
 
   @Test
   public void absolutifyTagLink() throws Exception {
-    checkAbsolutifyStates("link");
+    Element cssLink = elem("link", "href", RELATIVE_URI.toString(),
+                           "rel", "stylesheet", "type", "text/css");
+    assertEquals("CSS link tag should not be bypassed",
+                 VisitStatus.MODIFY, getVisitStatus(cssLink));
+  }
+
+  @Test
+  public void bypassTagLinkWithNoRel() throws Exception {
+    Element cssLink = elem("link", "href", RELATIVE_URI.toString(), "type", "text/css");
+    assertEquals("CSS link tag should be bypassed",
+                 VisitStatus.BYPASS, getVisitStatus(cssLink));
+  }
+
+  @Test
+  public void bypassTagLinkWithNoType() throws Exception {
+    Element cssLink = elem("link", "href", RELATIVE_URI.toString(), "rel", "stylesheet");
+    assertEquals("CSS link tag should be bypassed",
+                 VisitStatus.BYPASS, getVisitStatus(cssLink));
+  }
+
+  @Test
+  public void bypassTagLinkAlternate() throws Exception {
+    Element cssLink = elem("link", "href", RELATIVE_URI.toString(),
+                           "rel", "alternate", "hreflang", "el");
+    assertEquals("CSS link tag should be bypassed",
+                 VisitStatus.BYPASS, getVisitStatus(cssLink));
   }
 
   @Test

Modified: shindig/branches/2.0.x/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/ConcatVisitorTest.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/ConcatVisitorTest.java?rev=988569&r1=988568&r2=988569&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/ConcatVisitorTest.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/ConcatVisitorTest.java Tue Aug 24 14:33:23 2010
@@ -27,7 +27,6 @@ import com.google.common.collect.Immutab
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 
-import org.apache.commons.lang.StringUtils;
 import org.apache.shindig.common.uri.Uri;
 import org.apache.shindig.common.uri.UriBuilder;
 import org.apache.shindig.gadgets.rewrite.DomWalker.Visitor.VisitStatus;
@@ -236,7 +235,7 @@ public class ConcatVisitorTest extends D
     // Should be left with a single JS node child to parent.
     assertEquals(1, parent.getChildNodes().getLength());
     Element concatNode = (Element)parent.getChildNodes().item(0);
-    Uri concatUri = Uri.parse(StringUtils.replace(concatNode.getAttribute("src"), "&amp;", "&"));
+    Uri concatUri = Uri.parse(concatNode.getAttribute("src").replace("&amp;", "&"));
     assertEquals(CONCAT_BASE_URI.getScheme(), concatUri.getScheme());
     assertEquals(CONCAT_BASE_URI.getAuthority(), concatUri.getAuthority());
     assertEquals(CONCAT_BASE_URI.getPath(), concatUri.getPath());
@@ -260,7 +259,7 @@ public class ConcatVisitorTest extends D
     // Should be left with a single JS node child to parent.
     assertEquals(1, parent.getChildNodes().getLength());
     Element concatNode = (Element)parent.getChildNodes().item(0);
-    Uri concatUri = Uri.parse(StringUtils.replace(concatNode.getAttribute("href"), "&amp;", "&"));
+    Uri concatUri = Uri.parse(concatNode.getAttribute("href").replace("&amp;", "&"));
     assertEquals(CONCAT_BASE_URI.getScheme(), concatUri.getScheme());
     assertEquals(CONCAT_BASE_URI.getAuthority(), concatUri.getAuthority());
     assertEquals(CONCAT_BASE_URI.getPath(), concatUri.getPath());
@@ -287,7 +286,7 @@ public class ConcatVisitorTest extends D
     // Should have been independently concatenated.
     assertEquals(1, parent1.getChildNodes().getLength());
     Element cn1 = (Element)parent1.getChildNodes().item(0);
-    Uri concatUri1 = Uri.parse(StringUtils.replace(cn1.getAttribute("src"), "&amp;", "&"));
+    Uri concatUri1 = Uri.parse(cn1.getAttribute("src").replace("&amp;", "&"));
     assertEquals(CONCAT_BASE_URI.getScheme(), concatUri1.getScheme());
     assertEquals(CONCAT_BASE_URI.getAuthority(), concatUri1.getAuthority());
     assertEquals(CONCAT_BASE_URI.getPath(), concatUri1.getPath());
@@ -297,7 +296,7 @@ public class ConcatVisitorTest extends D
     
     assertEquals(1, parent2.getChildNodes().getLength());
     Element cn2 = (Element)parent2.getChildNodes().item(0);
-    Uri concatUri2 = Uri.parse(StringUtils.replace(cn2.getAttribute("src"), "&amp;", "&"));
+    Uri concatUri2 = Uri.parse(cn2.getAttribute("src").replace("&amp;", "&"));
     assertEquals(CONCAT_BASE_URI.getScheme(), concatUri2.getScheme());
     assertEquals(CONCAT_BASE_URI.getAuthority(), concatUri2.getAuthority());
     assertEquals(CONCAT_BASE_URI.getPath(), concatUri2.getPath());
@@ -324,7 +323,7 @@ public class ConcatVisitorTest extends D
     // Should have been independently concatenated.
     assertEquals(1, parent1.getChildNodes().getLength());
     Element cn1 = (Element)parent1.getChildNodes().item(0);
-    Uri concatUri1 = Uri.parse(StringUtils.replace(cn1.getAttribute("href"), "&amp;", "&"));
+    Uri concatUri1 = Uri.parse(cn1.getAttribute("href").replace("&amp;", "&"));
     assertEquals(CONCAT_BASE_URI.getScheme(), concatUri1.getScheme());
     assertEquals(CONCAT_BASE_URI.getAuthority(), concatUri1.getAuthority());
     assertEquals(CONCAT_BASE_URI.getPath(), concatUri1.getPath());
@@ -334,7 +333,7 @@ public class ConcatVisitorTest extends D
     
     assertEquals(3, parent2.getChildNodes().getLength());
     Element cn2 = (Element)parent2.getChildNodes().item(0);
-    Uri concatUri2 = Uri.parse(StringUtils.replace(cn2.getAttribute("href"), "&amp;", "&"));
+    Uri concatUri2 = Uri.parse(cn2.getAttribute("href").replace("&amp;", "&"));
     assertEquals(CONCAT_BASE_URI.getScheme(), concatUri2.getScheme());
     assertEquals(CONCAT_BASE_URI.getAuthority(), concatUri2.getAuthority());
     assertEquals(CONCAT_BASE_URI.getPath(), concatUri2.getPath());
@@ -345,7 +344,7 @@ public class ConcatVisitorTest extends D
     assertEquals("", cn2.getAttribute("media"));
     
     Element cn3 = (Element)parent2.getChildNodes().item(1);
-    Uri concatUri3 = Uri.parse(StringUtils.replace(cn3.getAttribute("href"), "&amp;", "&"));
+    Uri concatUri3 = Uri.parse(cn3.getAttribute("href").replace("&amp;", "&"));
     assertEquals(CONCAT_BASE_URI.getScheme(), concatUri3.getScheme());
     assertEquals(CONCAT_BASE_URI.getAuthority(), concatUri3.getAuthority());
     assertEquals(CONCAT_BASE_URI.getPath(), concatUri3.getPath());
@@ -355,7 +354,7 @@ public class ConcatVisitorTest extends D
     assertEquals("print", cn3.getAttribute("media"));
   
     Element cn4 = (Element)parent2.getChildNodes().item(2);
-    Uri concatUri4 = Uri.parse(StringUtils.replace(cn4.getAttribute("href"), "&amp;", "&"));
+    Uri concatUri4 = Uri.parse(cn4.getAttribute("href").replace("&amp;", "&"));
     assertEquals(CONCAT_BASE_URI.getScheme(), concatUri4.getScheme());
     assertEquals(CONCAT_BASE_URI.getAuthority(), concatUri4.getAuthority());
     assertEquals(CONCAT_BASE_URI.getPath(), concatUri4.getPath());
@@ -387,7 +386,7 @@ public class ConcatVisitorTest extends D
     // Should have been independently concatenated. Batches #1 and #2 are OK. Middle skipped.
     assertEquals(1, parent1.getChildNodes().getLength());
     Element cn1 = (Element)parent1.getChildNodes().item(0);
-    Uri concatUri1 = Uri.parse(StringUtils.replace(cn1.getAttribute("src"), "&amp;", "&"));
+    Uri concatUri1 = Uri.parse(cn1.getAttribute("src").replace("&amp;", "&"));
     assertEquals(CONCAT_BASE_URI.getScheme(), concatUri1.getScheme());
     assertEquals(CONCAT_BASE_URI.getAuthority(), concatUri1.getAuthority());
     assertEquals(CONCAT_BASE_URI.getPath(), concatUri1.getPath());
@@ -400,7 +399,7 @@ public class ConcatVisitorTest extends D
     
     assertEquals(1, parent2.getChildNodes().getLength());
     Element cn2 = (Element)parent2.getChildNodes().item(0);
-    Uri concatUri2 = Uri.parse(StringUtils.replace(cn2.getAttribute("src"), "&amp;", "&"));
+    Uri concatUri2 = Uri.parse(cn2.getAttribute("src").replace("&amp;", "&"));
     assertEquals(CONCAT_BASE_URI.getScheme(), concatUri2.getScheme());
     assertEquals(CONCAT_BASE_URI.getAuthority(), concatUri2.getAuthority());
     assertEquals(CONCAT_BASE_URI.getPath(), concatUri2.getPath());
@@ -423,7 +422,7 @@ public class ConcatVisitorTest extends D
     assertEquals(3, parent.getChildNodes().getLength());
     Element jsConcat = (Element)parent.getChildNodes().item(0);
     assertEquals("script", jsConcat.getTagName());
-    Uri concatUri = Uri.parse(StringUtils.replace(jsConcat.getAttribute("src"), "&amp;", "&"));
+    Uri concatUri = Uri.parse(jsConcat.getAttribute("src").replace("&amp;", "&"));
     assertEquals(CONCAT_BASE_URI.getScheme(), concatUri.getScheme());
     assertEquals(CONCAT_BASE_URI.getAuthority(), concatUri.getAuthority());
     assertEquals(CONCAT_BASE_URI.getPath(), concatUri.getPath());
@@ -465,7 +464,7 @@ public class ConcatVisitorTest extends D
     assertEquals(7, parent.getChildNodes().getLength());
     Element jsConcat = (Element)parent.getChildNodes().item(1);
     assertEquals("script", jsConcat.getTagName());
-    Uri concatUri = Uri.parse(StringUtils.replace(jsConcat.getAttribute("src"), "&amp;", "&"));
+    Uri concatUri = Uri.parse(jsConcat.getAttribute("src").replace("&amp;", "&"));
     assertEquals(CONCAT_BASE_URI.getScheme(), concatUri.getScheme());
     assertEquals(CONCAT_BASE_URI.getAuthority(), concatUri.getAuthority());
     assertEquals(CONCAT_BASE_URI.getPath(), concatUri.getPath());

Modified: shindig/branches/2.0.x/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/CssResponseRewriterTest.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/CssResponseRewriterTest.java?rev=988569&r1=988568&r2=988569&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/CssResponseRewriterTest.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/CssResponseRewriterTest.java Tue Aug 24 14:33:23 2010
@@ -101,7 +101,7 @@ public class CssResponseRewriterTest ext
         getResourceAsStream("org/apache/shindig/gadgets/rewrite/rewritebasic.css"));
     String expected = IOUtils.toString(this.getClass().getClassLoader().
         getResourceAsStream("org/apache/shindig/gadgets/rewrite/rewritebasic-expected.css"));
-    expected = expected.replaceAll("refresh=3600", "refresh=86400");
+    expected = expected.replace("refresh=3600", "refresh=86400");
     HttpRequest request = new HttpRequest(Uri.parse("http://www.example.org/path/rewritebasic.css"));
     request.setMethod("GET");
     request.setGadget(SPEC_URL);
@@ -120,7 +120,7 @@ public class CssResponseRewriterTest ext
         getResourceAsStream("org/apache/shindig/gadgets/rewrite/rewritebasic.css"));
     String expected = IOUtils.toString(this.getClass().getClassLoader().
         getResourceAsStream("org/apache/shindig/gadgets/rewrite/rewritebasic-expected.css"));
-    expected = expected.replaceAll("fp=1150739864", "fp=1150739864&nocache=1");
+    expected = expected.replace("fp=1150739864", "fp=1150739864&nocache=1");
     HttpRequest request = new HttpRequest(Uri.parse("http://www.example.org/path/rewritebasic.css"));
     request.setMethod("GET");
     request.setGadget(SPEC_URL);

Propchange: shindig/branches/2.0.x/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/PipelineDataGadgetRewriterTest.java
            ('svn:mergeinfo' removed)