You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shindig.apache.org by lr...@apache.org on 2008/05/20 01:05:00 UTC
svn commit: r658031 - in /incubator/shindig/trunk/java: gadgets/conf/
gadgets/src/main/java/org/apache/shindig/gadgets/
gadgets/src/main/java/org/apache/shindig/gadgets/http/
gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/
gadgets/src/main/ja...
Author: lryan
Date: Mon May 19 16:04:59 2008
New Revision: 658031
URL: http://svn.apache.org/viewvc?rev=658031&view=rev
Log:
Initial content-rewrite implementation
Added:
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ContentRewriter.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ContentRewriterFeature.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/CssRewriter.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/DefaultContentRewriter.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/HtmlRewriter.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/HtmlTagTransformer.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/JavascriptTagMerger.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/LinkRewriter.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/LinkingTagRewriter.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/NoOpContentRewriter.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ProxyingLinkRewriter.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/StyleTagRewriter.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/ConcatProxyServlet.java
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/CssRewriterTest.java
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/HtmlRewriterTest.java
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/JavascriptTagMergerTest.java
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/LinkingTagRewriterTest.java
Modified:
incubator/shindig/trunk/java/gadgets/conf/gadgets.properties
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/BasicGadgetSpecFactory.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/DefaultGuiceModule.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServer.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/BasicHttpFetcher.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/HttpRequest.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/HttpResponse.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/ProxyHandler.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/GadgetSpec.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/View.java
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetTestFixture.java
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/HttpTestFixture.java
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/spec/GadgetSpecTest.java
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/spec/ViewTest.java
incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.full.xml
incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.gadgets.xml
incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.xml
Modified: incubator/shindig/trunk/java/gadgets/conf/gadgets.properties
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/conf/gadgets.properties?rev=658031&r1=658030&r2=658031&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/conf/gadgets.properties (original)
+++ incubator/shindig/trunk/java/gadgets/conf/gadgets.properties Mon May 19 16:04:59 2008
@@ -7,4 +7,5 @@
signing.key-file=
locked-domain.enabled=false
locked-domain.embed-host=127.0.0.1:8080
+content-rewrite.enabled=true
cache.capacity=10000
Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/BasicGadgetSpecFactory.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/BasicGadgetSpecFactory.java?rev=658031&r1=658030&r2=658031&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/BasicGadgetSpecFactory.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/BasicGadgetSpecFactory.java Mon May 19 16:04:59 2008
@@ -18,12 +18,16 @@
*/
package org.apache.shindig.gadgets;
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+
import org.apache.shindig.gadgets.http.HttpFetcher;
import org.apache.shindig.gadgets.http.HttpRequest;
import org.apache.shindig.gadgets.http.HttpResponse;
+import org.apache.shindig.gadgets.rewrite.ContentRewriter;
+import org.apache.shindig.gadgets.rewrite.ContentRewriterFeature;
import org.apache.shindig.gadgets.spec.GadgetSpec;
-
-import com.google.inject.Inject;
+import org.apache.shindig.gadgets.spec.View;
import java.net.URI;
@@ -32,7 +36,9 @@
*/
public class BasicGadgetSpecFactory implements GadgetSpecFactory {
- private HttpFetcher specFetcher;
+ private final HttpFetcher specFetcher;
+ private final ContentRewriter rewriter;
+ private final boolean enableRewrite;
public GadgetSpec getGadgetSpec(GadgetContext context)
throws GadgetException {
@@ -52,11 +58,23 @@
}
GadgetSpec spec
= new GadgetSpec(gadgetUri, response.getResponseAsString());
+ if (new ContentRewriterFeature(spec, enableRewrite).isRewriteEnabled()) {
+ for (View v : spec.getViews().values()) {
+ if (v.getType() == View.ContentType.HTML && rewriter != null) {
+ v.setRewrittenContent(
+ rewriter.rewrite(gadgetUri, v.getContent(), "text/html"));
+ }
+ }
+ }
return spec;
}
@Inject
- public BasicGadgetSpecFactory(HttpFetcher specFetcher) {
+ public BasicGadgetSpecFactory(HttpFetcher specFetcher,
+ ContentRewriter rewriter,
+ @Named("content-rewrite.enabled") String defaultEnableRewrite) {
this.specFetcher = specFetcher;
+ this.rewriter = rewriter;
+ this.enableRewrite = Boolean.parseBoolean(defaultEnableRewrite);
}
-}
+}
\ No newline at end of file
Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/DefaultGuiceModule.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/DefaultGuiceModule.java?rev=658031&r1=658030&r2=658031&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/DefaultGuiceModule.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/DefaultGuiceModule.java Mon May 19 16:04:59 2008
@@ -18,6 +18,12 @@
*/
package org.apache.shindig.gadgets;
+import com.google.inject.AbstractModule;
+import com.google.inject.CreationException;
+import com.google.inject.Scopes;
+import com.google.inject.name.Names;
+import com.google.inject.spi.Message;
+
import org.apache.shindig.common.util.ResourceLoader;
import org.apache.shindig.gadgets.http.BasicHttpCache;
import org.apache.shindig.gadgets.http.BasicHttpFetcher;
@@ -26,12 +32,8 @@
import org.apache.shindig.gadgets.http.HttpFetcher;
import org.apache.shindig.gadgets.http.RemoteContentFetcherFactory;
import org.apache.shindig.gadgets.oauth.OAuthFetcherFactory;
-
-import com.google.inject.AbstractModule;
-import com.google.inject.CreationException;
-import com.google.inject.Scopes;
-import com.google.inject.name.Names;
-import com.google.inject.spi.Message;
+import org.apache.shindig.gadgets.rewrite.ContentRewriter;
+import org.apache.shindig.gadgets.rewrite.DefaultContentRewriter;
import java.io.IOException;
import java.io.InputStream;
@@ -52,6 +54,8 @@
protected void configure() {
Names.bindProperties(this.binder(), properties);
+ bind(ContentRewriter.class).to(DefaultContentRewriter.class);
+
bind(HttpFetcher.class).to(BasicHttpFetcher.class);
bind(HttpCache.class).to(BasicHttpCache.class);
Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServer.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServer.java?rev=658031&r1=658030&r2=658031&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServer.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServer.java Mon May 19 16:04:59 2008
@@ -17,6 +17,8 @@
*/
package org.apache.shindig.gadgets;
+import com.google.inject.Inject;
+
import org.apache.shindig.gadgets.http.ContentFetcherFactory;
import org.apache.shindig.gadgets.http.HttpRequest;
import org.apache.shindig.gadgets.http.HttpResponse;
@@ -27,8 +29,6 @@
import org.apache.shindig.gadgets.spec.MessageBundle;
import org.apache.shindig.gadgets.spec.Preload;
-import com.google.inject.Inject;
-
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
@@ -132,7 +132,7 @@
Integer.toString(context.getModuleId()));
UserPrefSubstituter.addSubstitutions(
substituter, spec, context.getUserPrefs());
- spec = spec.substitute(substituter);
+ spec = spec.substitute(substituter, !context.getIgnoreCache());
Set<GadgetFeatureRegistry.Entry> features = getFeatures(spec);
Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/BasicHttpFetcher.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/BasicHttpFetcher.java?rev=658031&r1=658030&r2=658031&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/BasicHttpFetcher.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/BasicHttpFetcher.java Mon May 19 16:04:59 2008
@@ -17,11 +17,11 @@
*/
package org.apache.shindig.gadgets.http;
-import org.apache.shindig.common.util.InputStreamConsumer;
-
import com.google.inject.Inject;
import com.google.inject.Singleton;
+import org.apache.shindig.common.util.InputStreamConsumer;
+
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
@@ -137,7 +137,14 @@
/** {@inheritDoc} */
public HttpResponse fetch(HttpRequest request) {
HttpResponse response = cache.getResponse(request);
- if (response != null) return response;
+ // TODO - Make this sensitive to custom rewriting rules
+ if (response != null) {
+ if (request.getOptions().rewriter != null &&
+ response.getRewritten() != null) {
+ return response.getRewritten();
+ }
+ return response;
+ }
try {
URLConnection fetcher = getConnection(request);
if ("POST".equals(request.getMethod()) &&
@@ -152,6 +159,11 @@
fetcher.getOutputStream());
}
response = makeResponse(fetcher);
+ if (request.getOptions().rewriter != null) {
+ // TODO - Make this sensitive to different rewriting rules
+ response.setRewritten(
+ request.getOptions().rewriter.rewrite(request.getUri(), response));
+ }
cache.addResponse(request, response);
return response;
} catch (IOException e) {
Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/HttpRequest.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/HttpRequest.java?rev=658031&r1=658030&r2=658031&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/HttpRequest.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/HttpRequest.java Mon May 19 16:04:59 2008
@@ -19,6 +19,8 @@
package org.apache.shindig.gadgets.http;
+import org.apache.shindig.gadgets.rewrite.ContentRewriter;
+
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
@@ -355,6 +357,7 @@
public boolean ignoreCache = false;
public boolean ownerSigned = true;
public boolean viewerSigned = true;
+ public ContentRewriter rewriter = null;
public Options() {}
@@ -365,6 +368,7 @@
this.ignoreCache = copyFrom.ignoreCache;
this.ownerSigned = copyFrom.ownerSigned;
this.viewerSigned = copyFrom.viewerSigned;
+ this.rewriter = copyFrom.rewriter;
}
}
}
Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/HttpResponse.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/HttpResponse.java?rev=658031&r1=658030&r2=658031&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/HttpResponse.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/HttpResponse.java Mon May 19 16:04:59 2008
@@ -51,6 +51,8 @@
private final Map<String, List<String>> headers;
private final Map<String, String> metadata;
+ private HttpResponse rewritten;
+
/**
* Create a dummy empty map. Access via HttpResponse.ERROR
*/
@@ -134,6 +136,13 @@
}
/**
+ * @reutrn the content length
+ */
+ public int getContentLength() {
+ return responseBytes.length;
+ }
+
+ /**
* @return An input stream suitable for reading the entirety of the response.
*/
public InputStream getResponse() {
@@ -204,4 +213,20 @@
public Map<String, String> getMetadata() {
return this.metadata;
}
+
+ /**
+ * Get the rewritten version of this content
+ * @return A rewritten HttpResponse
+ */
+ public HttpResponse getRewritten() {
+ return rewritten;
+ }
+
+ /**
+ * Set the rewritten version of this content
+ * @param rewritten
+ */
+ public void setRewritten(HttpResponse rewritten) {
+ this.rewritten = rewritten;
+ }
}
Added: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ContentRewriter.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ContentRewriter.java?rev=658031&view=auto
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ContentRewriter.java (added)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ContentRewriter.java Mon May 19 16:04:59 2008
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.apache.shindig.gadgets.rewrite;
+
+import org.apache.shindig.gadgets.http.HttpResponse;
+
+import java.io.Reader;
+import java.io.Writer;
+import java.net.URI;
+
+/**
+ * Standard interface for content rewriters
+ */
+public interface ContentRewriter {
+
+ /**
+ * Rewrite the original content located at source
+ * @param source Location of the original content
+ * @param original Original content
+ * @return A rewritten copy of the original or null if no rewriting occurred
+ */
+ public HttpResponse rewrite(URI source, HttpResponse original);
+
+ /**
+ * Rewrite the original content located at source
+ * @param source Location of the original content
+ * @param original Original content
+ * @param mimeType A string containing the mime type of the content, may
+ * contain other content as allowed in the HTTP Content-Type
+ * header
+ * @return A rewritten copy of the original or null if no rewriting occurred
+ */
+ public String rewrite(URI source, String original, String mimeType);
+
+ /**
+ * Rewrite the content in the original response located at source
+ * @param source Location of the original content
+ * @param original Original content
+ * @param mimeType A string containing the mime type of the content, may
+ * contain other content as allowed in the HTTP Content-Type
+ * header
+ * @param rewritten Target of rewritten content, not written to if no
+ * rewriting is done.
+ * @return true if rewrite occurred, false otherwise
+ */
+ public boolean rewrite(URI source, Reader original, String mimeType,
+ Writer rewritten);
+
+}
Added: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ContentRewriterFeature.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ContentRewriterFeature.java?rev=658031&view=auto
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ContentRewriterFeature.java (added)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ContentRewriterFeature.java Mon May 19 16:04:59 2008
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.apache.shindig.gadgets.rewrite;
+
+import org.apache.shindig.gadgets.spec.Feature;
+import org.apache.shindig.gadgets.spec.GadgetSpec;
+
+/**
+ * Parser for the "proxy-rewrite" feature
+ */
+public class ContentRewriterFeature {
+
+ private boolean isEnabled;
+
+ public ContentRewriterFeature(GadgetSpec spec, boolean containerDefault) {
+ Feature f = spec.getModulePrefs().getFeatures().get("content-rewrite");
+ isEnabled = containerDefault;
+ if (f != null) {
+ if ("NONE".equalsIgnoreCase(f.getParams().get("include"))) {
+ isEnabled = false;
+ } else if ("ALL".equalsIgnoreCase(f.getParams().get("include"))) {
+ isEnabled = true;
+ }
+ }
+ }
+
+ public boolean isRewriteEnabled() {
+ return isEnabled;
+ }
+}
Added: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/CssRewriter.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/CssRewriter.java?rev=658031&view=auto
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/CssRewriter.java (added)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/CssRewriter.java Mon May 19 16:04:59 2008
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.apache.shindig.gadgets.rewrite;
+
+import com.google.caja.lexer.CharProducer;
+import com.google.caja.lexer.CssLexer;
+import com.google.caja.lexer.CssTokenType;
+import com.google.caja.lexer.InputSource;
+import com.google.caja.lexer.ParseException;
+import com.google.caja.lexer.Token;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.net.URI;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Support rewriting links in CSS
+ */
+public class CssRewriter {
+
+ private static final Pattern urlMatcher =
+ Pattern.compile("(url\\s*\\(\\s*['\"]?)([^\\)'\"]*)(['\"]?\\s*\\))",
+ Pattern.CASE_INSENSITIVE);
+
+ public static String rewrite(String content, URI source,
+ LinkRewriter linkRewriter) {
+ StringWriter sw = new StringWriter((content.length() * 110) / 100);
+ rewrite(new StringReader(content), source, linkRewriter, sw);
+ return sw.toString();
+ }
+
+ public static void rewrite(Reader content, URI source,
+ LinkRewriter rewriter,
+ Writer writer) {
+ CharProducer producer = CharProducer.Factory.create(content,
+ new InputSource(source));
+ CssLexer lexer = new CssLexer(producer);
+ try {
+ while (lexer.hasNext()) {
+ Token<CssTokenType> token = lexer.next();
+ if (token.type == CssTokenType.URI) {
+ writer.write(rewriteLink(token, source, rewriter));
+ continue;
+ }
+ writer.write(token.text);
+ }
+ } catch (ParseException pe) {
+ pe.printStackTrace();
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ }
+ }
+
+ private static String rewriteLink(Token<CssTokenType> token,
+ URI base, LinkRewriter rewriter) {
+ Matcher matcher = urlMatcher.matcher(token.text);
+ if (!matcher.find()) return token.text;
+ return "url(\"" + rewriter.rewrite(matcher.group(2), base) + "\")";
+ }
+}
+
Added: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/DefaultContentRewriter.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/DefaultContentRewriter.java?rev=658031&view=auto
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/DefaultContentRewriter.java (added)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/DefaultContentRewriter.java Mon May 19 16:04:59 2008
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.apache.shindig.gadgets.rewrite;
+
+import org.apache.shindig.gadgets.http.HttpResponse;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Default implementation of content rewriting.
+ */
+public class DefaultContentRewriter implements ContentRewriter {
+
+ public DefaultContentRewriter() {
+ }
+
+ public HttpResponse rewrite(URI source, HttpResponse original) {
+ try {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream(
+ (original.getContentLength() * 110) / 100);
+ OutputStreamWriter output = new OutputStreamWriter(baos,
+ original.getEncoding());
+ if (rewrite(source,
+ new InputStreamReader(original.getResponse(), original.getEncoding()),
+ original.getHeader("Content-Type"),
+ output)) {
+ return new HttpResponse(original.getHttpStatusCode(),
+ baos.toByteArray(),
+ original.getAllHeaders());
+ }
+ return null;
+ } catch (UnsupportedEncodingException uee) {
+ throw new RuntimeException(uee);
+ }
+ }
+
+ public String rewrite(URI source, String original, String mimeType) {
+ StringWriter sw = new StringWriter();
+ if (rewrite(source, new StringReader(original), mimeType, sw)) {
+ return sw.toString();
+ } else {
+ return null;
+ }
+ }
+
+ public boolean rewrite(URI source, Reader r, String mimeType, Writer w) {
+ if (isHTML(mimeType)) {
+ Map<String, HtmlTagTransformer> transformerMap
+ = new HashMap<String, HtmlTagTransformer>();
+
+ if (getProxyUrl() != null) {
+ LinkRewriter linkRewriter = createLinkRewriter();
+ LinkingTagRewriter rewriter = new LinkingTagRewriter(
+ linkRewriter,
+ source);
+ for (String tag : rewriter.getSupportedTags()) {
+ transformerMap.put(tag, rewriter);
+ }
+ transformerMap.put("style", new StyleTagRewriter(source, linkRewriter));
+ }
+ if (getConcatUrl() != null) {
+ transformerMap
+ .put("script", new JavascriptTagMerger(getConcatUrl(), source));
+ }
+ HtmlRewriter.rewrite(r, source, transformerMap, w);
+ return true;
+ } else if (isCSS(mimeType)) {
+ if (getProxyUrl() != null) {
+ CssRewriter.rewrite(r, source, createLinkRewriter(), w);
+ return true;
+ } else {
+ return false;
+ }
+ }
+ return false;
+ }
+
+ private boolean isHTML(String mime) {
+ return (mime.toLowerCase().indexOf("html") != -1);
+ }
+
+ private boolean isCSS(String mime) {
+ return (mime.toLowerCase().indexOf("css") != -1);
+ }
+
+ private void copyContents(Reader r, Writer w) {
+ try {
+ for (int val = r.read(); val != -1; val = r.read()) {
+ w.write(val);
+ }
+ } catch (IOException ioe) {
+ throw new RuntimeException(ioe);
+ }
+ }
+
+ protected String getProxyUrl() {
+ return "/gadgets/proxy?url=";
+ }
+
+ protected String getConcatUrl() {
+ return "/gadgets/concat?";
+ }
+
+ protected LinkRewriter createLinkRewriter() {
+ return new ProxyingLinkRewriter(getProxyUrl());
+ }
+}
Added: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/HtmlRewriter.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/HtmlRewriter.java?rev=658031&view=auto
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/HtmlRewriter.java (added)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/HtmlRewriter.java Mon May 19 16:04:59 2008
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.shindig.gadgets.rewrite;
+
+import com.google.caja.lexer.CharProducer;
+import com.google.caja.lexer.HtmlLexer;
+import com.google.caja.lexer.HtmlTokenType;
+import com.google.caja.lexer.InputSource;
+import com.google.caja.lexer.ParseException;
+import com.google.caja.lexer.Token;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.net.URI;
+import java.util.Map;
+
+/**
+ * Rewrites an HTML content block
+ */
+public class HtmlRewriter {
+
+ private HtmlRewriter() {
+ }
+
+ public static String rewrite(String content, URI source,
+ Map<String, HtmlTagTransformer> transformers) {
+ StringWriter sw = new StringWriter((content.length() * 110) / 100);
+ rewrite(new StringReader(content), source, transformers, sw);
+ return sw.toString();
+ }
+
+ public static void rewrite(Reader content, URI source,
+ Map<String, HtmlTagTransformer> transformers,
+ Writer writer) {
+ CharProducer producer = CharProducer.Factory.create(content,
+ new InputSource(source));
+ HtmlLexer lexer = new HtmlLexer(producer);
+ try {
+ Token<HtmlTokenType> lastToken = null;
+ Token<HtmlTokenType> currentTag = null;
+ HtmlTagTransformer currentTransformer = null;
+ boolean tagChanged;
+ while (lexer.hasNext()) {
+ tagChanged = false;
+ Token<HtmlTokenType> token = lexer.next();
+ if (token.type == HtmlTokenType.IGNORABLE) {
+ continue;
+ }
+ if (token.type == HtmlTokenType.TAGBEGIN) {
+ currentTag = token;
+ tagChanged = true;
+ }
+ if (tagChanged) {
+ if (currentTransformer == null) {
+ currentTransformer = transformers
+ .get(currentTag.text.substring(1).toLowerCase());
+ } else {
+ if (!currentTransformer.acceptNextTag(currentTag)) {
+ writer.write(currentTransformer.close());
+ currentTransformer = transformers
+ .get(currentTag.text.substring(1).toLowerCase());
+ }
+ }
+ }
+ if (currentTransformer == null) {
+ writer.write(producePreTokenSeparator(token, lastToken));
+ writer.write(token.text);
+ writer.write(producePostTokenSeparator(token, lastToken));
+ } else {
+ currentTransformer.accept(token, lastToken);
+ }
+ if (token.type == HtmlTokenType.TAGEND) {
+ currentTag = null;
+ }
+ lastToken = token;
+ }
+ if (currentTransformer != null) {
+ writer.write(currentTransformer.close());
+ }
+ } catch (ParseException pe) {
+ pe.printStackTrace();
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ }
+ }
+
+
+ public static String producePreTokenSeparator(Token<HtmlTokenType> token,
+ Token<HtmlTokenType> lastToken) {
+ if (token.type == HtmlTokenType.ATTRNAME) {
+ return " ";
+ }
+ if (token.type == HtmlTokenType.ATTRVALUE &&
+ lastToken != null &&
+ lastToken.type == HtmlTokenType.ATTRNAME) {
+ return "=";
+ }
+ return "";
+ }
+
+
+ public static String producePostTokenSeparator(Token<HtmlTokenType> token,
+ Token<HtmlTokenType> lastToken) {
+ return "";
+ }
+
+}
Added: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/HtmlTagTransformer.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/HtmlTagTransformer.java?rev=658031&view=auto
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/HtmlTagTransformer.java (added)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/HtmlTagTransformer.java Mon May 19 16:04:59 2008
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.shindig.gadgets.rewrite;
+
+import com.google.caja.lexer.HtmlTokenType;
+import com.google.caja.lexer.Token;
+
+/**
+ * Provide custom transformations of a stream of HTML lexical tokens
+ * as provided by the Caja lexer. A tag transformer is initiated by
+ * the occurence of a start tag in the token stream. The transformer is
+ * fed all subsequent tokens within the tag. The transformer is given the\
+ * option of continuing to consume tokens from subsequent tags even after
+ * its initiating tag has ended.
+ */
+public interface HtmlTagTransformer {
+
+ /**
+ * Consume the token. Prior token supplied for context
+ * @param token current token
+ * @param lastToken
+ */
+ public void accept(Token<HtmlTokenType> token,
+ Token<HtmlTokenType> lastToken);
+
+ /**
+ * A new tag has begun, should this transformer continue to process
+ * @param tagStart
+ * @return true if continuing to process the new tag
+ */
+ public boolean acceptNextTag(Token<HtmlTokenType> tagStart);
+
+ /**
+ * Close the transformer, reset its state and return any content
+ * for inclusion in the rewritten output
+ * @return transformed content
+ */
+ public String close();
+}
Added: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/JavascriptTagMerger.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/JavascriptTagMerger.java?rev=658031&view=auto
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/JavascriptTagMerger.java (added)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/JavascriptTagMerger.java Mon May 19 16:04:59 2008
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.shindig.gadgets.rewrite;
+
+import com.google.caja.lexer.HtmlTokenType;
+import com.google.caja.lexer.Token;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Transform a contiguous block of script tags that refer to external scripts
+ * and rewrite them to a single script tag that uses a concatenating proxy
+ * to concatenate these scripts in order and also potentially perform other
+ * optimizations on the generated unified script such as minification
+ */
+public class JavascriptTagMerger implements HtmlTagTransformer {
+
+ private final List scripts = new ArrayList();
+
+ private final String concatBase;
+
+ private final URI relativeUrlBase;
+
+ private boolean isTagOpen = true;
+
+ /**
+ * @param concatBase Base url of the Concat servlet. Expected to be of the
+ * form www.host.com/concat?
+ * @param relativeUrlBase to resolve relative urls
+ */
+ public JavascriptTagMerger(String concatBase, URI relativeUrlBase) {
+ this.concatBase = concatBase;
+ this.relativeUrlBase = relativeUrlBase;
+ }
+
+ public void accept(Token<HtmlTokenType> token,
+ Token<HtmlTokenType> lastToken) {
+ try {
+ if (isTagOpen) {
+ if (lastToken != null &&
+ lastToken.type == HtmlTokenType.ATTRNAME &&
+ lastToken.text.equalsIgnoreCase("src")) {
+ scripts.add(new URI(stripQuotes(token.text)));
+ } else if (token.type == HtmlTokenType.UNESCAPED) {
+ scripts.add(token);
+ }
+ }
+ } catch (URISyntaxException use) {
+ throw new RuntimeException(use);
+ }
+ }
+
+ public boolean acceptNextTag(Token<HtmlTokenType> tagStart) {
+ if (tagStart.text.equalsIgnoreCase("<script")) {
+ isTagOpen = true;
+ return true;
+ } else if (tagStart.text.equalsIgnoreCase("</script")) {
+ isTagOpen = false;
+ return true;
+ }
+ return false;
+ }
+
+ public String close() {
+ List<URI> concat = new ArrayList<URI>();
+ StringBuilder builder = new StringBuilder(100);
+ for (Object o : scripts) {
+ if (o instanceof URI) {
+ concat.add((URI) o);
+ } else {
+ flushConcat(concat, builder);
+ builder.append("<script type=\"text/javascript\">")
+ .append(((Token<HtmlTokenType>) o).text).append("</script>");
+ }
+ }
+ flushConcat(concat, builder);
+ scripts.clear();
+ isTagOpen = true;
+ return builder.toString();
+ }
+
+ private void flushConcat(List<URI> concat, StringBuilder builder) {
+ if (concat.isEmpty()) {
+ return;
+ }
+ builder.append("<script src=\"").append(concatBase);
+ for (int i = 0; i < concat.size(); i++) {
+ URI srcUrl = concat.get(i);
+ if (!srcUrl.isAbsolute()) {
+ srcUrl = relativeUrlBase.resolve(srcUrl);
+ }
+ builder.append(i + 1).append("=")
+ .append(URLEncoder.encode(srcUrl.toString()));
+ if (i < concat.size() - 1) {
+ builder.append("&");
+ }
+ }
+ builder.append("\" type=\"text/javascript\"></script>");
+ concat.clear();
+ }
+
+ private String stripQuotes(String s) {
+ return s.replaceAll("\"", "").replaceAll("'","");
+ }
+}
Added: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/LinkRewriter.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/LinkRewriter.java?rev=658031&view=auto
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/LinkRewriter.java (added)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/LinkRewriter.java Mon May 19 16:04:59 2008
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.shindig.gadgets.rewrite;
+
+import java.net.URI;
+
+/**
+ * Rewrite a link
+ */
+public interface LinkRewriter {
+
+ public String rewrite(String link, URI context);
+
+}
Added: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/LinkingTagRewriter.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/LinkingTagRewriter.java?rev=658031&view=auto
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/LinkingTagRewriter.java (added)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/LinkingTagRewriter.java Mon May 19 16:04:59 2008
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.shindig.gadgets.rewrite;
+
+import com.google.caja.lexer.HtmlTokenType;
+import com.google.caja.lexer.Token;
+
+import java.net.URI;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/** Rewrite a linking attribute of an HTML tag to an arbitrary scheme */
+public class LinkingTagRewriter implements HtmlTagTransformer {
+
+ private final URI relativeBase;
+
+ private final LinkRewriter linkRewriter;
+
+ private final Map<String, Set<String>> tagAttributeTargets;
+
+ private final StringBuilder builder;
+
+ private Set<String> currentTagAttrs;
+
+ public static Map<String, Set<String>> getDefaultTargets() {
+ Map<String, Set<String>> targets = new HashMap<String, Set<String>>();
+ targets.put("img", new HashSet(Arrays.asList("src")));
+ targets.put("embed", new HashSet(Arrays.asList("src")));
+ targets.put("link", new HashSet(Arrays.asList("href")));
+ return targets;
+ }
+
+ public LinkingTagRewriter(LinkRewriter linkRewriter, URI relativeBase) {
+ this(getDefaultTargets(), linkRewriter, relativeBase);
+ }
+
+ public LinkingTagRewriter(Map<String, Set<String>> tagAttributeTargets,
+ LinkRewriter linkRewriter, URI relativeBase) {
+ this.tagAttributeTargets = tagAttributeTargets;
+ this.linkRewriter = linkRewriter;
+ this.relativeBase = relativeBase;
+ builder = new StringBuilder(300);
+ }
+
+ public Set<String> getSupportedTags() {
+ return tagAttributeTargets.keySet();
+ }
+
+ public void accept(Token<HtmlTokenType> token,
+ Token<HtmlTokenType> lastToken) {
+ if (token.type == HtmlTokenType.TAGBEGIN) {
+ currentTagAttrs = tagAttributeTargets
+ .get(token.text.substring(1).toLowerCase());
+ }
+
+ if (currentTagAttrs != null &&
+ lastToken != null &&
+ lastToken.type == HtmlTokenType.ATTRNAME &&
+ currentTagAttrs.contains(lastToken.text.toLowerCase())) {
+ String link = stripQuotes(token.text);
+ builder.append("=\"");
+ builder.append(linkRewriter.rewrite(link, relativeBase));
+ builder.append("\"");
+ return;
+ }
+ builder.append(HtmlRewriter.producePreTokenSeparator(token, lastToken));
+ builder.append(token.text);
+ builder.append(HtmlRewriter.producePostTokenSeparator(token, lastToken));
+ }
+
+ public boolean acceptNextTag(Token<HtmlTokenType> tagStart) {
+ return false;
+ }
+
+ public String close() {
+ String result = builder.toString();
+ currentTagAttrs = null;
+ builder.setLength(0);
+ return result;
+ }
+
+ private String stripQuotes(String s) {
+ return s.replaceAll("\"", "").replaceAll("'", "");
+ }
+}
Added: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/NoOpContentRewriter.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/NoOpContentRewriter.java?rev=658031&view=auto
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/NoOpContentRewriter.java (added)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/NoOpContentRewriter.java Mon May 19 16:04:59 2008
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.shindig.gadgets.rewrite;
+
+import org.apache.shindig.gadgets.http.HttpResponse;
+
+import java.io.Reader;
+import java.io.Writer;
+import java.net.URI;
+
+/**
+ * A no-op content rewriter
+ */
+public class NoOpContentRewriter implements ContentRewriter {
+
+ public NoOpContentRewriter() {
+ }
+
+ public HttpResponse rewrite(URI source, HttpResponse original) {
+ return null;
+ }
+
+ public String rewrite(URI source, String original, String mimeType) {
+ return null;
+ }
+
+ public boolean rewrite(URI source, Reader original, String mimeType,
+ Writer rewritten) {
+ return false;
+ }
+}
Added: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ProxyingLinkRewriter.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ProxyingLinkRewriter.java?rev=658031&view=auto
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ProxyingLinkRewriter.java (added)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ProxyingLinkRewriter.java Mon May 19 16:04:59 2008
@@ -0,0 +1,23 @@
+package org.apache.shindig.gadgets.rewrite;
+
+import java.net.URI;
+import java.net.URLEncoder;
+
+/**
+ * Simple link rewriter that expect to rewrite a link to the form
+ * http://www.host.com/proxy/url=<url encoded link>
+ */
+public class ProxyingLinkRewriter implements LinkRewriter {
+
+ private final String prefix;
+
+ public ProxyingLinkRewriter(String prefix) {
+ this.prefix = prefix;
+ }
+
+ public String rewrite(String link, URI context) {
+ URI uri = context.resolve(link);
+ return prefix + URLEncoder.encode(uri.toString());
+ }
+
+}
Added: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/StyleTagRewriter.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/StyleTagRewriter.java?rev=658031&view=auto
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/StyleTagRewriter.java (added)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/StyleTagRewriter.java Mon May 19 16:04:59 2008
@@ -0,0 +1,43 @@
+package org.apache.shindig.gadgets.rewrite;
+
+import com.google.caja.lexer.HtmlTokenType;
+import com.google.caja.lexer.Token;
+
+import java.net.URI;
+
+/**
+ * Rewrite the CSS content of a style tag
+ */
+public class StyleTagRewriter implements HtmlTagTransformer {
+
+ private URI source;
+ private LinkRewriter linkRewriter;
+
+ private StringBuffer sb;
+
+ public StyleTagRewriter(URI source, LinkRewriter linkRewriter) {
+ this.source = source;
+ this.linkRewriter = linkRewriter;
+ sb = new StringBuffer(500);
+ }
+
+ public void accept(Token<HtmlTokenType> token, Token<HtmlTokenType> lastToken) {
+ if (token.type == HtmlTokenType.UNESCAPED) {
+ sb.append(CssRewriter.rewrite(token.text, source, linkRewriter));
+ } else {
+ sb.append(HtmlRewriter.producePreTokenSeparator(token, lastToken));
+ sb.append(token.text);
+ sb.append(HtmlRewriter.producePostTokenSeparator(token, lastToken));
+ }
+ }
+
+ public boolean acceptNextTag(Token<HtmlTokenType> tagStart) {
+ return false;
+ }
+
+ public String close() {
+ String result = sb.toString();
+ sb.setLength(0);
+ return result;
+ }
+}
Added: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/ConcatProxyServlet.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/ConcatProxyServlet.java?rev=658031&view=auto
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/ConcatProxyServlet.java (added)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/ConcatProxyServlet.java Mon May 19 16:04:59 2008
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package org.apache.shindig.gadgets.servlet;
+
+import com.google.inject.Inject;
+
+import org.apache.shindig.common.servlet.InjectedServlet;
+import org.apache.shindig.gadgets.GadgetException;
+
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Servlet which concatenates the content of several proxied HTTP responses
+ *
+ * @see org.apache.shindig.gadgets.rewrite.JavascriptTagMerger
+ */
+public class ConcatProxyServlet extends InjectedServlet {
+
+ private static final Logger logger
+ = Logger.getLogger(ConcatProxyServlet.class.getName());
+
+ private ProxyHandler proxyHandler;
+
+ @Inject
+ public void setProxyHandler(ProxyHandler proxyHandler) {
+ this.proxyHandler = proxyHandler;
+ }
+
+ @Override
+ protected void doGet(HttpServletRequest request, HttpServletResponse response)
+ throws IOException {
+ for (int i = 1; i < Integer.MAX_VALUE; i++) {
+ String url = request.getParameter(Integer.toString(i));
+ if (url == null) {
+ break;
+ }
+ try {
+ proxyHandler.fetch(new RequestWrapper(request, url), response);
+ } catch (GadgetException ge) {
+ outputError(ge, response);
+ }
+ }
+ }
+
+
+ private void outputError(GadgetException excep, HttpServletResponse resp)
+ throws IOException {
+ StringBuilder err = new StringBuilder();
+ err.append(excep.getCode().toString());
+ err.append(' ');
+ err.append(excep.getMessage());
+
+ // Log the errors here for now. We might want different severity levels
+ // for different error codes.
+ logger.log(Level.INFO, "Concat proxy request failed", err);
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST, err.toString());
+ }
+
+ /** Simple request wrapper to make repeated calls to ProxyHandler */
+ private class RequestWrapper extends HttpServletRequestWrapper {
+
+ private final String url;
+
+ private RequestWrapper(HttpServletRequest httpServletRequest, String url) {
+ super(httpServletRequest);
+ this.url = url;
+ }
+
+ @Override
+ public String getParameter(String paramName) {
+ if (ProxyHandler.URL_PARAM.equals(paramName)) {
+ return url;
+ }
+ return super.getParameter(paramName);
+ }
+ }
+}
+
Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/ProxyHandler.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/ProxyHandler.java?rev=658031&r1=658030&r2=658031&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/ProxyHandler.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/ProxyHandler.java Mon May 19 16:04:59 2008
@@ -18,22 +18,22 @@
*/
package org.apache.shindig.gadgets.servlet;
+import com.google.inject.Inject;
+
import org.apache.shindig.common.SecurityToken;
import org.apache.shindig.common.SecurityTokenDecoder;
import org.apache.shindig.common.SecurityTokenException;
import org.apache.shindig.common.util.InputStreamConsumer;
import org.apache.shindig.gadgets.GadgetException;
import org.apache.shindig.gadgets.LockedDomainService;
-import org.apache.shindig.gadgets.http.HttpFetcher;
import org.apache.shindig.gadgets.http.ContentFetcherFactory;
-import org.apache.shindig.gadgets.http.HttpResponse;
+import org.apache.shindig.gadgets.http.HttpFetcher;
import org.apache.shindig.gadgets.http.HttpRequest;
+import org.apache.shindig.gadgets.http.HttpResponse;
import org.apache.shindig.gadgets.oauth.OAuthRequestParams;
+import org.apache.shindig.gadgets.rewrite.ContentRewriter;
import org.apache.shindig.gadgets.spec.Auth;
import org.apache.shindig.gadgets.spec.Preload;
-
-import com.google.inject.Inject;
-
import org.json.JSONException;
import org.json.JSONObject;
@@ -89,6 +89,7 @@
// This is a limitation of Guice, but this workaround...works.
private ContentFetcherFactory contentFetcherFactory;
private final LockedDomainService domainLocker;
+ private final ContentRewriter rewriter;
@Inject
public void setContentFetcher(ContentFetcherFactory contentFetcherFactory) {
@@ -98,10 +99,12 @@
@Inject
public ProxyHandler(ContentFetcherFactory contentFetcherFactory,
SecurityTokenDecoder securityTokenDecoder,
- LockedDomainService lockedDomainService) {
+ LockedDomainService lockedDomainService,
+ ContentRewriter rewriter) {
this.contentFetcherFactory = contentFetcherFactory;
this.securityTokenDecoder = securityTokenDecoder;
this.domainLocker = lockedDomainService;
+ this.rewriter = rewriter;
}
/**
@@ -208,6 +211,7 @@
options.ownerSigned = Boolean
.parseBoolean(request.getParameter(SIGN_OWNER));
}
+ options.rewriter = rewriter;
return new HttpRequest(
method, url, headers, postBody, options);
Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/GadgetSpec.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/GadgetSpec.java?rev=658031&r1=658030&r2=658031&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/GadgetSpec.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/GadgetSpec.java Mon May 19 16:04:59 2008
@@ -21,7 +21,6 @@
import org.apache.shindig.common.xml.XmlException;
import org.apache.shindig.common.xml.XmlUtil;
import org.apache.shindig.gadgets.Substitutions;
-
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
@@ -101,7 +100,7 @@
* @param substituter
* @return The substituted spec.
*/
- public GadgetSpec substitute(Substitutions substituter) {
+ public GadgetSpec substitute(Substitutions substituter, boolean rewrite) {
GadgetSpec spec = new GadgetSpec(this);
spec.modulePrefs = modulePrefs.substitute(substituter);
if (userPrefs.size() == 0) {
@@ -115,7 +114,7 @@
}
Map<String, View> viewMap = new HashMap<String, View>(views.size());
for (View view : views.values()) {
- viewMap.put(view.getName(), view.substitute(substituter));
+ viewMap.put(view.getName(), view.substitute(substituter, rewrite));
}
spec.views = Collections.unmodifiableMap(viewMap);
Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/View.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/View.java?rev=658031&r1=658030&r2=658031&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/View.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/View.java Mon May 19 16:04:59 2008
@@ -16,9 +16,9 @@
* specific language governing permissions and limitations under the License.
*/
package org.apache.shindig.gadgets.spec;
+
import org.apache.shindig.common.xml.XmlUtil;
import org.apache.shindig.gadgets.Substitutions;
-
import org.w3c.dom.Element;
import java.net.URI;
@@ -89,9 +89,13 @@
* @param substituter
* @return The substituted view.
*/
- public View substitute(Substitutions substituter) {
+ public View substitute(Substitutions substituter, boolean rewrite) {
View view = new View(this);
- view.content = substituter.substituteString(null, content);
+ if (rewrite && rewrittenContent != null) {
+ view.content = substituter.substituteString(null, rewrittenContent);
+ } else {
+ view.content = substituter.substituteString(null, content);
+ }
view.href = substituter.substituteUri(null, href);
return view;
}
@@ -180,4 +184,17 @@
return "url".equals(value) ? URL : HTML;
}
}
+
+ //
+ // Decorations
+ //
+ private String rewrittenContent;
+
+ public String getRewrittenContent() {
+ return rewrittenContent;
+ }
+
+ public void setRewrittenContent(String rewrittenContent) {
+ this.rewrittenContent = rewrittenContent;
+ }
}
\ No newline at end of file
Modified: incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetTestFixture.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetTestFixture.java?rev=658031&r1=658030&r2=658031&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetTestFixture.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetTestFixture.java Mon May 19 16:04:59 2008
@@ -22,6 +22,7 @@
import org.apache.shindig.common.SecurityTokenDecoder;
import org.apache.shindig.gadgets.http.ContentFetcherFactory;
import org.apache.shindig.gadgets.http.HttpFetcher;
+import org.apache.shindig.gadgets.rewrite.NoOpContentRewriter;
import java.util.concurrent.Executor;
@@ -39,7 +40,7 @@
public final HttpFetcher fetcher = mock(HttpFetcher.class);
public final GadgetBlacklist blacklist = mock(GadgetBlacklist.class);
public final GadgetSpecFactory specFactory =
- new BasicGadgetSpecFactory(fetcher);
+ new BasicGadgetSpecFactory(fetcher, new NoOpContentRewriter(), "true");
public final MessageBundleFactory bundleFactory =
new BasicMessageBundleFactory(fetcher);
public GadgetFeatureRegistry registry;
Added: incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/CssRewriterTest.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/CssRewriterTest.java?rev=658031&view=auto
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/CssRewriterTest.java (added)
+++ incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/CssRewriterTest.java Mon May 19 16:04:59 2008
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.apache.shindig.gadgets.rewrite;
+
+import org.apache.shindig.gadgets.EasyMockTestCase;
+
+import java.net.URI;
+import java.util.Map;
+
+/**
+ * test CSS link rewriting
+ */
+public class CssRewriterTest extends EasyMockTestCase {
+
+ private URI dummyUri;
+
+ private Map<String, HtmlTagTransformer> defaultTransformerMap;
+
+ private LinkRewriter defaultRewriter = new ProxyingLinkRewriter(
+ "http://www.test.com/proxy?url=");
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ dummyUri = new URI("http://www.w3c.org");
+ defaultRewriter = new ProxyingLinkRewriter("http://www.test.com/proxy?url=");
+ }
+
+ private void validateRewritten(String content, URI base,
+ LinkRewriter rewriter, String expected) {
+ assertEquals(expected, CssRewriter.rewrite(content, base, rewriter));
+ }
+
+ private void validateRewritten(String content, String expected) {
+ validateRewritten(content, dummyUri, defaultRewriter, expected);
+ }
+
+ public void testUrlDeclarationRewrite() {
+ String original =
+ "div {list-style-image:url('http://a.b.com/bullet.gif');list-style-position:outside;margin:5px;padding:0}\n" +
+ ".someid {background-image:url(http://a.b.com/bigimg.png);float:right;width:165px;height:23px;margin-top:4px;margin-left:5px}";
+ String rewritten =
+ "div {list-style-image:url(\"http://www.test.com/proxy?url=http%3A%2F%2Fa.b.com%2Fbullet.gif\");list-style-position:outside;margin:5px;padding:0}\n" +
+ ".someid {background-image:url(\"http://www.test.com/proxy?url=http%3A%2F%2Fa.b.com%2Fbigimg.png\");float:right;width:165px;height:23px;margin-top:4px;margin-left:5px}";
+ validateRewritten(original, rewritten);
+ }
+
+}
Added: incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/HtmlRewriterTest.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/HtmlRewriterTest.java?rev=658031&view=auto
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/HtmlRewriterTest.java (added)
+++ incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/HtmlRewriterTest.java Mon May 19 16:04:59 2008
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.shindig.gadgets.rewrite;
+
+import org.apache.shindig.gadgets.EasyMockTestCase;
+
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Test the HTML rewriter foundation for basic operation
+ */
+public class HtmlRewriterTest extends EasyMockTestCase {
+
+ private URI dummyUri;
+
+ private Map<String, HtmlTagTransformer> defaultTransformerMap;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ dummyUri = new URI("http://www.w3c.org");
+ defaultTransformerMap = new HashMap<String, HtmlTagTransformer>();
+ }
+
+ private void validateRewritten(String content, URI base,
+ Map<String, HtmlTagTransformer> transformerMap,
+ String expected) {
+ assertEquals(expected, HtmlRewriter.rewrite(content, base, transformerMap));
+ }
+
+ private void validateRewritten(String content, String expected) {
+ validateRewritten(content, dummyUri, defaultTransformerMap, expected);
+ }
+
+ public void testPreserveJunk() {
+ String s = "<div id=notvalid name='horrorShow\" />\n"
+ + "</br>\n"
+ + "</div>";
+ validateRewritten(s, s);
+ }
+
+ public void testPreserveScript() {
+ String s = "<script src=\"http://a.b.com/1.js\">\n</script>"
+ + "\n<script src=\"http://a.b.com/2.js\">\n</script>";
+ validateRewritten(s, s);
+ }
+
+ public void testPreserveCss() {
+ String s = "<html><style>body { background-color:#7f7f7f }</style>";
+ validateRewritten(s, s);
+ }
+
+ public void testBigChunk() {
+ // The source of the goolge homepage at a point in time
+ String s =
+ "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\">\n"
+ + "<html><head><title>DRAFT - HTML4 Test Suite:7_5_5-BF-01</title>\n"
+ + "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">\n"
+ + "<meta http-equiv=\"Content-Style-Type\" content=\"text/css\">\n"
+ + "<link rel=\"stylesheet\" type=\"text/css\" media=\"screen\" href=\"static.css\"></head>\n"
+ + "<body>\n"
+ + "<div class=\"navigation\">\n"
+ + "<h2>DRAFT - HTML4 Test Suite: Test 7_5_5-BF-01 Headings: The H1, H2, H3, H4, H5, H6 elements</h2>\n"
+ + "<hr>[<a href=\"sec7_5_4-BF-02.html\">Previous</a>] [<a href=\"section8.html\">Next</a>] [<a href=\"section7.html\">Section</a>]"
+ + " [<a href=\"index.html\">Contents</a>] [<a href=\"http://www.w3.org/TR/html401/struct/global.html#h-7.5.5\">Specification</a>]<BR>\n"
+ + "\n"
+ + "</div>\n"
+ + "<object height=\"100%\" width=\"100%\" border=\"0\" type=\"text/html\" data=\"7_5_5-BF-01.html\">\n"
+ + "<a class=\"navigation\" href=\"7_5_5-BF-01.html\" target=\"testwindow\">Test</a></object>\n"
+ + "</body></html>";
+ validateRewritten(s, s);
+ }
+
+ public void testPreserveCData() {
+ String s = "<script><![CDATA[dontcare]]></script>";
+ validateRewritten(s, s);
+ }
+
+ public void testPreserveComment() {
+ String s = "<script> <!-- something here --></script>";
+ validateRewritten(s, s);
+ }
+
+ // Eventaully we want the opposite.
+ public void testPreserveUselessWhitespace() {
+ String s = " <script> \n</script>";
+ validateRewritten(s, s);
+ }
+
+}
Added: incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/JavascriptTagMergerTest.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/JavascriptTagMergerTest.java?rev=658031&view=auto
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/JavascriptTagMergerTest.java (added)
+++ incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/JavascriptTagMergerTest.java Mon May 19 16:04:59 2008
@@ -0,0 +1,139 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.shindig.gadgets.rewrite;
+
+import org.apache.shindig.gadgets.EasyMockTestCase;
+
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Test for Javascript tag merge functionality
+ */
+public class JavascriptTagMergerTest extends EasyMockTestCase {
+
+ private URI dummyUri;
+ private URI relativeBase;
+
+ private Map<String, HtmlTagTransformer> defaultTransformerMap;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ dummyUri = new URI("http://www.w3c.org");
+ relativeBase = new URI("http://a.b.com/");
+ defaultTransformerMap = new HashMap<String, HtmlTagTransformer>();
+ defaultTransformerMap
+ .put("script", new JavascriptTagMerger("http://www.test.com/concat?",
+ relativeBase));
+ }
+
+ private void validateRewritten(String content, URI base,
+ Map<String, HtmlTagTransformer> transformerMap,
+ String expected) {
+ assertEquals(expected, HtmlRewriter.rewrite(content, base, transformerMap));
+ }
+
+ private void validateRewritten(String content, String expected) {
+ validateRewritten(content, dummyUri, defaultTransformerMap, expected);
+ }
+
+ public void testPreserveNoExternal() {
+ String original = "<script type=\"text/javascript\">\n"
+ + "doSomething\n"
+ + "</script>";
+ validateRewritten(original, original);
+ }
+
+ public void testPreserveNoScript() {
+ String original
+ = "<html><div id=\"test\">ceci ne pas une script</div></html>";
+ validateRewritten(original, original);
+ }
+
+ public void testPreserveWithComment() {
+ String original = "<script type=\"text/javascript\"><!--\n"
+ + "doSomething\n"
+ + "--></script>";
+ validateRewritten(original, original);
+ }
+
+ public void testSingleScriptReWrite() {
+ String original = "<script src=\"http://a.b.com/1.js\"></script>";
+ String rewritten
+ = "<script src=\"http://www.test.com/concat?1=http%3A%2F%2Fa.b.com%2F1.js\" type=\"text/javascript\"></script>";
+ validateRewritten(original, rewritten);
+ }
+
+ public void testTwoScriptReWrite() {
+ String original = "<script src=\"http://a.b.com/1.js\"></script>\n"
+ + "<script src=\"http://a.b.com/2.js\"></script>";
+ String rewritten
+ = "<script src=\"http://www.test.com/concat?1=http%3A%2F%2Fa.b.com%2F1.js&2=http%3A%2F%2Fa.b.com%2F2.js\" type=\"text/javascript\"></script>";
+ validateRewritten(original, rewritten);
+ }
+
+ public void testLeadAndTrailingScriptReWrite() {
+ String original = "<script>\n"
+ + "doSomething\n"
+ + "</script>\n"
+ + "<script src=\"http://a.b.com/1.js\"></script>\n"
+ + "<script src=\"http://a.b.com/2.js\"></script>\n"
+ + "<script>\n"
+ + "doSomething\n"
+ + "</script>";
+ String rewritten = "<script type=\"text/javascript\">\n"
+ + "doSomething\n"
+ + "</script>"
+ + "<script src=\"http://www.test.com/concat?1=http%3A%2F%2Fa.b.com%2F1.js&2=http%3A%2F%2Fa.b.com%2F2.js\" type=\"text/javascript\"></script>"
+ + "<script type=\"text/javascript\">\n"
+ + "doSomething\n"
+ + "</script>";
+ validateRewritten(original, rewritten);
+ }
+
+ public void testInterspersed() {
+ String original = "<script src=\"http://a.b.com/1.js\"></script>\n"
+ + "<script src=\"http://a.b.com/2.js\"></script>\n"
+ + "<script type=\"text/javascript\"><!-- doSomething --></script>\n"
+ + "<script src=\"http://a.b.com/3.js\"></script>\n"
+ + "<script src=\"http://a.b.com/4.js\"></script>";
+ String rewritten =
+ "<script src=\"http://www.test.com/concat?1=http%3A%2F%2Fa.b.com%2F1.js&2=http%3A%2F%2Fa.b.com%2F2.js\" type=\"text/javascript\"></script>"
+ + "<script type=\"text/javascript\"><!-- doSomething --></script>"
+ + "<script src=\"http://www.test.com/concat?1=http%3A%2F%2Fa.b.com%2F3.js&2=http%3A%2F%2Fa.b.com%2F4.js\" type=\"text/javascript\"></script>";
+ validateRewritten(original, rewritten);
+ }
+
+ public void testDerelativizeHostRelative() {
+ String original = "<script src=\"/1.js\"></script>";
+ String rewritten
+ = "<script src=\"http://www.test.com/concat?1=http%3A%2F%2Fa.b.com%2F1.js\" type=\"text/javascript\"></script>";
+ validateRewritten(original, rewritten);
+ }
+
+ public void testDerelativizePathRelative() {
+ String original = "<script src=\"1.js\"></script>";
+ String rewritten
+ = "<script src=\"http://www.test.com/concat?1=http%3A%2F%2Fa.b.com%2F1.js\" type=\"text/javascript\"></script>";
+ validateRewritten(original, rewritten);
+ }
+
+}
Added: incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/LinkingTagRewriterTest.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/LinkingTagRewriterTest.java?rev=658031&view=auto
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/LinkingTagRewriterTest.java (added)
+++ incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/LinkingTagRewriterTest.java Mon May 19 16:04:59 2008
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.shindig.gadgets.rewrite;
+
+import org.apache.shindig.gadgets.EasyMockTestCase;
+
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Test link rewriting
+ */
+public class LinkingTagRewriterTest extends EasyMockTestCase {
+
+ private URI dummyUri;
+ private URI relativeBase;
+
+ private Map<String, HtmlTagTransformer> defaultTransformerMap;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ dummyUri = new URI("http://www.w3c.org");
+ relativeBase = new URI("http://a.b.com/");
+ LinkingTagRewriter rewriter = new LinkingTagRewriter(
+ new ProxyingLinkRewriter("http://www.test.com/proxy?url="),
+ relativeBase);
+
+ defaultTransformerMap = new HashMap<String, HtmlTagTransformer>();
+ for (String tag : rewriter.getSupportedTags()) {
+ defaultTransformerMap
+ .put(tag, rewriter);
+ }
+ }
+
+ private void validateRewritten(String content, URI base,
+ Map<String, HtmlTagTransformer> transformerMap,
+ String expected) {
+ assertEquals(expected, HtmlRewriter.rewrite(content, base, transformerMap));
+ }
+
+ private void validateRewritten(String content, String expected) {
+ validateRewritten(content, dummyUri, defaultTransformerMap, expected);
+ }
+
+ public void testStandardRewrite() {
+ String original = "<img src=\"http://a.b.com/img.gif\"></img>\n"
+ + "<IMG src=\"http://a.b.com/img.gif\"/>\n"
+ + "<eMbeD src=\"http://a.b.com/some.mov\" width=\"100\" height=\"30px\"/>";
+ String expected = "<img src=\"http://www.test.com/proxy?url=http%3A%2F%2Fa.b.com%2Fimg.gif\"></img>\n"
+ + "<IMG src=\"http://www.test.com/proxy?url=http%3A%2F%2Fa.b.com%2Fimg.gif\"/>\n"
+ + "<eMbeD src=\"http://www.test.com/proxy?url=http%3A%2F%2Fa.b.com%2Fsome.mov\" width=\"100\" height=\"30px\"/>";
+ validateRewritten(original, expected);
+ }
+
+
+}
Modified: incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/HttpTestFixture.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/HttpTestFixture.java?rev=658031&r1=658030&r2=658031&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/HttpTestFixture.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/HttpTestFixture.java Mon May 19 16:04:59 2008
@@ -21,6 +21,8 @@
import org.apache.shindig.gadgets.GadgetTestFixture;
import org.apache.shindig.gadgets.LockedDomainService;
import org.apache.shindig.gadgets.http.ContentFetcherFactory;
+import org.apache.shindig.gadgets.rewrite.ContentRewriter;
+import org.apache.shindig.gadgets.rewrite.NoOpContentRewriter;
public abstract class HttpTestFixture extends GadgetTestFixture {
public final ProxyHandler proxyHandler;
@@ -31,13 +33,15 @@
public final UrlGenerator urlGenerator = mock(UrlGenerator.class);
public final LockedDomainService lockedDomainService =
mock(LockedDomainService.class);
+ public final ContentRewriter rewriter = new NoOpContentRewriter();
public HttpTestFixture() {
super();
proxyHandler = new ProxyHandler(
contentFetcherFactory,
securityTokenDecoder,
- lockedDomainService);
+ lockedDomainService,
+ rewriter);
gadgetRenderer = new GadgetRenderingTask(gadgetServer, registry,
containerConfig, urlGenerator, securityTokenDecoder, lockedDomainService);
jsonRpcHandler = new JsonRpcHandler(executor, gadgetServer, urlGenerator);
Modified: incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/spec/GadgetSpecTest.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/spec/GadgetSpecTest.java?rev=658031&r1=658030&r2=658031&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/spec/GadgetSpecTest.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/spec/GadgetSpecTest.java Mon May 19 16:04:59 2008
@@ -19,12 +19,12 @@
package org.apache.shindig.gadgets.spec;
+import junit.framework.TestCase;
+
import org.apache.shindig.gadgets.GadgetException;
import org.apache.shindig.gadgets.Substitutions;
import org.apache.shindig.gadgets.Substitutions.Type;
-import junit.framework.TestCase;
-
import java.net.URI;
public class GadgetSpecTest extends TestCase {
@@ -104,7 +104,7 @@
substituter.addSubstitution(Type.USER_PREF, "title", title);
substituter.addSubstitution(Type.MESSAGE, "content", content);
- GadgetSpec spec = new GadgetSpec(SPEC_URL, xml).substitute(substituter);
+ GadgetSpec spec = new GadgetSpec(SPEC_URL, xml).substitute(substituter, false);
assertEquals(title, spec.getModulePrefs().getTitle());
assertEquals(content, spec.getView(GadgetSpec.DEFAULT_VIEW).getContent());
}
Modified: incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/spec/ViewTest.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/spec/ViewTest.java?rev=658031&r1=658030&r2=658031&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/spec/ViewTest.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/spec/ViewTest.java Mon May 19 16:04:59 2008
@@ -19,12 +19,12 @@
package org.apache.shindig.gadgets.spec;
+import junit.framework.TestCase;
+
import org.apache.shindig.common.xml.XmlUtil;
import org.apache.shindig.gadgets.Substitutions;
import org.apache.shindig.gadgets.Substitutions.Type;
-import junit.framework.TestCase;
-
import java.util.Arrays;
public class ViewTest extends TestCase {
@@ -122,7 +122,7 @@
substituter.addSubstitution(Type.MODULE, "ID", "3");
View view = new View("test",
- Arrays.asList(XmlUtil.parse(xml))).substitute(substituter);
+ Arrays.asList(XmlUtil.parse(xml))).substitute(substituter, false);
assertEquals("Hello, foo Earthright 3", view.getContent());
}
@@ -138,7 +138,7 @@
substituter.addSubstitution(Type.MODULE, "ID", "123");
View view = new View("test",
- Arrays.asList(XmlUtil.parse(xml))).substitute(substituter);
+ Arrays.asList(XmlUtil.parse(xml))).substitute(substituter, false);
assertEquals("http://up.example.org/123?dir=rtl",
view.getHref().toString());
}
Modified: incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.full.xml
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.full.xml?rev=658031&r1=658030&r2=658031&view=diff
==============================================================================
--- incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.full.xml (original)
+++ incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.full.xml Mon May 19 16:04:59 2008
@@ -49,6 +49,13 @@
</servlet-class>
</servlet>
+ <servlet>
+ <servlet-name>concat</servlet-name>
+ <servlet-class>
+ org.apache.shindig.gadgets.servlet.ConcatProxyServlet
+ </servlet-class>
+ </servlet>
+
<!-- Metadata RPC -->
<servlet>
<servlet-name>metadata</servlet-name>
@@ -95,6 +102,11 @@
</servlet-mapping>
<servlet-mapping>
+ <servlet-name>concat</servlet-name>
+ <url-pattern>/gadgets/concat</url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
<servlet-name>xml-to-html</servlet-name>
<url-pattern>/gadgets/ifr</url-pattern>
</servlet-mapping>
Modified: incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.gadgets.xml
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.gadgets.xml?rev=658031&r1=658030&r2=658031&view=diff
==============================================================================
--- incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.gadgets.xml (original)
+++ incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.gadgets.xml Mon May 19 16:04:59 2008
@@ -49,6 +49,13 @@
</servlet-class>
</servlet>
+ <servlet>
+ <servlet-name>concat</servlet-name>
+ <servlet-class>
+ org.apache.shindig.gadgets.servlet.ConcatProxyServlet
+ </servlet-class>
+ </servlet>
+
<!-- Metadata RPC -->
<servlet>
<servlet-name>metadata</servlet-name>
@@ -74,6 +81,11 @@
</servlet-mapping>
<servlet-mapping>
+ <servlet-name>concat</servlet-name>
+ <url-pattern>/gadgets/concat</url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
<servlet-name>xml-to-html</servlet-name>
<url-pattern>/gadgets/ifr</url-pattern>
</servlet-mapping>
Modified: incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.xml?rev=658031&r1=658030&r2=658031&view=diff
==============================================================================
--- incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.xml (original)
+++ incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.xml Mon May 19 16:04:59 2008
@@ -49,6 +49,14 @@
</servlet-class>
</servlet>
+ <!-- Concat -->
+ <servlet>
+ <servlet-name>concat</servlet-name>
+ <servlet-class>
+ org.apache.shindig.gadgets.servlet.ConcatProxyServlet
+ </servlet-class>
+ </servlet>
+
<!-- Metadata RPC -->
<servlet>
<servlet-name>metadata</servlet-name>
@@ -94,6 +102,11 @@
</servlet-mapping>
<servlet-mapping>
+ <servlet-name>concat</servlet-name>
+ <url-pattern>/gadgets/concat</url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
<servlet-name>xml-to-html</servlet-name>
<url-pattern>/gadgets/ifr</url-pattern>
</servlet-mapping>