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/06/02 11:05:02 UTC

svn commit: r950443 [3/7] - in /shindig/branches/2.0.x: ./ config/ content/samplecontainer/ content/samplecontainer/examples/ content/samplecontainer/examples/ActivityStreams/ content/sampledata/ extras/src/main/java/org/apache/shindig/extras/ extras/s...

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/AccessorInfoBuilder.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/AccessorInfoBuilder.java?rev=950443&r1=950442&r2=950443&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/AccessorInfoBuilder.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/AccessorInfoBuilder.java Wed Jun  2 09:04:51 2010
@@ -23,7 +23,6 @@ import net.oauth.OAuthAccessor;
 
 import org.apache.shindig.gadgets.oauth.AccessorInfo.HttpMethod;
 import org.apache.shindig.gadgets.oauth.AccessorInfo.OAuthParamLocation;
-import org.apache.shindig.gadgets.oauth.OAuthResponseParams.OAuthRequestException;
 import org.apache.shindig.gadgets.oauth.OAuthStore.ConsumerInfo;
 
 /**
@@ -45,10 +44,10 @@ public class AccessorInfoBuilder {
 
   public AccessorInfo create(OAuthResponseParams responseParams) throws OAuthRequestException {
     if (location == null) {
-      throw responseParams.oauthRequestException(OAuthError.UNKNOWN_PROBLEM, "no location");
+      throw new OAuthRequestException(OAuthError.UNKNOWN_PROBLEM, "no location");
     }
     if (consumer == null) {
-      throw responseParams.oauthRequestException(OAuthError.UNKNOWN_PROBLEM, "no consumer");
+      throw new OAuthRequestException(OAuthError.UNKNOWN_PROBLEM, "no consumer");
     }
 
     OAuthAccessor accessor = new OAuthAccessor(consumer.getConsumer());

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/BasicOAuthStore.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/BasicOAuthStore.java?rev=950443&r1=950442&r2=950443&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/BasicOAuthStore.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/BasicOAuthStore.java Wed Jun  2 09:04:51 2010
@@ -129,7 +129,7 @@ public class BasicOAuthStore implements 
     String keyTypeStr = consumerInfo.getString(KEY_TYPE_KEY);
     KeyType keyType = KeyType.HMAC_SYMMETRIC;
 
-    if (keyTypeStr.equals("RSA_PRIVATE")) {
+    if ("RSA_PRIVATE".equals(keyTypeStr)) {
       keyType = KeyType.RSA_PRIVATE;
       consumerSecret = convertFromOpenSsl(consumerSecret);
     }

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/GadgetOAuthCallbackGenerator.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/GadgetOAuthCallbackGenerator.java?rev=950443&r1=950442&r2=950443&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/GadgetOAuthCallbackGenerator.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/GadgetOAuthCallbackGenerator.java Wed Jun  2 09:04:51 2010
@@ -32,7 +32,6 @@ import org.apache.shindig.gadgets.Gadget
 import org.apache.shindig.gadgets.LockedDomainService;
 import org.apache.shindig.gadgets.UrlGenerator;
 import org.apache.shindig.gadgets.http.HttpRequest;
-import org.apache.shindig.gadgets.oauth.OAuthResponseParams.OAuthRequestException;
 import org.apache.shindig.gadgets.process.ProcessingException;
 import org.apache.shindig.gadgets.process.Processor;
 import org.apache.shindig.gadgets.servlet.OAuthCallbackServlet;
@@ -118,12 +117,12 @@ public class GadgetOAuthCallbackGenerato
       Uri activeUrl = Uri.parse(securityToken.getActiveUrl());
       String hostname = activeUrl.getAuthority();
       if (!lockedDomainService.gadgetCanRender(hostname, gadget, securityToken.getContainer())) {
-        throw responseParams.oauthRequestException(OAuthError.UNKNOWN_PROBLEM,
+        throw new OAuthRequestException(OAuthError.UNKNOWN_PROBLEM,
             "Gadget should not be using URL " + activeUrl);
       }
       return activeUrl;
     } catch (ProcessingException e) {
-      throw responseParams.oauthRequestException(OAuthError.UNKNOWN_PROBLEM,
+      throw new OAuthRequestException(OAuthError.UNKNOWN_PROBLEM,
           "Unable to check if gadget is using locked-domain", e);
     }
   }
@@ -151,7 +150,7 @@ public class GadgetOAuthCallbackGenerato
       callback.addQueryParameter(OAuthCallbackServlet.CALLBACK_STATE_PARAM,
           state.getEncryptedState());
     } catch (BlobCrypterException e) {
-      throw responseParams.oauthRequestException(OAuthError.UNKNOWN_PROBLEM,
+      throw new OAuthRequestException(OAuthError.UNKNOWN_PROBLEM,
           "Failure generating callback URL", e);
     }
     return callback.toString();

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/GadgetOAuthTokenStore.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/GadgetOAuthTokenStore.java?rev=950443&r1=950442&r2=950443&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/GadgetOAuthTokenStore.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/GadgetOAuthTokenStore.java Wed Jun  2 09:04:51 2010
@@ -24,7 +24,6 @@ import org.apache.shindig.gadgets.Gadget
 import org.apache.shindig.gadgets.GadgetSpecFactory;
 import org.apache.shindig.gadgets.oauth.AccessorInfo.HttpMethod;
 import org.apache.shindig.gadgets.oauth.AccessorInfo.OAuthParamLocation;
-import org.apache.shindig.gadgets.oauth.OAuthResponseParams.OAuthRequestException;
 import org.apache.shindig.gadgets.oauth.OAuthStore.ConsumerInfo;
 import org.apache.shindig.gadgets.oauth.OAuthStore.TokenInfo;
 import org.apache.shindig.gadgets.spec.GadgetSpec;
@@ -105,7 +104,7 @@ public class GadgetOAuthTokenStore {
           securityToken, arguments.getServiceName(), provider);
       accessorBuilder.setConsumer(consumer);
     } catch (GadgetException e) {
-      throw responseParams.oauthRequestException(OAuthError.UNKNOWN_PROBLEM,
+      throw new OAuthRequestException(OAuthError.UNKNOWN_PROBLEM,
           "Unable to retrieve consumer key", e);
     }
 
@@ -130,13 +129,13 @@ public class GadgetOAuthTokenStore {
     GadgetSpec spec = findSpec(securityToken, arguments, responseParams);
     OAuthSpec oauthSpec = spec.getModulePrefs().getOAuthSpec();
     if (oauthSpec == null) {
-      throw responseParams.oauthRequestException(OAuthError.BAD_OAUTH_CONFIGURATION,
+      throw new OAuthRequestException(OAuthError.BAD_OAUTH_CONFIGURATION,
           "Failed to retrieve OAuth URLs, spec for gadget " +
           securityToken.getAppUrl() + " does not contain OAuth element.");
     }
     OAuthService service = oauthSpec.getServices().get(arguments.getServiceName());
     if (service == null) {
-      throw responseParams.oauthRequestException(OAuthError.BAD_OAUTH_CONFIGURATION,
+      throw new OAuthRequestException(OAuthError.BAD_OAUTH_CONFIGURATION,
           "Failed to retrieve OAuth URLs, spec for gadget does not contain OAuth service " +
           arguments.getServiceName() + ".  Known services: " +
           StringUtils.join(oauthSpec.getServices().keySet(), ',') + '.');
@@ -175,7 +174,7 @@ public class GadgetOAuthTokenStore {
       return new OAuthServiceProvider(requestTokenUrl, authorizationUrl, accessTokenUrl);
     } catch (SpecParserException e) {
       // these exceptions have decent programmer readable messages
-      throw responseParams.oauthRequestException(OAuthError.BAD_OAUTH_CONFIGURATION,
+      throw new OAuthRequestException(OAuthError.BAD_OAUTH_CONFIGURATION,
           e.getMessage());
     }
   }
@@ -189,12 +188,10 @@ public class GadgetOAuthTokenStore {
     try {
       uri = Uri.parse(url);
     } catch (Throwable t) {
-      throw responseParams.oauthRequestException(OAuthError.BAD_OAUTH_CONFIGURATION,
-          "Invalid url: " + url);
+      throw new OAuthRequestException(OAuthError.INVALID_URL, url);
     }
     if (!uri.isAbsolute()) {
-      throw responseParams.oauthRequestException(OAuthError.BAD_OAUTH_CONFIGURATION,
-          "Invalid url: " + url);
+      throw new OAuthRequestException(OAuthError.INVALID_URL, url);
     }
   }
 
@@ -235,7 +232,7 @@ public class GadgetOAuthTokenStore {
         tokenInfo = store.getTokenInfo(securityToken, consumerInfo,
             arguments.getServiceName(), arguments.getTokenName());
       } catch (GadgetException e) {
-        throw responseParams.oauthRequestException(OAuthError.UNKNOWN_PROBLEM,
+        throw new OAuthRequestException(OAuthError.UNKNOWN_PROBLEM,
             "Unable to retrieve access token", e);
       }
       if (tokenInfo != null && tokenInfo.getAccessToken() != null) {
@@ -263,8 +260,7 @@ public class GadgetOAuthTokenStore {
     case BODY:
       return OAuthParamLocation.POST_BODY;
     }
-    throw responseParams.oauthRequestException(OAuthError.INVALID_REQUEST,
-        "Unknown parameter location " + location);
+    throw new OAuthRequestException(OAuthError.UNKNOWN_PARAMETER_LOCATION);
   }
 
   private HttpMethod getStoreMethod(Method method, OAuthResponseParams responseParams)
@@ -275,7 +271,7 @@ public class GadgetOAuthTokenStore {
     case POST:
       return HttpMethod.POST;
     }
-    throw responseParams.oauthRequestException(OAuthError.INVALID_REQUEST, "Unknown method " + method);
+    throw new OAuthRequestException(OAuthError.UNSUPPORTED_HTTP_METHOD, method.toString());
   }
 
   private GadgetSpec findSpec(final SecurityToken securityToken, final OAuthArguments arguments,
@@ -284,10 +280,10 @@ public class GadgetOAuthTokenStore {
       GadgetContext context = new OAuthGadgetContext(securityToken, arguments);
       return specFactory.getGadgetSpec(context);
     } catch (IllegalArgumentException e) {
-      throw responseParams.oauthRequestException(OAuthError.UNKNOWN_PROBLEM,
+      throw new OAuthRequestException(OAuthError.UNKNOWN_PROBLEM,
           "Could not fetch gadget spec, gadget URI invalid.", e);
     } catch (GadgetException e) {
-      throw responseParams.oauthRequestException(OAuthError.UNKNOWN_PROBLEM,
+      throw new OAuthRequestException(OAuthError.UNKNOWN_PROBLEM,
           "Could not fetch gadget spec", e);
     }
   }
@@ -302,7 +298,7 @@ public class GadgetOAuthTokenStore {
       store.setTokenInfo(securityToken, consumerInfo, arguments.getServiceName(),
           arguments.getTokenName(), tokenInfo);
     } catch (GadgetException e) {
-      throw responseParams.oauthRequestException(OAuthError.UNKNOWN_PROBLEM,
+      throw new OAuthRequestException(OAuthError.UNKNOWN_PROBLEM,
           "Unable to store access token", e);
     }
   }
@@ -316,7 +312,7 @@ public class GadgetOAuthTokenStore {
       store.removeToken(securityToken, consumerInfo, arguments.getServiceName(),
           arguments.getTokenName());
     } catch (GadgetException e) {
-      throw responseParams.oauthRequestException(OAuthError.UNKNOWN_PROBLEM,
+      throw new OAuthRequestException(OAuthError.UNKNOWN_PROBLEM,
           "Unable to remove access token", e);
     }
   }

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/OAuthCallbackGenerator.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/OAuthCallbackGenerator.java?rev=950443&r1=950442&r2=950443&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/OAuthCallbackGenerator.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/OAuthCallbackGenerator.java Wed Jun  2 09:04:51 2010
@@ -21,7 +21,6 @@ package org.apache.shindig.gadgets.oauth
 import com.google.inject.ImplementedBy;
 
 import org.apache.shindig.gadgets.http.HttpRequest;
-import org.apache.shindig.gadgets.oauth.OAuthResponseParams.OAuthRequestException;
 
 /**
  * Figures out the OAuth callback URL to send service providers.

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/OAuthRequest.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/OAuthRequest.java?rev=950443&r1=950442&r2=950443&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/OAuthRequest.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/OAuthRequest.java Wed Jun  2 09:04:51 2010
@@ -42,7 +42,6 @@ import org.apache.shindig.gadgets.http.H
 import org.apache.shindig.gadgets.http.HttpResponseBuilder;
 import org.apache.shindig.gadgets.oauth.AccessorInfo.HttpMethod;
 import org.apache.shindig.gadgets.oauth.AccessorInfo.OAuthParamLocation;
-import org.apache.shindig.gadgets.oauth.OAuthResponseParams.OAuthRequestException;
 import org.apache.shindig.gadgets.oauth.OAuthStore.TokenInfo;
 import org.json.JSONObject;
 
@@ -196,9 +195,9 @@ public class OAuthRequest {
       response = fetchWithRetry();
     } catch (OAuthRequestException e) {
       // No data for us.
-      if (OAuthError.UNAUTHENTICATED.toString().equals(responseParams.getError())) {
+      if (OAuthError.UNAUTHENTICATED.toString().equals(e.getError())) {
         responseParams.logDetailedInfo("Unauthenticated OAuth fetch", e);
-      } else if (OAuthError.INVALID_REQUEST.toString().equals(responseParams.getError())) {
+      } else if (OAuthError.BAD_OAUTH_TOKEN_URL.toString().equals(e.getError())) {
         responseParams.logDetailedInfo("Invalid OAuth fetch request", e);
       } else {
         responseParams.logDetailedWarning("OAuth fetch fatal error", e);
@@ -207,7 +206,7 @@ public class OAuthRequest {
       response = new HttpResponseBuilder()
           .setHttpStatusCode(HttpResponse.SC_FORBIDDEN)
           .setStrictNoCache();
-      responseParams.addToResponse(response);
+      responseParams.addToResponse(response, e);
       return response.create();
     }
 
@@ -220,8 +219,7 @@ public class OAuthRequest {
       responseParams.setSendTraceToClient(true);
     }
 
-    responseParams.addToResponse(response);
-
+    responseParams.addToResponse(response, null);
     return response.create();
   }
 
@@ -242,10 +240,10 @@ public class OAuthRequest {
         retry = handleProtocolException(pe, attempts);
         if (!retry) {
           if (pe.getProblemCode() != null) {
-            throw responseParams.oauthRequestException(pe.getProblemCode(),
+            throw new OAuthRequestException(pe.getProblemCode(),
                 "Service provider rejected request", pe);
           } else {
-            throw responseParams.oauthRequestException(OAuthError.UNKNOWN_PROBLEM,
+            throw new OAuthRequestException(OAuthError.UNKNOWN_PROBLEM,
                 "Service provider rejected request", pe);
           }
         }
@@ -318,14 +316,13 @@ public class OAuthRequest {
     String pageViewer = realRequest.getSecurityToken().getViewerId();
     String stateOwner = clientState.getOwner();
     if (pageOwner == null || pageViewer == null) {
-      throw responseParams.oauthRequestException(OAuthError.UNAUTHENTICATED, "Unauthenticated");
+      throw new OAuthRequestException(OAuthError.UNAUTHENTICATED);
     }
     if (!fetcherConfig.isViewerAccessTokensEnabled() && !pageOwner.equals(pageViewer)) {
-      throw responseParams.oauthRequestException(OAuthError.NOT_OWNER,
-          "Non-Secure Owner Page -- Only page owners can grant OAuth approval");
+      throw new OAuthRequestException(OAuthError.NOT_OWNER);
     }
     if (stateOwner != null && !stateOwner.equals(pageViewer)) {
-      throw responseParams.oauthRequestException(OAuthError.UNKNOWN_PROBLEM,
+      throw new OAuthRequestException(OAuthError.UNKNOWN_PROBLEM,
           "Client state belongs to a different person " +
           "(state owner=" + stateOwner + ", pageViewer=" + pageViewer + ')');
     }
@@ -334,11 +331,11 @@ public class OAuthRequest {
   private void fetchRequestToken() throws OAuthRequestException, OAuthProtocolException {
     OAuthAccessor accessor = accessorInfo.getAccessor();
     HttpRequest request = createRequestTokenRequest(accessor);
-    
+
     List<Parameter> requestTokenParams = Lists.newArrayList();
-    
+
     addCallback(requestTokenParams);
-    
+
     HttpRequest signed = sanitizeAndSign(request, requestTokenParams, true);
 
     OAuthMessage reply = sendOAuthMessage(signed);
@@ -350,8 +347,7 @@ public class OAuthRequest {
   private HttpRequest createRequestTokenRequest(OAuthAccessor accessor)
       throws OAuthRequestException {
     if (accessor.consumer.serviceProvider.requestTokenURL == null) {
-      throw responseParams.oauthRequestException(OAuthError.BAD_OAUTH_CONFIGURATION,
-          "No request token URL specified");
+      throw new OAuthRequestException(OAuthError.BAD_OAUTH_TOKEN_URL, "request token");
     }
     HttpRequest request = new HttpRequest(
         Uri.parse(accessor.consumer.serviceProvider.requestTokenURL));
@@ -384,9 +380,7 @@ public class OAuthRequest {
       if (allowParam(name)) {
         list.add(p);
       } else {
-        throw responseParams.oauthRequestException(OAuthError.INVALID_REQUEST,
-            "invalid parameter name " + name +
-            ", applications may not override opensocial or oauth parameters");
+        throw new OAuthRequestException(OAuthError.INVALID_PARAMETER, name);
       }
     }
     return list;
@@ -399,35 +393,31 @@ public class OAuthRequest {
         canonParamName.startsWith("opensocial")) &&
         ALLOWED_PARAM_NAME.matcher(canonParamName).matches());
   }
-  
+
   /**
    * This gives a chance to override parameters by passing trusted parameters.
-   * 
+   *
    */
   private void overrideParameters(List<Parameter> authParams)
     throws OAuthRequestException {
     if (trustedParams == null) {
       return;
     }
-    
+
     Map<String, String> paramMap = Maps.newLinkedHashMap();
     for (Parameter param : authParams) {
       paramMap.put(param.getKey(), param.getValue());
     }
     for (Parameter param : trustedParams) {
       if (!isContainerInjectedParameter(param.getKey())) {
-        throw responseParams.oauthRequestException(
-            OAuthError.INVALID_REQUEST,
-            "invalid trusted parameter name " 
-            + param.getKey() 
-            + ", trusted parameter must start with 'oauth' 'xoauth'or 'opensocial' ");         
+        throw new OAuthRequestException(OAuthError.INVALID_TRUSTED_PARAMETER, param.getKey());
       }
-      paramMap.put(param.getKey(), param.getValue());    
+      paramMap.put(param.getKey(), param.getValue());
     }
-    
+
     authParams.clear();
-    for (String key : paramMap.keySet()) {
-      authParams.add(new Parameter(key, paramMap.get(key)));
+    for (Entry<String, String> entry : paramMap.entrySet()) {
+      authParams.add(new Parameter(entry.getKey(), entry.getValue()));
     }
   }
 
@@ -462,7 +452,7 @@ public class OAuthRequest {
     if (appUrl != null) {
       params.add(new Parameter(OPENSOCIAL_APPURL, appUrl));
     }
-    
+
     if (realRequest.getOAuthArguments().isProxiedContentRequest()) {
       params.add(new Parameter(OPENSOCIAL_PROXIED_CONTENT, "1"));
     }
@@ -531,7 +521,7 @@ public class OAuthRequest {
           params.addAll(sanitize(OAuth.decodeForm(base.getPostBodyAsString())));
         } catch (IllegalArgumentException e) {
           // Occurs if OAuth.decodeForm finds an invalid URL to decode.
-          throw responseParams.oauthRequestException(OAuthError.INVALID_REQUEST,
+          throw new OAuthRequestException(OAuthError.INVALID_REQUEST,
               "Could not decode body", e);
         }
         break;
@@ -542,7 +532,7 @@ public class OAuthRequest {
           String b64 = new String(Base64.encodeBase64(hash), CharsetUtil.UTF8.name());
           params.add(new Parameter(OAuthConstants.OAUTH_BODY_HASH, b64));
         } catch (IOException e) {
-          throw responseParams.oauthRequestException(OAuthError.UNKNOWN_PROBLEM,
+          throw new OAuthRequestException(OAuthError.UNKNOWN_PROBLEM,
               "Error taking body hash", e);
         }
         break;
@@ -551,13 +541,13 @@ public class OAuthRequest {
     // authParams are parameters prefixed with 'xoauth' 'oauth' or 'opensocial',
     // trusted parameters have ability to override these parameters.
     List<Parameter> authParams = Lists.newArrayList();
-    
+
     addIdentityParams(authParams);
 
     addSignatureParams(authParams);
-    
+
     overrideParameters(authParams);
-    
+
     params.addAll(authParams);
 
     try {
@@ -568,7 +558,7 @@ public class OAuthRequest {
       oauthHttpRequest.setFollowRedirects(false);
       return oauthHttpRequest;
     } catch (OAuthException e) {
-      throw responseParams.oauthRequestException(OAuthError.UNKNOWN_PROBLEM,
+      throw new OAuthRequestException(OAuthError.UNKNOWN_PROBLEM,
           "Error signing message", e);
     }
   }
@@ -600,8 +590,8 @@ public class OAuthRequest {
       case POST_BODY:
         String contentType = result.getHeader("Content-Type");
         if (!OAuth.isFormEncoded(contentType)) {
-          throw responseParams.oauthRequestException(OAuthError.INVALID_REQUEST,
-              "OAuth param location can only be post_body if post body if of " +
+          throw new OAuthRequestException(OAuthError.INVALID_REQUEST,
+              "OAuth param location can only be post_body if it is of " +
               "type x-www-form-urlencoded");
         }
         String oauthData = OAuthUtil.formEncode(oauthParams);
@@ -640,12 +630,12 @@ public class OAuthRequest {
     reply.addParameters(OAuth.decodeForm(response.getResponseAsString()));
     reply = parseAuthHeader(reply, response);
     if (OAuthUtil.getParameter(reply, OAuth.OAUTH_TOKEN) == null) {
-      throw responseParams.oauthRequestException(OAuthError.UNKNOWN_PROBLEM,
-          "No oauth_token returned from service provider");
+      throw new OAuthRequestException(OAuthError.MISSING_OAUTH_PARAMETER,
+          OAuth.OAUTH_TOKEN);
     }
     if (OAuthUtil.getParameter(reply, OAuth.OAUTH_TOKEN_SECRET) == null) {
-      throw responseParams.oauthRequestException(OAuthError.UNKNOWN_PROBLEM,
-          "No oauth_token_secret returned from service provider");
+      throw new OAuthRequestException(OAuthError.MISSING_OAUTH_PARAMETER,
+          OAuth.OAUTH_TOKEN_SECRET);
     }
     return reply;
   }
@@ -687,8 +677,8 @@ public class OAuthRequest {
     // We add the token, gadget is responsible for the callback URL.
     OAuthAccessor accessor = accessorInfo.getAccessor();
     if (accessor.consumer.serviceProvider.userAuthorizationURL == null) {
-      throw responseParams.oauthRequestException(OAuthError.BAD_OAUTH_CONFIGURATION,
-          "No authorization URL specified");
+      throw new OAuthRequestException(OAuthError.BAD_OAUTH_TOKEN_URL,
+          "authorization");
     }
     StringBuilder azn = new StringBuilder(
         accessor.consumer.serviceProvider.userAuthorizationURL);
@@ -731,9 +721,9 @@ public class OAuthRequest {
       accessorInfo.getAccessor().accessToken = null;
     }
     OAuthAccessor accessor = accessorInfo.getAccessor();
+
     if (accessor.consumer.serviceProvider.accessTokenURL == null) {
-      throw responseParams.oauthRequestException(OAuthError.BAD_OAUTH_CONFIGURATION,
-          "No access token URL specified.");
+      throw new OAuthRequestException(OAuthError.BAD_OAUTH_TOKEN_URL, "access token");
     }
     Uri accessTokenUri = Uri.parse(accessor.consumer.serviceProvider.accessTokenURL);
     HttpRequest request = new HttpRequest(accessTokenUri);
@@ -752,12 +742,12 @@ public class OAuthRequest {
     if (!StringUtils.isBlank(receivedCallback)) {
       try {
         Uri parsed = Uri.parse(receivedCallback);
-        String verifier = parsed.getQueryParameter(OAuthConstants.OAUTH_VERIFIER);
+        String verifier = parsed.getQueryParameter(OAuth.OAUTH_VERIFIER);
         if (verifier != null) {
-          msgParams.add(new Parameter(OAuthConstants.OAUTH_VERIFIER, verifier));
+          msgParams.add(new Parameter(OAuth.OAUTH_VERIFIER, verifier));
         }
       } catch (IllegalArgumentException e) {
-        throw responseParams.oauthRequestException(OAuthError.INVALID_REQUEST,
+        throw new OAuthRequestException(OAuthError.INVALID_REQUEST,
             "Invalid received callback URL: " + receivedCallback, e);
       }
     }
@@ -856,13 +846,11 @@ public class OAuthRequest {
     try {
       response = fetcher.fetch(request);
       if (response == null) {
-        throw responseParams.oauthRequestException(OAuthError.UNKNOWN_PROBLEM,
-            "No response from server");
+        throw new OAuthRequestException(OAuthError.MISSING_SERVER_RESPONSE);
       }
       return response;
     } catch (GadgetException e) {
-      throw responseParams.oauthRequestException(
-          OAuthError.UNKNOWN_PROBLEM, "No response from server", e);
+      throw new OAuthRequestException(OAuthError.MISSING_SERVER_RESPONSE, "", e);
     } finally {
       responseParams.addRequestTrace(request, response);
     }

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/OAuthResponseParams.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/OAuthResponseParams.java?rev=950443&r1=950442&r2=950443&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/OAuthResponseParams.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/OAuthResponseParams.java Wed Jun  2 09:04:51 2010
@@ -20,7 +20,6 @@
 package org.apache.shindig.gadgets.oauth;
 
 import com.google.common.collect.Lists;
-import com.google.common.base.Preconditions;
 
 import org.apache.shindig.auth.SecurityToken;
 import org.apache.shindig.common.Pair;
@@ -41,7 +40,6 @@ import java.util.regex.Pattern;
  * Container for OAuth specific data to include in the response to the client.
  */
 public class OAuthResponseParams {
-
   private static final Logger logger = Logger.getLogger(OAuthResponseParams.class.getName());
 
   // Finds the values of sensitive response params: oauth_token_secret and oauth_session_handle
@@ -80,16 +78,6 @@ public class OAuthResponseParams {
   private String aznUrl;
 
   /**
-   * Error code for the client.
-   */
-  private String error;
-
-  /**
-   * Error text for the client.
-   */
-  private String errorText;
-
-  /**
    * Whether we should include the request trace in the response to the application.
    *
    * It might be nice to make this configurable based on options passed to makeRequest.  For now
@@ -111,18 +99,24 @@ public class OAuthResponseParams {
    * Log a warning message that includes the details of the request.
    */
   public void logDetailedWarning(String note) {
-    logger.log(Level.WARNING, note + '\n' + getDetails());
+    if (logger.isLoggable(Level.WARNING)) {
+      logger.log(Level.WARNING, note + '\n' + getDetails(null));
+    }
   }
 
   /**
    * Log a warning message that includes the details of the request and the thrown exception.
    */
-  public void logDetailedWarning(String note, Throwable cause) {
-    logger.log(Level.WARNING, note + '\n' + getDetails(), cause);
+  public void logDetailedWarning(String note, Throwable e) {
+    if (logger.isLoggable(Level.WARNING)) {
+      logger.log(Level.WARNING, note + '\n' + getDetails(e), e);
+    }
   }
   
-  public void logDetailedInfo(String note, Throwable cause) {
-    logger.log(Level.INFO, note + '\n' + getDetails(), cause);
+  public void logDetailedInfo(String note, Throwable e) {
+    if (logger.isLoggable(Level.INFO)) {    
+      logger.log(Level.INFO, note + '\n' + getDetails(e), e);
+    }
   }
 
   /**
@@ -144,9 +138,21 @@ public class OAuthResponseParams {
     return false;
   }
 
-  private String getDetails() {
-    return "OAuth error [" + error + ", " + errorText + "] for application " +
-        securityToken.getAppUrl() + ".  Request trace:" + getRequestTrace();
+  private String getDetails(Throwable e) {
+    String error = null;
+
+    if (null != e) {
+      if(e instanceof OAuthRequestException) {
+        OAuthRequestException reqException = ((OAuthRequestException) e);
+        error = reqException.getError() + ", " + reqException.getErrorText();
+      }
+      else {
+        error = e.getMessage();
+      }
+    }
+    
+    return "OAuth error [" + error + "] for application "
+        + securityToken.getAppUrl() + ".  Request trace:" + getRequestTrace();
   }
 
   private String getRequestTrace() {
@@ -156,11 +162,11 @@ public class OAuthResponseParams {
     trace.append("\n====");
     int i = 1;
     for (Pair<HttpRequest, HttpResponse> event : requestTrace) {
-      trace.append("\n==== Sent request " + i + ":\n");
+      trace.append("\n==== Sent request ").append(i).append(":\n");
       if (event.one != null) {
         trace.append(filterSecrets(event.one.toString()));
       }
-      trace.append("\n==== Received response " + i + ":\n");
+      trace.append("\n==== Received response ").append(i).append(":\n");
       if (event.two != null) {
         trace.append(filterSecrets(event.two.toString()));
       }
@@ -181,30 +187,31 @@ public class OAuthResponseParams {
   /**
    * Update a response with additional data to be returned to the application.
    */
-  public void addToResponse(HttpResponseBuilder response) {
+  public void addToResponse(HttpResponseBuilder response, OAuthRequestException e) {
     if (!newClientState.isEmpty()) {
       try {
         response.setMetadata(CLIENT_STATE, newClientState.getEncryptedState());
-      } catch (BlobCrypterException e) {
+      } catch (BlobCrypterException cryptException) {
         // Configuration error somewhere, this should never happen.
-        throw new RuntimeException(e);
+        throw new RuntimeException(cryptException);
       }
     }
     if (aznUrl != null) {
       response.setMetadata(APPROVAL_URL, aznUrl);
     }
-    if (error != null) {
-      response.setMetadata(ERROR_CODE, error);
-    }
-    if (errorText != null || sendTraceToClient) {
+
+    if (e != null || sendTraceToClient) {
       StringBuilder verboseError = new StringBuilder();
-      if (errorText != null) {
-        verboseError.append(errorText);
+      
+      if (e != null) {
+        response.setMetadata(ERROR_CODE, e.getError());
+        verboseError.append(e.getErrorText());
       }
       if (sendTraceToClient) {
         verboseError.append('\n');
         verboseError.append(getRequestTrace());
       }
+
       response.setMetadata(ERROR_TEXT, verboseError.toString());
     }
   }
@@ -234,53 +241,4 @@ public class OAuthResponseParams {
   public void setSendTraceToClient(boolean sendTraceToClient) {
     this.sendTraceToClient = sendTraceToClient;
   }
-
-  public String getError() {
-    return error;
-  }
-
-  public OAuthRequestException oauthRequestException(OAuthError error, String errorText) {
-    return oauthRequestException(error.toString(), errorText);
-  }
-
-  public OAuthRequestException oauthRequestException(OAuthError error, String errorText,
-      Throwable cause) {
-    return oauthRequestException(error.toString(), errorText, cause);
-  }
-
-  /**
-   * Create an exception and record information about the exception to be returned to the gadget.
-   */
-  public OAuthRequestException oauthRequestException(String error, String errorText) {
-    this.error = Preconditions.checkNotNull(error);
-    this.errorText = Preconditions.checkNotNull(errorText);
-    return new OAuthRequestException('[' + error + ',' + errorText + ']');
-  }
-
-  /**
-   * Create an exception and record information about the exception to be returned to the gadget.
-   */
-  public OAuthRequestException oauthRequestException(String error, String errorText,
-      Throwable cause) {
-    this.error = Preconditions.checkNotNull(error);
-    this.errorText = Preconditions.checkNotNull(errorText);
-    return new OAuthRequestException('[' + error + ',' + errorText + ']', cause);
-  }
-
-  /**
-   * Superclass for all exceptions thrown from OAuthRequest and friends.
-   *
-   * The constructors are private, use OAuthResponseParams.oauthRequestException to create this
-   * exception.  This makes sure that any exception thrown is also exposed to the calling gadget
-   * in a useful way.
-   */
-  public static class OAuthRequestException extends Exception {
-    private OAuthRequestException(String message) {
-      super(message);
-    }
-
-    private OAuthRequestException(String message, Throwable cause) {
-      super(message, cause);
-    }
-  }
 }

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/testing/FakeOAuthServiceProvider.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/testing/FakeOAuthServiceProvider.java?rev=950443&r1=950442&r2=950443&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/testing/FakeOAuthServiceProvider.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/testing/FakeOAuthServiceProvider.java Wed Jun  2 09:04:51 2010
@@ -27,6 +27,7 @@ import net.oauth.OAuthConsumer;
 import net.oauth.OAuthException;
 import net.oauth.OAuthMessage;
 import net.oauth.OAuthServiceProvider;
+import net.oauth.OAuthValidator;
 import net.oauth.SimpleOAuthValidator;
 import net.oauth.OAuth.Parameter;
 import net.oauth.signature.RSA_SHA1;
@@ -304,23 +305,23 @@ public class FakeOAuthServiceProvider im
       consumer = oauthConsumer;
     } else {
       return makeOAuthProblemReport(
-          OAuthConstants.PROBLEM_CONSUMER_KEY_UNKNOWN, "invalid consumer: " + requestConsumer,
+          OAuth.Problems.CONSUMER_KEY_UNKNOWN, "invalid consumer: " + requestConsumer,
           HttpResponse.SC_FORBIDDEN);
     }
     if (throttled) {
       return makeOAuthProblemReport(
-          OAuthConstants.PROBLEM_CONSUMER_KEY_REFUSED, "exceeded quota exhausted",
+          OAuth.Problems.CONSUMER_KEY_REFUSED, "exceeded quota exhausted",
           HttpResponse.SC_FORBIDDEN);
     }
     if (unauthorized) {
       return makeOAuthProblemReport(
-          OAuthConstants.PROBLEM_PERMISSION_DENIED, "user refused access",
+          OAuth.Problems.PERMISSION_DENIED, "user refused access",
           HttpResponse.SC_BAD_REQUEST);
     }
     if (rejectExtraParams) {
       String extra = hasExtraParams(info.message);
       if (extra != null) {
-        return makeOAuthProblemReport(OAuthConstants.PROBLEM_PARAMETER_REJECTED, extra,
+        return makeOAuthProblemReport(OAuth.Problems.PARAMETER_REJECTED, extra,
             HttpResponse.SC_BAD_REQUEST);
       }
     }
@@ -335,7 +336,7 @@ public class FakeOAuthServiceProvider im
         "oauth_token", requestToken,
         "oauth_token_secret", requestTokenSecret);
     if (callbackUrl != null) {
-      responseParams.add(new Parameter(OAuthConstants.OAUTH_CALLBACK_CONFIRMED, "true"));
+      responseParams.add(new Parameter(OAuth.OAUTH_CALLBACK_CONFIRMED, "true"));
     }
     return new HttpResponse(OAuth.formEncode(responseParams));
   }
@@ -513,7 +514,7 @@ public class FakeOAuthServiceProvider im
     state.setUserData(parsed.getQueryParam("user_data"));
     if (state.callbackUrl != null) {
       UriBuilder callback = UriBuilder.parse(state.callbackUrl);
-      callback.addQueryParameter(OAuthConstants.OAUTH_VERIFIER, state.verifier);
+      callback.addQueryParameter(OAuth.OAUTH_VERIFIER, state.verifier);
       return callback.toString();
     }
     return null;
@@ -571,19 +572,19 @@ public class FakeOAuthServiceProvider im
     String requestToken = info.message.getParameter("oauth_token");
     TokenState state = tokenState.get(requestToken);
     if (throttled) {
-      return makeOAuthProblemReport(OAuthConstants.PROBLEM_CONSUMER_KEY_REFUSED,
+      return makeOAuthProblemReport(OAuth.Problems.CONSUMER_KEY_REFUSED,
           "exceeded quota", HttpResponse.SC_FORBIDDEN);
     } else if (unauthorized) {
-      return makeOAuthProblemReport(OAuthConstants.PROBLEM_PERMISSION_DENIED,
+      return makeOAuthProblemReport(OAuth.Problems.PERMISSION_DENIED,
           "user refused access", HttpResponse.SC_UNAUTHORIZED);
     } else if (state == null) {
-      return makeOAuthProblemReport(OAuthConstants.PROBLEM_TOKEN_REJECTED,
+      return makeOAuthProblemReport(OAuth.Problems.TOKEN_REJECTED,
           "Unknown request token", HttpResponse.SC_UNAUTHORIZED);
     }   
     if (rejectExtraParams) {
       String extra = hasExtraParams(info.message);
       if (extra != null) {
-        return makeOAuthProblemReport(OAuthConstants.PROBLEM_PARAMETER_REJECTED,
+        return makeOAuthProblemReport(OAuth.Problems.PARAMETER_REJECTED,
             extra, HttpResponse.SC_BAD_REQUEST);
       }
     }
@@ -604,7 +605,7 @@ public class FakeOAuthServiceProvider im
       // Verify can refresh
       String sentHandle = info.message.getParameter("oauth_session_handle");
       if (sentHandle == null) {
-        return makeOAuthProblemReport(OAuthConstants.PROBLEM_PARAMETER_ABSENT,
+        return makeOAuthProblemReport(OAuth.Problems.PARAMETER_ABSENT,
             "no oauth_session_handle", HttpResponse.SC_BAD_REQUEST);
       }
       if (!sentHandle.equals(state.sessionHandle)) {
@@ -613,7 +614,7 @@ public class FakeOAuthServiceProvider im
       }
       state.renewToken();
     } else if (state.getState() == State.REVOKED){
-      return makeOAuthProblemReport(OAuthConstants.PROBLEM_TOKEN_REVOKED,
+      return makeOAuthProblemReport(OAuth.Problems.TOKEN_REVOKED,
           "Revoked access token can't be renewed", HttpResponse.SC_UNAUTHORIZED);
     } else {
       throw new Exception("Token in weird state " + state.getState());
@@ -653,18 +654,18 @@ public class FakeOAuthServiceProvider im
     } else if ("container.com".equals(consumerId)) {
       consumer = signedFetchConsumer;
     } else {
-      return makeOAuthProblemReport(OAuthConstants.PROBLEM_PARAMETER_MISSING,
+      return makeOAuthProblemReport(OAuth.Problems.PARAMETER_ABSENT,
           "oauth_consumer_key not found", HttpResponse.SC_BAD_REQUEST);
     }
     OAuthAccessor accessor = new OAuthAccessor(consumer);
     String responseBody = null;
     if (throttled) {
       return makeOAuthProblemReport(
-          OAuthConstants.PROBLEM_CONSUMER_KEY_REFUSED, "exceeded quota", HttpResponse.SC_FORBIDDEN);
+          OAuth.Problems.CONSUMER_KEY_REFUSED, "exceeded quota", HttpResponse.SC_FORBIDDEN);
     }
     if (unauthorized) {
       return makeOAuthProblemReport(
-          OAuthConstants.PROBLEM_PERMISSION_DENIED, "user refused access",
+          OAuth.Problems.PERMISSION_DENIED, "user refused access",
           HttpResponse.SC_UNAUTHORIZED);
     }
     if (consumer == oauthConsumer) {
@@ -673,7 +674,7 @@ public class FakeOAuthServiceProvider im
       TokenState state = tokenState.get(accessToken);
       if (state == null) {
         return makeOAuthProblemReport(
-            OAuthConstants.PROBLEM_TOKEN_REJECTED, "Access token unknown",
+            OAuth.Problems.TOKEN_REJECTED, "Access token unknown",
             HttpResponse.SC_UNAUTHORIZED);
       }
       // Check the signature
@@ -683,7 +684,7 @@ public class FakeOAuthServiceProvider im
 
       if (state.getState() != State.APPROVED) {
         return makeOAuthProblemReport(
-            OAuthConstants.PROBLEM_TOKEN_REVOKED, "User revoked permissions",
+            OAuth.Problems.TOKEN_REVOKED, "User revoked permissions",
             HttpResponse.SC_UNAUTHORIZED);
       }
       if (sessionExtension) {
@@ -721,7 +722,9 @@ public class FakeOAuthServiceProvider im
   
   private void validateMessage(OAuthAccessor accessor, MessageInfo info, boolean tokenEndpoint)
       throws OAuthException, IOException, URISyntaxException {
-    info.message.validateMessage(accessor, new FakeTimeOAuthValidator());
+    OAuthValidator validator = new FakeTimeOAuthValidator();
+    validator.validateMessage(info.message,accessor);
+    
     String bodyHash = info.message.getParameter("oauth_body_hash");
     if (tokenEndpoint && bodyHash != null) {
       throw new RuntimeException("Can't have body hash on token endpoints");

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/parse/GadgetHtmlParser.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/parse/GadgetHtmlParser.java?rev=950443&r1=950442&r2=950443&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/parse/GadgetHtmlParser.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/parse/GadgetHtmlParser.java Wed Jun  2 09:04:51 2010
@@ -34,6 +34,7 @@ import org.w3c.dom.DOMException;
 import org.w3c.dom.DOMImplementation;
 import org.w3c.dom.Document;
 import org.w3c.dom.DocumentFragment;
+import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 
@@ -180,14 +181,14 @@ public abstract class GadgetHtmlParser {
       prependToNode(head, beforeHead);
       prependToNode(body, beforeBody);
       
-      // One exception. <style> nodes from <body> end up at the end of <head>, since doing so
-      // is HTML compliant and can never break rendering due to ordering concerns.
+      // One exception. <style>/<link rel="stylesheet" nodes from <body> end up at the end of <head>,
+      // since doing so is HTML compliant and can never break rendering due to ordering concerns.
       LinkedList<Node> styleNodes = Lists.newLinkedList();
       NodeList bodyKids = body.getChildNodes();
       for (int i = 0; i < bodyKids.getLength(); ++i) {
         Node bodyKid = bodyKids.item(i);
         if (bodyKid.getNodeType() == Node.ELEMENT_NODE &&
-            "style".equalsIgnoreCase(bodyKid.getNodeName())) {
+            isStyleElement((Element)bodyKid)) {
           styleNodes.add(bodyKid);
         }
       }
@@ -224,6 +225,13 @@ public abstract class GadgetHtmlParser {
       to.insertBefore(from.removeLast(), to.getFirstChild());
     }
   }
+  
+  private boolean isStyleElement(Element elem) {
+    return "style".equalsIgnoreCase(elem.getNodeName()) ||
+           ("link".equalsIgnoreCase(elem.getNodeName()) &&
+            ("stylesheet".equalsIgnoreCase(elem.getAttribute("rel")) ||
+             elem.getAttribute("type").toLowerCase().contains("css")));
+  }
 
   /**
    * Parses a snippet of markup and appends the result as children to the 

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/parse/caja/CajaCssUtils.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/parse/caja/CajaCssUtils.java?rev=950443&r1=950442&r2=950443&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/parse/caja/CajaCssUtils.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/parse/caja/CajaCssUtils.java Wed Jun  2 09:04:51 2010
@@ -27,8 +27,9 @@ import java.util.List;
 /**
  * Utility functions for traversing Caja's CSS DOM
  */
-class CajaCssUtils {
- 
+public final class CajaCssUtils {
+  private CajaCssUtils() {}
+  
   /**
    * Get the immediate children of the passed node with the specified node type
    */

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/parse/caja/CajaHtmlParser.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/parse/caja/CajaHtmlParser.java?rev=950443&r1=950442&r2=950443&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/parse/caja/CajaHtmlParser.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/parse/caja/CajaHtmlParser.java Wed Jun  2 09:04:51 2010
@@ -89,8 +89,21 @@ public class CajaHtmlParser extends Gadg
       throws GadgetException {
     try {
       MessageQueue mq = makeMessageQueue();
-      DomParser parser = getDomParser(source, mq);
+      // Newline works around Caja parser issue with certain short-form
+      // HTML - the internal Lexer gets confused. A bug has been filed w/ Caja.
+      // Even so, adding the newline is innocuous for any HTML.
+      DomParser parser = getDomParser(source + '\n', mq);
       DocumentFragment fragment = parser.parseFragment();
+      // Get rid of the newline, if maintained.
+      Node lastChild = fragment != null ? fragment.getLastChild() : null;
+      if (lastChild != null && lastChild.getNodeType() == Node.TEXT_NODE) {
+        String lastText = lastChild.getTextContent();
+        if ("\n".equals(lastText)) {
+          fragment.removeChild(lastChild);
+        } else if (lastText.endsWith("\n")) {
+          lastChild.setTextContent(lastText.substring(0, lastText.length() - 1));
+        }
+      }
       if (mq.hasMessageAtLevel(MessageLevel.ERROR)) {
         StringBuilder err = new StringBuilder();
         for (Message m : mq.getMessages()) {

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/preload/PipelineExecutor.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/preload/PipelineExecutor.java?rev=950443&r1=950442&r2=950443&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/preload/PipelineExecutor.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/preload/PipelineExecutor.java Wed Jun  2 09:04:51 2010
@@ -129,7 +129,7 @@ public class PipelineExecutor {
             
             String id = (String) JsonUtil.getProperty(entry, "id");
 
-            Object data = JsonUtil.getProperty(entry, "data");
+            Object data = JsonUtil.getProperty(entry, "result");
             if (data != null) {
               elResults.put(id, data);
             } else {

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/preload/PipelinedDataPreloader.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/preload/PipelinedDataPreloader.java?rev=950443&r1=950442&r2=950443&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/preload/PipelinedDataPreloader.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/preload/PipelinedDataPreloader.java Wed Jun  2 09:04:51 2010
@@ -60,7 +60,7 @@ public class PipelinedDataPreloader {
   private final RequestPipeline requestPipeline;
   private final ContainerConfig config;
 
-  private static Set<String> HTTP_RESPONSE_HEADERS =
+  private static final Set<String> HTTP_RESPONSE_HEADERS =
     ImmutableSet.of("content-type", "location", "set-cookie");
 
   @Inject
@@ -121,7 +121,7 @@ public class PipelinedDataPreloader {
 
     public VariableTask(String key, Object data) {
       this.result = (data == null) ? ImmutableMap.of("id", (Object) key)
-          : ImmutableMap.of("id", key, "data", data); 
+          : ImmutableMap.of("id", key, "result", data); 
     }
 
     public PreloadedData call() throws Exception {
@@ -284,7 +284,7 @@ public class PipelinedDataPreloader {
           } else {
             // Create {data: {status: [CODE], content: {...}|[...]|"...", headers:{...}}}
             JSONObject data = new JSONObject();
-            wrapper.put("data", data);
+            wrapper.put("result", data);
 
             // Add the status
             data.put("status", response.getHttpStatusCode());
@@ -305,8 +305,8 @@ public class PipelinedDataPreloader {
                   data.put("content", new JSONObject(responseText));
                 }
               } catch (JSONException je) {
-                // JSON parse failed: create a 406 error, and remove the "data" section
-                wrapper.remove("data");
+                // JSON parse failed: create a 406 error, and remove the "result" section
+                wrapper.remove("result");
                 wrapper.put("error", createJsonError(
                     HttpResponse.SC_NOT_ACCEPTABLE, je.getMessage(), response));
               }

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/DefaultServiceFetcher.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/DefaultServiceFetcher.java?rev=950443&r1=950442&r2=950443&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/DefaultServiceFetcher.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/DefaultServiceFetcher.java Wed Jun  2 09:04:51 2010
@@ -50,7 +50,7 @@ public class DefaultServiceFetcher {
 
   static final Logger logger = Logger.getLogger(Renderer.class.getName());
 
-  static final String JSON_RESPONSE_WRAPPER_ELEMENT = "data";
+  static final String JSON_RESPONSE_WRAPPER_ELEMENT = "result";
 
   static final String OSAPI_FEATURE_CONFIG = "osapi";
 

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/ProxyRenderer.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/ProxyRenderer.java?rev=950443&r1=950442&r2=950443&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/ProxyRenderer.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/ProxyRenderer.java Wed Jun  2 09:04:51 2010
@@ -151,7 +151,7 @@ public class ProxyRenderer {
     if (userAgent != null) {
       String myIdent = getUAIdent();
       if (myIdent != null) {
-        userAgent = userAgent + " " + myIdent;
+        userAgent = userAgent + ' ' + myIdent;
       }
       request.setHeader("User-Agent", userAgent);
     }

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

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingResults.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingResults.java?rev=950443&r1=950442&r2=950443&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingResults.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingResults.java Wed Jun  2 09:04:51 2010
@@ -27,7 +27,7 @@ import javax.servlet.http.HttpServletRes
 /**
  * Contains the results of a rendering operation.
  */
-public class RenderingResults {
+public final class RenderingResults {
   private final Status status;
   private final String content;
   private final String errorMessage;

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/SanitizingGadgetRewriter.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/SanitizingGadgetRewriter.java?rev=950443&r1=950442&r2=950443&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/SanitizingGadgetRewriter.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/SanitizingGadgetRewriter.java Wed Jun  2 09:04:51 2010
@@ -65,7 +65,7 @@ public class SanitizingGadgetRewriter ex
    * @return true if sanitization will be enabled
    */
   public static boolean isSanitizedRenderingRequest(Gadget gadget) {
-    return ("1".equals(gadget.getContext().getParameter("sanitize")));
+    return "1".equals(gadget.getContext().getParameter("sanitize"));
   }
   
   /**
@@ -211,7 +211,7 @@ public class SanitizingGadgetRewriter ex
   /**
    * Restrict the set of allowed tags and attributes
    */
-  static class BasicElementFilter extends SanitizingWalker {
+  static final class BasicElementFilter extends SanitizingWalker {
     private final Set<String> allowedTags;
     private final Set<String> allowedAttributes;
     
@@ -265,7 +265,7 @@ public class SanitizingGadgetRewriter ex
    * Enfore that all images in the document are rewritten through the proxy.
    * Prevents issues in IE where the image content contains script
    */
-  static class ImageFilter extends SanitizingWalker {
+  static final class ImageFilter extends SanitizingWalker {
     private final SanitizingProxyUriManager imageRewriter;
 
     private ImageFilter(ProxyUriManager proxyUriManager) {
@@ -298,7 +298,7 @@ public class SanitizingGadgetRewriter ex
   /**
    * Pass the contents of style tags through the CSS sanitizer
    */
-  static class StyleFilter implements DomWalker.Visitor {
+  static final class StyleFilter implements DomWalker.Visitor {
     private final SanitizingProxyUriManager imageRewriter;
     private final SanitizingProxyUriManager cssImportRewriter;
     private final CajaCssSanitizer cssSanitizer;
@@ -328,7 +328,7 @@ public class SanitizingGadgetRewriter ex
    * Restrict link tags to stylesheet content only and force the link to
    * be rewritten through the proxy and sanitized
    */
-  static class LinkFilter extends SanitizingWalker {
+  static final class LinkFilter extends SanitizingWalker {
     private final SanitizingProxyUriManager cssImportRewriter;
 
     private LinkFilter(ProxyUriManager proxyUriManager) {

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/old/SanitizingGadgetRewriter.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/old/SanitizingGadgetRewriter.java?rev=950443&r1=950442&r2=950443&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/old/SanitizingGadgetRewriter.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/old/SanitizingGadgetRewriter.java Wed Jun  2 09:04:51 2010
@@ -36,7 +36,6 @@ import org.w3c.dom.Element;
 import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
-import org.w3c.dom.UserDataHandler;
 
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
@@ -57,26 +56,14 @@ import java.util.Set;
  * rendering, OSML, etc.)
  */
 public class SanitizingGadgetRewriter implements GadgetRewriter {
-
-  /** Key stored as element user-data to bypass sanitization */
-  private static final String BYPASS_SANITIZATION_KEY = "shindig.bypassSanitization";
-
   /**
    * Is the Gadget to be rendered sanitized?
    * @return true if sanitization will be enabled
    */
   public static boolean isSanitizedRenderingRequest(Gadget gadget) {
-    return ("1".equals(gadget.getContext().getParameter("sanitize")));
+    return "1".equals(gadget.getContext().getParameter("sanitize"));
   }
   
-  private static UserDataHandler copyOnClone = new UserDataHandler() {
-    public void handle(short operation, String key, Object data, Node src, Node dst) {
-      if (operation == NODE_IMPORTED || operation == NODE_CLONED) {
-        dst.setUserData(key, data, copyOnClone);
-      }
-    }
-  };
-  
   private final Set<String> allowedTags;
   private final Set<String> allowedAttributes;
   private final CajaCssSanitizer cssSanitizer;

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/old/SanitizingRequestRewriter.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/old/SanitizingRequestRewriter.java?rev=950443&r1=950442&r2=950443&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/old/SanitizingRequestRewriter.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/old/SanitizingRequestRewriter.java Wed Jun  2 09:04:51 2010
@@ -24,11 +24,10 @@ import org.apache.sanselan.ImageReadExce
 import org.apache.sanselan.Sanselan;
 import org.apache.sanselan.common.byteSources.ByteSourceInputStream;
 import org.apache.shindig.gadgets.http.HttpRequest;
-import org.apache.shindig.gadgets.http.HttpResponse;
+import org.apache.shindig.gadgets.http.HttpResponseBuilder;
 import org.apache.shindig.gadgets.parse.caja.old.CajaCssSanitizer;
 import org.apache.shindig.gadgets.rewrite.ContentRewriterFeature;
-import org.apache.shindig.gadgets.rewrite.MutableContent;
-import org.apache.shindig.gadgets.rewrite.RequestRewriter;
+import org.apache.shindig.gadgets.rewrite.ResponseRewriter;
 
 import java.io.IOException;
 import java.util.logging.Level;
@@ -39,7 +38,7 @@ import com.google.inject.Inject;
 /**
  * Rewriter that sanitizes CSS and image content.
  */
-public class SanitizingRequestRewriter implements RequestRewriter {
+public class SanitizingRequestRewriter implements ResponseRewriter {
   private static final Logger logger =
     Logger.getLogger(SanitizingRequestRewriter.class.getName());
 
@@ -57,7 +56,7 @@ public class SanitizingRequestRewriter i
     this.sanitizingProxyingLinkRewriterFactory = sanitizingProxyingLinkRewriterFactory;
   }
 
-  public boolean rewrite(HttpRequest request, HttpResponse resp, MutableContent content) {
+  public void rewrite(HttpRequest request, HttpResponseBuilder resp) {
     // Content fetched through the proxy can stipulate that it must be sanitized.
     if (request.isSanitizationRequested()) {
       ContentRewriterFeature.Config rewriterFeature =
@@ -65,22 +64,17 @@ public class SanitizingRequestRewriter i
       if (StringUtils.isEmpty(request.getRewriteMimeType())) {
         logger.log(Level.WARNING, "Request to sanitize without content type for "
             + request.getUri());
-        content.setContent("");
-        return true;
+        resp.setContent("");
       } else if (request.getRewriteMimeType().equalsIgnoreCase("text/css")) {
-        return rewriteProxiedCss(request, resp, content, rewriterFeature);
+        rewriteProxiedCss(request, resp, rewriterFeature);
       } else if (request.getRewriteMimeType().toLowerCase().startsWith("image/")) {
-        return rewriteProxiedImage(request, resp, content);
+        rewriteProxiedImage(request, resp);
       } else {
         logger.log(Level.WARNING, "Request to sanitize unknown content type "
             + request.getRewriteMimeType()
             + " for " + request.getUri());
-        content.setContent("");
-        return true;
+        resp.setContent("");
       }
-    } else {
-      // No Op
-      return false;
     }
   }
 
@@ -88,8 +82,7 @@ public class SanitizingRequestRewriter i
    * We don't actually rewrite the image we just ensure that it is in fact a valid
    * and known image type.
    */
-  private boolean rewriteProxiedImage(HttpRequest request, HttpResponse resp,
-      MutableContent content) {
+  private void rewriteProxiedImage(HttpRequest request, HttpResponseBuilder resp) {
     boolean imageIsSafe = false;
     try {
       String contentType = resp.getHeader("Content-Type");
@@ -97,30 +90,30 @@ public class SanitizingRequestRewriter i
         // Unspecified or unknown image mime type.
         try {
           ImageFormat imageFormat = Sanselan
-          .guessFormat(new ByteSourceInputStream(resp.getResponse(),
-              request.getUri().getPath()));
+              .guessFormat(new ByteSourceInputStream(resp.getContentBytes(),
+                  request.getUri().getPath()));
           if (imageFormat == ImageFormat.IMAGE_FORMAT_UNKNOWN) {
             logger.log(Level.INFO, "Unable to sanitize unknown image type "
                 + request.getUri().toString());
-            return true;
+            return;
           }
           imageIsSafe = true;
           // Return false to indicate that no rewriting occurred
-          return false;
+          return;
         } catch (IOException ioe) {
           throw new RuntimeException(ioe);
         } catch (ImageReadException ire) {
           // Unable to read the image so its not safe
           logger.log(Level.INFO, "Unable to detect image type for " +request.getUri().toString() +
               " for sanitized content", ire);
-          return true;
+          return;
         }
       } else {
-        return true;
+        return;
       }
     } finally {
       if (!imageIsSafe) {
-        content.setContent("");
+        resp.setContent("");
       }
     }
   }
@@ -128,8 +121,8 @@ public class SanitizingRequestRewriter i
   /**
    * Sanitize a CSS file.
    */
-  private boolean rewriteProxiedCss(HttpRequest request, HttpResponse response,
-      MutableContent content, ContentRewriterFeature.Config rewriterFeature) {
+  private void rewriteProxiedCss(HttpRequest request, HttpResponseBuilder response,
+      ContentRewriterFeature.Config rewriterFeature) {
     String sanitized = "";
     try {
       String contentType = response.getHeader("Content-Type");
@@ -140,15 +133,13 @@ public class SanitizingRequestRewriter i
         SanitizingProxyingLinkRewriter cssImageRewriter = sanitizingProxyingLinkRewriterFactory
             .create(request.getGadget(), rewriterFeature, request
                 .getContainer(), "image/*", false, request.getIgnoreCache());
-        sanitized = cssSanitizer.sanitize(content.getContent(), request.getUri(), cssImportRewriter,
-            cssImageRewriter);
+        sanitized = cssSanitizer.sanitize(response.getContent(), request.getUri(),
+            cssImportRewriter, cssImageRewriter);
       }
-      
-      return true;
     } finally {
       // Set sanitized content in finally to ensure it is always cleared in
       // the case of errors
-      content.setContent(sanitized);
+      response.setContent(sanitized);
     }
   }
 }

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/CaptureRewriter.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/CaptureRewriter.java?rev=950443&r1=950442&r2=950443&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/CaptureRewriter.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/CaptureRewriter.java Wed Jun  2 09:04:51 2010
@@ -20,19 +20,17 @@ package org.apache.shindig.gadgets.rewri
 
 import org.apache.shindig.gadgets.Gadget;
 import org.apache.shindig.gadgets.http.HttpRequest;
-import org.apache.shindig.gadgets.http.HttpResponse;
+import org.apache.shindig.gadgets.http.HttpResponseBuilder;
 
 /**
  * Utility rewriter for testing.
  */
-public class CaptureRewriter implements RequestRewriter, GadgetRewriter {
+public class CaptureRewriter implements ResponseRewriter, GadgetRewriter {
   private boolean rewroteView = false;
   private boolean rewroteResponse = false;
 
-  public boolean rewrite(HttpRequest request, HttpResponse original,
-      MutableContent content) {
+  public void rewrite(HttpRequest request, HttpResponseBuilder original) {
     rewroteResponse = true;
-    return true;
   }
 
   public boolean responseWasRewritten() {

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ContentRewriterFeature.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ContentRewriterFeature.java?rev=950443&r1=950442&r2=950443&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ContentRewriterFeature.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ContentRewriterFeature.java Wed Jun  2 09:04:51 2010
@@ -155,7 +155,8 @@ public class ContentRewriterFeature {
     
     // Lazily computed
     private Integer fingerprint;
-    
+    private static final Pattern COMMA_WHITESPACE_PATTERN = Pattern.compile("\\s*,\\s*");
+
     /**
      * Constructor which takes a gadget spec and container settings
      * as "raw" input strings.
@@ -180,7 +181,7 @@ public class ContentRewriterFeature {
 
       // Parse includeTags
       ImmutableSet.Builder<String> includeTagsBuilder = ImmutableSet.builder();
-      for (String s : paramTrim(defaultTags).toLowerCase().split("\\s*,\\s*")) {
+      for (String s : COMMA_WHITESPACE_PATTERN.split(paramTrim(defaultTags).toLowerCase())) {
         if (s != null && s.length() > 0) {
           includeTagsBuilder.add(s);
         }

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=950443&r1=950442&r2=950443&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 Wed Jun  2 09:04:51 2010
@@ -25,7 +25,7 @@ import org.apache.shindig.common.uri.Uri
 import org.apache.shindig.gadgets.Gadget;
 import org.apache.shindig.gadgets.GadgetContext;
 import org.apache.shindig.gadgets.http.HttpRequest;
-import org.apache.shindig.gadgets.http.HttpResponse;
+import org.apache.shindig.gadgets.http.HttpResponseBuilder;
 import org.apache.shindig.gadgets.spec.GadgetSpec;
 import org.apache.shindig.gadgets.uri.UriCommon.Param;
 
@@ -42,7 +42,9 @@ import java.util.Map;
  * 
  * See subclass doc for additional detail.
  */
-public class DomWalker {
+public final class DomWalker {
+  private DomWalker() {}
+
   /**
    * Implemented by classes that do actual manipulation of the DOM
    * while {@code DomWalker.ContentVisitor} walks it. {@code Visitor}
@@ -104,7 +106,7 @@ public class DomWalker {
    * will be revisited after the entire DOM tree is walked.
    * The DOM tree is walked in depth-first order.
    */
-  public static class Rewriter implements GadgetRewriter, RequestRewriter {
+  public static class Rewriter implements GadgetRewriter, ResponseRewriter {
     private final List<Visitor> visitors;
     
     public Rewriter(List<Visitor> visitors) {
@@ -133,13 +135,12 @@ public class DomWalker {
       rewrite(makeVisitors(gadget, gadget.getSpec().getUrl()), gadget, content);
     }
 
-    public boolean rewrite(HttpRequest request, HttpResponse original,
-        MutableContent content) throws RewritingException {
-      if (RewriterUtils.isHtml(request, original)) {
+    public void rewrite(HttpRequest request, HttpResponseBuilder builder)
+        throws RewritingException {
+      if (RewriterUtils.isHtml(request, builder)) {
         Gadget context = makeGadget(request);
-        return rewrite(makeVisitors(context, request.getGadget()), context, content);
+        rewrite(makeVisitors(context, request.getGadget()), context, builder);
       }
-      return false;
     }
     
     private boolean rewrite(List<Visitor> visitors, Gadget gadget, MutableContent content) 

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/MutableContent.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/MutableContent.java?rev=950443&r1=950442&r2=950443&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/MutableContent.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/MutableContent.java Wed Jun  2 09:04:51 2010
@@ -32,6 +32,7 @@ import java.io.UnsupportedEncodingExcept
 import java.util.Arrays;
 import java.util.Map;
 
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Maps;
 
 /**
@@ -39,13 +40,15 @@ import com.google.common.collect.Maps;
  * and a consistent view of those contents as an HTML parse tree.
  */
 public class MutableContent {
+  private static final Map<String, Object> EMPTY_MAP = ImmutableMap.of();
+
   private String content;
   private byte[] contentBytes;
   private HttpResponse contentSource;
   private Document document;
   private int numChanges;
   private final GadgetHtmlParser contentParser;
-  private final Map<String, Object> pipelinedData;
+  private Map<String, Object> pipelinedData;
 
   private static final String MUTABLE_CONTENT_LISTENER = "MutableContentListener";
 
@@ -63,7 +66,6 @@ public class MutableContent {
     this.contentParser = contentParser;
     this.content = content;
     this.numChanges = 0;
-    this.pipelinedData = Maps.newHashMap();
   }
 
   /**
@@ -73,7 +75,6 @@ public class MutableContent {
   public MutableContent(GadgetHtmlParser contentParser, HttpResponse contentSource) {
     this.contentParser = contentParser;
     this.contentSource = contentSource;
-    this.pipelinedData = Maps.newHashMap();
   }
 
   /**
@@ -221,10 +222,13 @@ public class MutableContent {
   }
   
   public void addPipelinedData(String key, Object value) {
+    if (null == pipelinedData) {
+      pipelinedData = Maps.newHashMap();
+    }
     pipelinedData.put(key, value);
   }
   
   public Map<String, Object> getPipelinedData() {
-    return pipelinedData;
+    return (null == pipelinedData) ? EMPTY_MAP : pipelinedData;
   }
 }

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/RewriteModule.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/RewriteModule.java?rev=950443&r1=950442&r2=950443&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/RewriteModule.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/RewriteModule.java Wed Jun  2 09:04:51 2010
@@ -25,10 +25,12 @@ import com.google.inject.Provides;
 import com.google.inject.Singleton;
 import com.google.inject.name.Named;
 
+import org.apache.shindig.gadgets.parse.GadgetHtmlParser;
 import org.apache.shindig.gadgets.render.OpenSocialI18NGadgetRewriter;
 import org.apache.shindig.gadgets.render.RenderingGadgetRewriter;
 import org.apache.shindig.gadgets.render.old.SanitizingGadgetRewriter;
 import org.apache.shindig.gadgets.render.old.SanitizingRequestRewriter;
+import org.apache.shindig.gadgets.rewrite.image.BasicImageRewriter;
 import org.apache.shindig.gadgets.rewrite.old.CssRequestRewriter;
 import org.apache.shindig.gadgets.rewrite.old.HTMLContentRewriter;
 import org.apache.shindig.gadgets.servlet.CajaContentRewriter;
@@ -56,7 +58,8 @@ public class RewriteModule extends Abstr
       SanitizingGadgetRewriter sanitizedRewriter,
       RenderingGadgetRewriter renderingRewriter,
       OpenSocialI18NGadgetRewriter i18nRewriter) {
-    return ImmutableList.of(pipelineRewriter, templateRewriter, optimizingRewriter, cajaRewriter, sanitizedRewriter, renderingRewriter, i18nRewriter);
+    return ImmutableList.of(pipelineRewriter, templateRewriter, optimizingRewriter,
+        cajaRewriter, sanitizedRewriter, renderingRewriter, i18nRewriter);
   }
 
   @Provides
@@ -67,10 +70,29 @@ public class RewriteModule extends Abstr
       CajaContentRewriter cajaRewriter) {
     return ImmutableList.of(optimizingRewriter, cajaRewriter);
   }
+  
+  // TODO: Clean this up. Ideally we would let the ResponseRewriterRegistry
+  // binding create the concrete object instance.
+  @Provides
+  @Singleton
+  @Named("shindig.rewriters.response.pre-cache")
+  protected ResponseRewriterRegistry providePreCacheResponseRewritersRegistry(
+      GadgetHtmlParser parser,
+      @Named("shindig.rewriters.response.pre-cache") List<ResponseRewriter> preCached) {
+    return new DefaultResponseRewriterRegistry(preCached, parser);
+  }
+
+  @Provides
+  @Singleton
+  @Named("shindig.rewriters.response.pre-cache")
+  protected List<ResponseRewriter> providePreCacheResponseRewriters(
+      BasicImageRewriter imageRewriter) {
+    return ImmutableList.<ResponseRewriter>of(imageRewriter);
+  }
 
   @Provides
   @Singleton
-  protected List<RequestRewriter> provideRequestRewriters(
+  protected List<ResponseRewriter> provideResponseRewriters(
       HTMLContentRewriter optimizingRewriter,
       CssRequestRewriter cssRewriter,
       SanitizingRequestRewriter sanitizedRewriter) {

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/RewriterUtils.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/RewriterUtils.java?rev=950443&r1=950442&r2=950443&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/RewriterUtils.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/RewriterUtils.java Wed Jun  2 09:04:51 2010
@@ -20,26 +20,43 @@ package org.apache.shindig.gadgets.rewri
 
 import org.apache.shindig.gadgets.http.HttpRequest;
 import org.apache.shindig.gadgets.http.HttpResponse;
+import org.apache.shindig.gadgets.http.HttpResponseBuilder;
 
 /**
  * Various utility functions used by rewriters
  */
-public class RewriterUtils {
+public final class RewriterUtils {
+  private RewriterUtils() {}
   
   public static boolean isHtml(HttpRequest request, HttpResponse original) {
     String mimeType = getMimeType(request, original);
     return mimeType != null && (mimeType.contains("html"));
   }
+  
+  public static boolean isHtml(HttpRequest request, HttpResponseBuilder original) {
+    String mimeType = getMimeType(request, original);
+    return mimeType != null && (mimeType.contains("html"));
+  }
 
   public static boolean isCss(HttpRequest request, HttpResponse original) {
     String mimeType = getMimeType(request, original);
     return mimeType != null && mimeType.contains("css");
   }
+  
+  public static boolean isCss(HttpRequest request, HttpResponseBuilder original) {
+    String mimeType = getMimeType(request, original);
+    return mimeType != null && mimeType.contains("css");
+  }
 
   public static boolean isJavascript(HttpRequest request, HttpResponse original) {
     String mimeType = getMimeType(request, original);
     return mimeType != null && mimeType.contains("javascript");
   }
+  
+  public static boolean isJavascript(HttpRequest request, HttpResponseBuilder original) {
+    String mimeType = getMimeType(request, original);
+    return mimeType != null && mimeType.contains("javascript");
+  }
 
   public static String getMimeType(HttpRequest request, HttpResponse original) {
     String mimeType = request.getRewriteMimeType();
@@ -48,4 +65,12 @@ public class RewriterUtils {
     }
     return mimeType != null ? mimeType.toLowerCase() : null;
   }
+
+  public static String getMimeType(HttpRequest request, HttpResponseBuilder original) {
+    String mimeType = request.getRewriteMimeType();
+    if (mimeType == null) {
+      mimeType = original.getHeader("Content-Type");
+    }
+    return mimeType != null ? mimeType.toLowerCase() : null;
+  }
 }

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/StyleTagExtractorContentRewriter.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/StyleTagExtractorContentRewriter.java?rev=950443&r1=950442&r2=950443&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/StyleTagExtractorContentRewriter.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/StyleTagExtractorContentRewriter.java Wed Jun  2 09:04:51 2010
@@ -33,12 +33,12 @@ import java.util.List;
 public class StyleTagExtractorContentRewriter extends DomWalker.Rewriter {
   private final ContentRewriterFeature.Factory featureConfigFactory;
   private final ProxyUriManager proxyUriManager;
-  private final CssRequestRewriter cssRewriter;
+  private final CssResponseRewriter cssRewriter;
   
   @Inject
   public StyleTagExtractorContentRewriter(ContentRewriterFeature.Factory featureConfigFactory,
       ConcatUriManager concatUriManager, ProxyUriManager proxyUriManager,
-      CssRequestRewriter cssRewriter) {
+      CssResponseRewriter cssRewriter) {
     this.featureConfigFactory = featureConfigFactory;
     this.proxyUriManager = proxyUriManager;
     this.cssRewriter = cssRewriter;

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/StyleTagExtractorVisitor.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/StyleTagExtractorVisitor.java?rev=950443&r1=950442&r2=950443&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/StyleTagExtractorVisitor.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/StyleTagExtractorVisitor.java Wed Jun  2 09:04:51 2010
@@ -31,11 +31,11 @@ import org.w3c.dom.Node;
 
 public class StyleTagExtractorVisitor implements Visitor {
   private final ContentRewriterFeature.Config config;
-  private final CssRequestRewriter cssRewriter;
+  private final CssResponseRewriter cssRewriter;
   private final ProxyUriManager proxyUriManager;
   
   public StyleTagExtractorVisitor(ContentRewriterFeature.Config config,
-      CssRequestRewriter cssRewriter, ProxyUriManager proxyUriManager) {
+      CssResponseRewriter cssRewriter, ProxyUriManager proxyUriManager) {
     this.config = config;
     this.cssRewriter = cssRewriter;
     this.proxyUriManager = proxyUriManager;
@@ -74,7 +74,7 @@ public class StyleTagExtractorVisitor im
       // Guaranteed safe cast due to reservation logic.
       Element elem = (Element)node;
       List<String> extractedUrls = cssRewriter.rewrite(
-          elem, contentBase, CssRequestRewriter.uriMaker(proxyUriManager, config), true);
+          elem, contentBase, CssResponseRewriter.uriMaker(proxyUriManager, config), true);
       for (String extractedUrl : extractedUrls) {
         // Add extracted urls as link elements to head
         Element newLink = head.getOwnerDocument().createElement("link");

Modified: shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/image/BMPOptimizer.java
URL: http://svn.apache.org/viewvc/shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/image/BMPOptimizer.java?rev=950443&r1=950442&r2=950443&view=diff
==============================================================================
--- shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/image/BMPOptimizer.java (original)
+++ shindig/branches/2.0.x/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/image/BMPOptimizer.java Wed Jun  2 09:04:51 2010
@@ -19,7 +19,7 @@ package org.apache.shindig.gadgets.rewri
 
 import org.apache.sanselan.ImageReadException;
 import org.apache.sanselan.Sanselan;
-import org.apache.shindig.gadgets.http.HttpResponse;
+import org.apache.shindig.gadgets.http.HttpResponseBuilder;
 
 import javax.imageio.ImageIO;
 import javax.imageio.ImageWriter;
@@ -37,8 +37,8 @@ public class BMPOptimizer extends PNGOpt
     return Sanselan.getBufferedImage(is);
   }
 
-  public BMPOptimizer(OptimizerConfig config, HttpResponse original) {
-    super(config, original);
+  public BMPOptimizer(OptimizerConfig config, HttpResponseBuilder response) {
+    super(config, response);
     ImageWriter writer = ImageIO.getImageWritersByFormatName("png").next();
     outputter = new ImageIOOutputter(writer, null);
   }

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=950443&r1=950442&r2=950443&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 Wed Jun  2 09:04:51 2010
@@ -20,7 +20,6 @@ package org.apache.shindig.gadgets.rewri
 import org.apache.sanselan.ImageFormat;
 import org.apache.sanselan.ImageWriteException;
 import org.apache.sanselan.Sanselan;
-import org.apache.shindig.gadgets.http.HttpResponse;
 import org.apache.shindig.gadgets.http.HttpResponseBuilder;
 
 import com.google.common.collect.ImmutableMap;
@@ -51,7 +50,7 @@ abstract class BaseOptimizer {
       "gif", ImageFormat.IMAGE_FORMAT_GIF,
       "jpeg", ImageFormat.IMAGE_FORMAT_JPEG);
 
-  final HttpResponse originalResponse;
+  final HttpResponseBuilder response;
   final OptimizerConfig config;
 
   protected ImageOutputter outputter;
@@ -60,10 +59,10 @@ abstract class BaseOptimizer {
   int reductionPct;
 
 
-  public BaseOptimizer(OptimizerConfig config, HttpResponse original) {
+  public BaseOptimizer(OptimizerConfig config, HttpResponseBuilder response) {
     this.config = config;
-    this.originalResponse = original;
-    this.minLength = original.getContentLength();
+    this.response = response;
+    this.minLength = response.getContentLength();
     this.outputter = getOutputter();
   }
 
@@ -92,14 +91,14 @@ abstract class BaseOptimizer {
     if (minLength > bytes.length) {
       minBytes = bytes;
       minLength = minBytes.length;
-      reductionPct = ((originalResponse.getContentLength() - minLength) * 100) /
-          originalResponse.getContentLength();
+      reductionPct = ((response.getContentLength() - minLength) * 100) /
+          response.getContentLength();
     }
   }
 
-  public HttpResponse rewrite(BufferedImage image) throws IOException {
+  public void rewrite(BufferedImage image) throws IOException {
     if (outputter == null) {
-      return originalResponse;
+      return;
     }
 
     long time = System.currentTimeMillis();
@@ -108,17 +107,16 @@ abstract class BaseOptimizer {
     if (minBytes != null && minBytes.length != 0) {
       StringBuilder rewriteMsg = new StringBuilder(24);
       rewriteMsg.append("c=").append(
-          ((minBytes.length * 100) / originalResponse.getContentLength()));
+          ((minBytes.length * 100) / response.getContentLength()));
       if (!getOutputContentType().equals(getOriginalContentType())) {
         rewriteMsg.append(";o=").append(getOriginalContentType());
       }
       rewriteMsg.append(";t=").append(time);
-      return new HttpResponseBuilder(originalResponse)
+      response.clearAllHeaders()
           .setHeader("Content-Type", getOutputContentType())
           .setHeader("X-Shindig-Rewrite", rewriteMsg.toString())
-          .setResponse(minBytes).create();
+          .setResponse(minBytes);
     }
-    return originalResponse;
   }
 
   /**