You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shindig.apache.org by jo...@apache.org on 2008/01/16 09:06:32 UTC
svn commit: r612381 - in /incubator/shindig/trunk/java/gadgets: ./
src/main/java/org/apache/shindig/gadgets/
src/main/java/org/apache/shindig/gadgets/http/
Author: johnh
Date: Wed Jan 16 00:06:30 2008
New Revision: 612381
URL: http://svn.apache.org/viewvc?rev=612381&view=rev
Log:
First commit of Caja support in Shindig.
* GadgetContentFilter introduced as a general mechanism for filtering Gadget output.
* CajaContentFilter is the first example of the above.
* pom.xml cleaned up to have only one Caja reference
This commit is based on Ihab A.B. Awad's patch, and resolves JIRA issue SHINDIG-17. Thanks Ihab!
Added:
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetContentFilter.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/CajaContentFilter.java
Modified:
incubator/shindig/trunk/java/gadgets/pom.xml
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetFeatureRegistry.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/GadgetRenderingServlet.java
Modified: incubator/shindig/trunk/java/gadgets/pom.xml
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/pom.xml?rev=612381&r1=612380&r2=612381&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/pom.xml (original)
+++ incubator/shindig/trunk/java/gadgets/pom.xml Wed Jan 16 00:06:30 2008
@@ -56,7 +56,7 @@
</build>
<repositories>
<repository>
- <id>google-caja</id>
+ <id>caja</id>
<url>http://google-caja.googlecode.com/svn/maven</url>
</repository>
</repositories>
@@ -80,12 +80,6 @@
<scope>compile</scope>
</dependency>
<dependency>
- <groupId>caja</groupId>
- <artifactId>caja</artifactId>
- <version>r339</version>
- <scope>compile</scope>
- </dependency>
- <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.4</version>
@@ -102,6 +96,12 @@
<artifactId>easymockclassextension</artifactId>
<version>2.2.2</version>
<scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>caja</groupId>
+ <artifactId>caja</artifactId>
+ <version>r394</version>
+ <scope>compile</scope>
</dependency>
</dependencies>
<distributionManagement>
Added: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetContentFilter.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetContentFilter.java?rev=612381&view=auto
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetContentFilter.java (added)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetContentFilter.java Wed Jan 16 00:06:30 2008
@@ -0,0 +1,22 @@
+/*
+ * Licensed 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;
+
+/**
+ * Simple interface for a class which filters the content of a Gadget
+ * before returning it to the requestor.
+ */
+public interface GadgetContentFilter {
+ public String filter(String content) throws GadgetException;
+}
Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetFeatureRegistry.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetFeatureRegistry.java?rev=612381&r1=612380&r2=612381&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetFeatureRegistry.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetFeatureRegistry.java Wed Jan 16 00:06:30 2008
@@ -75,6 +75,7 @@
core.put(entry.getName(), entry);
}
}
+
// Everything depends on core JS being set up first because in gadget
// rendering mode, we pre-populate some of the data.
core.put(FEAT_MSG_BUNDLE,
Added: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/CajaContentFilter.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/CajaContentFilter.java?rev=612381&view=auto
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/CajaContentFilter.java (added)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/CajaContentFilter.java Wed Jan 16 00:06:30 2008
@@ -0,0 +1,99 @@
+/*
+ * Licensed 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.http;
+
+import org.apache.shindig.gadgets.GadgetContentFilter;
+import org.apache.shindig.gadgets.GadgetException;
+
+import com.google.caja.lexer.ExternalReference;
+import com.google.caja.opensocial.DefaultGadgetRewriter;
+import com.google.caja.opensocial.GadgetContentRewriter;
+import com.google.caja.opensocial.UriCallback;
+import com.google.caja.opensocial.GadgetRewriteException;
+import com.google.caja.opensocial.UriCallbackException;
+import com.google.caja.opensocial.UriCallbackOption;
+import com.google.caja.reporting.SimpleMessageQueue;
+import com.google.caja.reporting.MessageQueue;
+import com.google.caja.reporting.Message;
+import com.google.caja.reporting.MessageContext;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+
+public class CajaContentFilter implements GadgetContentFilter {
+ private final URI retrievedUri;
+
+ public CajaContentFilter(URI retrievedUri) {
+ this.retrievedUri = retrievedUri;
+ }
+
+ public String filter(String content) throws GadgetException {
+ UriCallback cb = new UriCallback() {
+ public UriCallbackOption getOption(ExternalReference externalReference,
+ String string) {
+ return UriCallbackOption.REWRITE;
+ }
+
+ public Reader retrieve(ExternalReference externalReference, String string)
+ throws UriCallbackException {
+ throw new UriCallbackException(externalReference);
+ }
+
+ public URI rewrite(ExternalReference externalReference, String string)
+ throws UriCallbackException {
+ return externalReference.getUri();
+ }
+ };
+
+ MessageQueue mq = new SimpleMessageQueue();
+ GadgetContentRewriter rw = new DefaultGadgetRewriter(mq);
+ Readable input = new StringReader(content);
+ Appendable output = new StringBuilder();
+
+ try {
+ rw.rewriteContent(retrievedUri, input, cb, output);
+ } catch (GadgetRewriteException e) {
+ throwCajolingException(e, mq);
+ } catch (UriCallbackException e) {
+ throwCajolingException(e, mq);
+ } catch (IOException e) {
+ throwCajolingException(e, mq);
+ }
+
+ return output.toString();
+ }
+
+ private void throwCajolingException(Exception cause, MessageQueue mq)
+ throws GadgetException {
+ StringBuilder errbuilder = new StringBuilder();
+ MessageContext mc = new MessageContext();
+ List<GadgetException> exceptions = new ArrayList<GadgetException>();
+
+ if (cause != null) {
+ errbuilder.append(cause).append("\n");
+ }
+
+ for (Message m : mq.getMessages()) {
+ errbuilder.append(m.format(mc)).append("\n");
+ }
+
+ throw new GadgetException(
+ GadgetException.Code.MALFORMED_FOR_SAFE_INLINING,
+ errbuilder.toString());
+ }
+}
Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/GadgetRenderingServlet.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/GadgetRenderingServlet.java?rev=612381&r1=612380&r2=612381&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/GadgetRenderingServlet.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/GadgetRenderingServlet.java Wed Jan 16 00:06:30 2008
@@ -16,6 +16,7 @@
import org.apache.shindig.gadgets.BasicGadgetDataCache;
import org.apache.shindig.gadgets.BasicRemoteContentFetcher;
import org.apache.shindig.gadgets.Gadget;
+import org.apache.shindig.gadgets.GadgetContentFilter;
import org.apache.shindig.gadgets.GadgetDataCache;
import org.apache.shindig.gadgets.GadgetException;
import org.apache.shindig.gadgets.GadgetFeatureRegistry;
@@ -37,6 +38,8 @@
import java.net.URLEncoder;
import java.util.Enumeration;
import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Executor;
@@ -55,12 +58,12 @@
private GadgetServer gadgetServer;
private String jsServicePath;
private GadgetFeatureRegistry registry;
+ private static final String CAJA_PARAM = "caja";
private static final String USERPREF_PARAM_PREFIX = "up_";
private static final String LIBS_PARAM_NAME = "libs";
private static final String JS_FILE_SUFFIX = ".js";
public static final String DEFAULT_JS_SERVICE_PATH = "js/";
-
/**
* Creates a {@code GadgetRenderingServlet} with default executor,
* caches, etc.
@@ -145,6 +148,13 @@
ProcessingOptions options = new ProcessingOptions();
options.ignoreCache = getIgnoreCache(req);
+ // Prepare a list of GadgetContentFilters applied to the output
+ List<GadgetContentFilter> contentFilters =
+ new LinkedList<GadgetContentFilter>();
+ if (getUseCaja(req)) {
+ contentFilters.add(new CajaContentFilter(uri));
+ }
+
Gadget gadget = null;
try {
gadget = gadgetServer.processGadget(gadgetId,
@@ -152,17 +162,19 @@
context.getLocale(),
RenderingContext.GADGET,
options);
- outputGadget(gadget, resp);
+ outputGadget(gadget, contentFilters, resp);
} catch (GadgetServer.GadgetProcessException e) {
outputErrors(e, resp);
}
}
- private void outputGadget(Gadget gadget, HttpServletResponse resp)
- throws IOException {
+ private void outputGadget(Gadget gadget,
+ List<GadgetContentFilter> contentFilters,
+ HttpServletResponse resp)
+ throws IOException, GadgetServer.GadgetProcessException {
switch(gadget.getContentType()) {
case HTML:
- outputHtmlGadget(gadget, resp);
+ outputHtmlGadget(gadget, contentFilters, resp);
break;
case URL:
outputUrlGadget(gadget, resp);
@@ -174,8 +186,10 @@
}
}
- private void outputHtmlGadget(Gadget gadget, HttpServletResponse resp)
- throws IOException {
+ private void outputHtmlGadget(Gadget gadget,
+ List<GadgetContentFilter> contentFilters,
+ HttpServletResponse resp)
+ throws IOException, GadgetServer.GadgetProcessException {
resp.setContentType("text/html");
StringBuilder markup = new StringBuilder();
@@ -190,6 +204,7 @@
StringBuilder externJs = new StringBuilder();
StringBuilder inlineJs = new StringBuilder();
String externFmt = "<script src=\"%s\"></script>\n";
+
for (JsLibrary library : gadget.getJsLibraries()) {
if (library.getType() == JsLibrary.Type.URL) {
externJs.append(String.format(externFmt, library.getContent()));
@@ -197,14 +212,30 @@
inlineJs.append(library.getContent()).append("\n");
}
}
+
if (inlineJs.length() > 0) {
markup.append("<script><!--\n").append(inlineJs)
- .append("\n-->\n</script>");
+ .append("\n-->\n</script>");
}
+
if (externJs.length() > 0) {
markup.append(externJs);
}
- markup.append(gadget.getContentData());
+
+ List<GadgetException> gadgetExceptions = new LinkedList<GadgetException>();
+ String content = gadget.getContentData();
+ for (GadgetContentFilter filter : contentFilters) {
+ try {
+ content = filter.filter(content);
+ } catch (GadgetException e) {
+ gadgetExceptions.add(e);
+ }
+ }
+ if (gadgetExceptions.size() > 0) {
+ throw new GadgetServer.GadgetProcessException(gadgetExceptions);
+ }
+
+ markup.append(content);
markup.append("<script>gadgets.util.runOnLoadHandlers();</script>");
markup.append("</body></html>");
@@ -314,5 +345,10 @@
noCacheParam = req.getParameter("bpc");
}
return noCacheParam != null && noCacheParam.equals("1");
+ }
+
+ protected boolean getUseCaja(HttpServletRequest req) {
+ String cajaParam = req.getParameter(CAJA_PARAM);
+ return cajaParam != null && cajaParam.equals("1");
}
}