You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shindig.apache.org by et...@apache.org on 2008/09/25 17:58:19 UTC
svn commit: r699010 - in /incubator/shindig/trunk/java/gadgets/src:
main/java/org/apache/shindig/gadgets/
main/java/org/apache/shindig/gadgets/render/
test/java/org/apache/shindig/gadgets/render/
Author: etnu
Date: Thu Sep 25 08:58:19 2008
New Revision: 699010
URL: http://svn.apache.org/viewvc?rev=699010&view=rev
Log:
Splitting responsibilities of Renderer into two classes to reduce dependencies. Requires temporary renaming.
Added:
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/HtmlRenderer.java
- copied, changed from r698928, incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/Renderer.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderDispatcher.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingResults.java
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/HtmlRendererTest.java
- copied, changed from r698928, incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/RendererTest.java
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/RenderDispatcherTest.java
Removed:
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/Renderer.java
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/RendererTest.java
Modified:
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Gadget.java
Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Gadget.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Gadget.java?rev=699010&r1=699009&r2=699010&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Gadget.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Gadget.java Thu Sep 25 08:58:19 2008
@@ -45,6 +45,9 @@
private GadgetContext context;
private GadgetSpec spec;
private Preloads preloads;
+ private View currentView;
+
+ @Deprecated
private MutableContent mutableContent;
@Deprecated
@@ -53,9 +56,6 @@
@Deprecated
private Map<Preload, Future<HttpResponse>> preloadMap;
- @Deprecated
- private View currentView;
-
public Gadget() { }
/**
@@ -107,17 +107,6 @@
return spec;
}
- /**
- * @param mutableContent Content associated with rendering this gadget.
- */
- public Gadget setMutableContent(MutableContent mutableContent) {
- this.mutableContent = mutableContent;
- return this;
- }
-
- public MutableContent getMutableContent() {
- return mutableContent;
- }
/**
* Sets the current content of the rendered output of this gadget.
@@ -133,10 +122,6 @@
return mutableContent.getContent();
}
- public GadgetHtmlNode getParseTree() {
- return mutableContent.getParseTree();
- }
-
/**
* @param preloads The preloads for the gadget that is being processed.
*/
@@ -149,6 +134,18 @@
return preloads;
}
+ public Gadget setCurrentView(View currentView) {
+ this.currentView = currentView;
+ return this;
+ }
+
+ /**
+ * @return The View applicable for the current request.
+ */
+ public View getCurrentView() {
+ return currentView;
+ }
+
/**
* Convenience function for getting the locale spec for the current context.
*
@@ -160,7 +157,21 @@
return spec.getModulePrefs().getLocale(context.getLocale());
}
+ @Deprecated
+ public Gadget setMutableContent(MutableContent mutableContent) {
+ this.mutableContent = mutableContent;
+ return this;
+ }
+
+ @Deprecated
+ public MutableContent getMutableContent() {
+ return mutableContent;
+ }
+ @Deprecated
+ public GadgetHtmlNode getParseTree() {
+ return mutableContent.getParseTree();
+ }
/**
* @return A mutable collection of JsLibrary objects attached to this Gadget.
@@ -179,14 +190,6 @@
}
/**
- * @return The View applicable for the current request.
- */
- @Deprecated
- public View getCurrentView() {
- return currentView;
- }
-
- /**
* Attempts to extract the "current" view for this gadget.
*
* @param config The container configuration; used to look for any view name
Copied: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/HtmlRenderer.java (from r698928, incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/Renderer.java)
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/HtmlRenderer.java?p2=incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/HtmlRenderer.java&p1=incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/Renderer.java&r1=698928&r2=699010&rev=699010&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/Renderer.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/HtmlRenderer.java Thu Sep 25 08:58:19 2008
@@ -18,12 +18,10 @@
*/
package org.apache.shindig.gadgets.render;
-import org.apache.shindig.common.ContainerConfig;
import org.apache.shindig.common.uri.Uri;
import org.apache.shindig.gadgets.Gadget;
import org.apache.shindig.gadgets.GadgetContext;
import org.apache.shindig.gadgets.GadgetException;
-import org.apache.shindig.gadgets.GadgetSpecFactory;
import org.apache.shindig.gadgets.http.ContentFetcherFactory;
import org.apache.shindig.gadgets.http.HttpRequest;
import org.apache.shindig.gadgets.http.HttpResponse;
@@ -34,27 +32,18 @@
import com.google.inject.Inject;
-import org.json.JSONArray;
-import org.json.JSONException;
-
/**
* Handles producing output markup for a gadget based on the provided context.
*/
-public class Renderer {
- private final GadgetSpecFactory gadgetSpecFactory;
+public class HtmlRenderer {
private final ContentFetcherFactory fetcher;
private final PreloaderService preloader;
- private final ContainerConfig containerConfig;
@Inject
- public Renderer(GadgetSpecFactory gadgetSpecFactory,
- ContentFetcherFactory fetcher,
- PreloaderService preloader,
- ContainerConfig containerConfig) {
- this.gadgetSpecFactory = gadgetSpecFactory;
+ public HtmlRenderer(ContentFetcherFactory fetcher,
+ PreloaderService preloader) {
this.fetcher = fetcher;
this.preloader = preloader;
- this.containerConfig = containerConfig;
}
/**
@@ -66,30 +55,15 @@
*
* - Perform rewriting operations on the output content, handled by Rewriter.
*
- * @param context The context for the gadget rendering operation.
+ * @param gadget The gadget for the rendering operation.
* @return The rendered gadget content
* @throws RenderingException if any issues arise that prevent rendering.
*/
- public String render(GadgetContext context) throws RenderingException {
+ public String render(Gadget gadget) throws RenderingException {
try {
- GadgetSpec spec = gadgetSpecFactory.getGadgetSpec(context);
-
- Gadget gadget = new Gadget()
- .setContext(context)
- .setSpec(spec);
-
- // TODO: Move Gadget.getView into a utility method so that the correct view can be pulled from
- // the gadget with aliasing done automatically.
- View view = getView(context, spec);
-
- if (view == null) {
- throw new RenderingException("Unable to locate an appropriate view in this gadget. " +
- "Requested: '" + context.getView() + "' Available: " + spec.getViews().keySet());
- }
-
- if (view.getType() == View.ContentType.URL) {
- throw new RenderingException("Attempted to render a url-type gadget.");
- }
+ View view = gadget.getCurrentView();
+ GadgetContext context = gadget.getContext();
+ GadgetSpec spec = gadget.getSpec();
gadget.setPreloads(preloader.preload(context, spec));
@@ -98,9 +72,9 @@
} else {
// TODO: Add current url to GadgetContext to support transitive proxying.
HttpRequest request = new HttpRequest(Uri.fromJavaUri(view.getHref()))
- .setSecurityToken(context.getToken())
.setOAuthArguments(new OAuthArguments(view))
.setAuthType(view.getAuthType())
+ .setSecurityToken(context.getToken())
.setContainer(context.getContainer())
.setGadget(Uri.fromJavaUri(context.getUrl()));
HttpResponse response = fetcher.fetch(request);
@@ -110,34 +84,4 @@
throw new RenderingException(e);
}
}
-
- /**
- * Attempts to extract the "current" view for the given gadget.
- */
- private View getView(GadgetContext context, GadgetSpec spec) {
- String viewName = context.getView();
- View view = spec.getView(viewName);
- if (view == null) {
- JSONArray aliases = containerConfig.getJsonArray(context.getContainer(),
- "gadgets.features/views/" + viewName + "/aliases");
- if (aliases != null) {
- try {
- for (int i = 0, j = aliases.length(); i < j; ++i) {
- viewName = aliases.getString(i);
- view = spec.getView(viewName);
- if (view != null) {
- break;
- }
- }
- } catch (JSONException e) {
- view = null;
- }
- }
-
- if (view == null) {
- view = spec.getView(GadgetSpec.DEFAULT_VIEW);
- }
- }
- return view;
- }
}
Added: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderDispatcher.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderDispatcher.java?rev=699010&view=auto
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderDispatcher.java (added)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderDispatcher.java Thu Sep 25 08:58:19 2008
@@ -0,0 +1,179 @@
+/*
+ * 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.render;
+
+import org.apache.shindig.common.ContainerConfig;
+import org.apache.shindig.common.uri.Uri;
+import org.apache.shindig.gadgets.Gadget;
+import org.apache.shindig.gadgets.GadgetContext;
+import org.apache.shindig.gadgets.GadgetException;
+import org.apache.shindig.gadgets.GadgetSpecFactory;
+import org.apache.shindig.gadgets.spec.GadgetSpec;
+import org.apache.shindig.gadgets.spec.View;
+
+import com.google.inject.Inject;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+
+import java.net.URI;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.regex.Pattern;
+
+/**
+ * Validates a rendering request parameters before calling an appropriate renderer.
+ *
+ * TODO: Rename to Renderer
+ */
+public class RenderDispatcher {
+ private static final Logger LOG = Logger.getLogger(RenderDispatcher.class.getName());
+ private final HtmlRenderer renderer;
+ private final GadgetSpecFactory gadgetSpecFactory;
+ private final ContainerConfig containerConfig;
+
+ @Inject
+ public RenderDispatcher(HtmlRenderer renderer,
+ GadgetSpecFactory gadgetSpecFactory,
+ ContainerConfig containerConfig) {
+ this.renderer = renderer;
+ this.gadgetSpecFactory = gadgetSpecFactory;
+ this.containerConfig = containerConfig;
+ }
+
+ /**
+ * Attempts to render the requested gadget.
+ *
+ * @return The results of the rendering attempt.
+ *
+ * TODO: Localize error messages.
+ */
+ public RenderingResults render(GadgetContext context) {
+ URI url = context.getUrl();
+
+ if (url == null) {
+ return RenderingResults.error("Missing or malformed url parameter");
+ }
+
+ if (!"http".equalsIgnoreCase(url.getScheme()) && !"https".equalsIgnoreCase(url.getScheme())) {
+ return RenderingResults.error("Unsupported scheme (must be http or https).");
+ }
+
+ if (!validateParent(context)) {
+ return RenderingResults.error("Unsupported parent parameter. Check your container code.");
+ }
+
+ try {
+ GadgetSpec spec = gadgetSpecFactory.getGadgetSpec(context);
+ View view = getView(context, spec);
+
+ if (view == null) {
+ return RenderingResults.error("Unable to locate an appropriate view in this gadget. " +
+ "Requested: '" + context.getView() + "' Available: " + spec.getViews().keySet());
+ }
+
+ Gadget gadget = new Gadget()
+ .setContext(context)
+ .setSpec(spec)
+ .setCurrentView(view);
+
+ if (view.getType() == View.ContentType.URL) {
+ return RenderingResults.mustRedirect(getTypeUrlRedirect(gadget));
+ }
+
+ // TODO: Validate locked domain.
+
+ return RenderingResults.ok(renderer.render(gadget));
+ } catch (RenderingException e) {
+ LOG.log(Level.WARNING, "Failed to render gadget " + context.getUrl(), e);
+ return RenderingResults.error(e.getLocalizedMessage());
+ } catch (GadgetException e) {
+ LOG.log(Level.WARNING, "Failed to process gadget " + context.getUrl(), e);
+ return RenderingResults.error(e.getLocalizedMessage());
+ }
+ }
+
+ /**
+ * Validates that the parent parameter was acceptable.
+ *
+ * @return True if the parent parameter is valid for the current container.
+ */
+ private boolean validateParent(GadgetContext context) {
+ String container = context.getContainer();
+ String parent = context.getParameter("parent");
+
+ if (parent == null) {
+ // If there is no parent parameter, we are still safe because no
+ // dependent code ever has to trust it anyway.
+ return true;
+ }
+
+ try {
+ JSONArray parents = containerConfig.getJsonArray(container, "gadgets.parent");
+ if (parents == null) {
+ return true;
+ } else {
+ // We need to check each possible parent parameter against this regex.
+ for (int i = 0, j = parents.length(); i < j; ++i) {
+ if (Pattern.matches(parents.getString(i), parent)) {
+ return true;
+ }
+ }
+ }
+ } catch (JSONException e) {
+ LOG.log(Level.WARNING, "Configuration error", e);
+ }
+ return false;
+ }
+
+ private Uri getTypeUrlRedirect(Gadget gadget) {
+ // TODO: This should probably just call UrlGenerator.getIframeUrl().
+ return Uri.fromJavaUri(gadget.getCurrentView().getHref());
+ }
+
+ /**
+ * Attempts to extract the "current" view for the given gadget.
+ */
+ private View getView(GadgetContext context, GadgetSpec spec) {
+ String viewName = context.getView();
+ View view = spec.getView(viewName);
+ if (view == null) {
+ JSONArray aliases = containerConfig.getJsonArray(context.getContainer(),
+ "gadgets.features/views/" + viewName + "/aliases");
+ if (aliases != null) {
+ try {
+ for (int i = 0, j = aliases.length(); i < j; ++i) {
+ viewName = aliases.getString(i);
+ view = spec.getView(viewName);
+ if (view != null) {
+ break;
+ }
+ }
+ } catch (JSONException e) {
+ view = null;
+ }
+ }
+
+ if (view == null) {
+ view = spec.getView(GadgetSpec.DEFAULT_VIEW);
+ }
+ }
+ return view;
+ }
+}
Added: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingResults.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingResults.java?rev=699010&view=auto
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingResults.java (added)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingResults.java Thu Sep 25 08:58:19 2008
@@ -0,0 +1,86 @@
+/*
+ * 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.render;
+
+import org.apache.shindig.common.uri.Uri;
+import org.apache.shindig.common.util.Check;
+
+/**
+ * Contains the results of a rendering operation.
+ */
+public class RenderingResults {
+ private final Status status;
+ private final String content;
+ private final String errorMessage;
+ private final Uri redirect;
+
+ private RenderingResults(Status status, String content, String errorMessage, Uri redirect) {
+ this.status = status;
+ this.content = content;
+ this.errorMessage = errorMessage;
+ this.redirect = redirect;
+ }
+
+ public static RenderingResults ok(String content) {
+ return new RenderingResults(Status.OK, content, null, null);
+ }
+
+ public static RenderingResults error(String errorMessage) {
+ return new RenderingResults(Status.ERROR, null, errorMessage, null);
+ }
+
+ public static RenderingResults mustRedirect(Uri redirect) {
+ return new RenderingResults(Status.MUST_REDIRECT, null, null, redirect);
+ }
+
+ /**
+ * @return The status of the rendering operation.
+ */
+ public Status getStatus() {
+ return status;
+ }
+
+ /**
+ * @return The content to render. Only available when status is OK.
+ */
+ public String getContent() {
+ Check.eq(status, Status.OK, "Only available when status is OK.");
+ return content;
+ }
+
+ /**
+ * @return The error message for rendering. Only available when status is ERROR.
+ */
+ public String getErrorMessage() {
+ Check.eq(status, Status.ERROR, "Only available when status is ERROR.");
+ return errorMessage;
+ }
+
+ /**
+ * @return The error message for rendering. Only available when status is ERROR.
+ */
+ public Uri getRedirect() {
+ Check.eq(status, Status.MUST_REDIRECT, "Only available when status is MUST_REDIRECT.");
+ return redirect;
+ }
+
+ public enum Status {
+ OK, MUST_REDIRECT, ERROR;
+ }
+}
Copied: incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/HtmlRendererTest.java (from r698928, incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/RendererTest.java)
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/HtmlRendererTest.java?p2=incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/HtmlRendererTest.java&p1=incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/RendererTest.java&r1=698928&r2=699010&rev=699010&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/RendererTest.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/HtmlRendererTest.java Thu Sep 25 08:58:19 2008
@@ -23,24 +23,21 @@
import org.apache.shindig.auth.AnonymousSecurityToken;
import org.apache.shindig.auth.SecurityToken;
-import org.apache.shindig.common.ContainerConfig;
-import org.apache.shindig.common.ContainerConfigException;
import org.apache.shindig.common.uri.Uri;
+import org.apache.shindig.common.xml.XmlUtil;
+import org.apache.shindig.gadgets.Gadget;
import org.apache.shindig.gadgets.GadgetContext;
import org.apache.shindig.gadgets.GadgetException;
-import org.apache.shindig.gadgets.GadgetSpecFactory;
import org.apache.shindig.gadgets.http.ContentFetcherFactory;
import org.apache.shindig.gadgets.http.HttpRequest;
import org.apache.shindig.gadgets.http.HttpResponse;
import org.apache.shindig.gadgets.preload.PreloaderService;
import org.apache.shindig.gadgets.preload.Preloads;
import org.apache.shindig.gadgets.spec.GadgetSpec;
+import org.apache.shindig.gadgets.spec.View;
import com.google.common.collect.Maps;
-import org.json.JSONArray;
-import org.json.JSONObject;
-import org.junit.Before;
import org.junit.Test;
import java.net.URI;
@@ -50,121 +47,84 @@
/**
* Tests for Renderer
*/
-public class RendererTest {
+public class HtmlRendererTest {
private static final Uri SPEC_URL = Uri.parse("http://example.org/gadget.xml");
private static final String BASIC_HTML_CONTENT = "Hello, World!";
private static final String PROXIED_HTML_CONTENT = "Hello, Universe!";
private static final Uri PROXIED_HTML_HREF = Uri.parse("http://example.org/proxied.php");
- private static final String GADGET =
- "<Module>" +
- " <ModulePrefs title='foo'/>" +
- " <Content view='html' type='html'>" + BASIC_HTML_CONTENT + "</Content>" +
- " <Content view='proxied' type='html' href='" + PROXIED_HTML_HREF + "'/>" +
- " <Content view='proxied-signed' authz='signed' href='" + PROXIED_HTML_HREF + "'/>" +
- " <Content view='proxied-oauth' authz='oauth' href='" + PROXIED_HTML_HREF + "'/>" +
- " <Content view='url' type='url' href='http://example.org/always/an/error.html'/>" +
- " <Content view='alias' type='html'>" + BASIC_HTML_CONTENT + "</Content>" +
- "</Module>";
+ private static final GadgetContext CONTEXT = new GadgetContext() {
+ @Override
+ public URI getUrl() {
+ return SPEC_URL.toJavaUri();
+ }
+
+ @Override
+ public SecurityToken getToken() {
+ return new AnonymousSecurityToken();
+ }
+ };
- private final FakeGadgetSpecFactory specFactory = new FakeGadgetSpecFactory();
private final FakeContentFetcherFactory fetcher = new FakeContentFetcherFactory();
private final FakePreloaderService preloaderService = new FakePreloaderService();
- private FakeContainerConfig containerConfig;
- private Renderer renderer;
+ private final HtmlRenderer renderer = new HtmlRenderer(fetcher, preloaderService);
- @Before
- public void setUp() throws Exception {
- containerConfig = new FakeContainerConfig();
- renderer = new Renderer(specFactory, fetcher, preloaderService, containerConfig);
- }
-
- private GadgetContext makeContext(final String view, final Uri specUrl) {
- return new GadgetContext() {
- @Override
- public URI getUrl() {
- return specUrl.toJavaUri();
- }
-
- @Override
- public String getView() {
- return view;
- }
-
- @Override
- public SecurityToken getToken() {
- return new AnonymousSecurityToken();
- }
- };
+ private Gadget makeGadget(String content) throws GadgetException {
+ GadgetSpec spec = new GadgetSpec(URI.create("#"),
+ "<Module><ModulePrefs title=''/><Content><![CDATA[" + content + "]]></Content></Module>");
+
+ return new Gadget()
+ .setSpec(spec)
+ .setContext(CONTEXT)
+ .setCurrentView(spec.getView("default"));
+ }
+
+ private Gadget makeHrefGadget(String authz) throws Exception {
+ Gadget gadget = makeGadget("");
+ String doc = "<Content href='" + PROXIED_HTML_HREF + "' authz='" + authz + "'/>";
+ View view = new View("proxied", Arrays.asList(XmlUtil.parse(doc)));
+ gadget.setCurrentView(view);
+ return gadget;
}
@Test
public void renderPlainTypeHtml() throws Exception {
- String content = renderer.render(makeContext("html", SPEC_URL));
+ String content = renderer.render(makeGadget(BASIC_HTML_CONTENT));
assertEquals(BASIC_HTML_CONTENT, content);
}
@Test
- public void renderProxiedTypeHtml() throws Exception {
+ public void renderProxied() throws Exception {
fetcher.plainResponses.put(PROXIED_HTML_HREF, new HttpResponse(PROXIED_HTML_CONTENT));
- String content = renderer.render(makeContext("proxied", SPEC_URL));
+ String content = renderer.render(makeHrefGadget("none"));
assertEquals(PROXIED_HTML_CONTENT, content);
}
- @Test(expected = RenderingException.class)
- public void renderTypeUrl() throws RenderingException {
- renderer.render(makeContext("url", SPEC_URL));
- }
-
- @Test(expected = RenderingException.class)
- public void renderInvalidUrl() throws RenderingException {
- renderer.render(makeContext("url", Uri.parse("doesnotexist")));
- }
-
@Test
- public void doPreloading() throws RenderingException {
- renderer.render(makeContext("html", SPEC_URL));
- assertTrue("Preloading not performed.", preloaderService.wasPreloaded);
- }
-
- @Test
- public void renderProxiedSigned() throws RenderingException {
- fetcher.oauthResponses.put(PROXIED_HTML_HREF, new HttpResponse(PROXIED_HTML_CONTENT));
- String content = renderer.render(makeContext("proxied-signed", SPEC_URL));
+ public void renderProxiedSigned() throws Exception {
+ fetcher.signedResponses.put(PROXIED_HTML_HREF, new HttpResponse(PROXIED_HTML_CONTENT));
+ String content = renderer.render(makeHrefGadget("signed"));
assertEquals(PROXIED_HTML_CONTENT, content);
}
@Test
- public void renderProxiedOAuth() throws RenderingException {
+ public void renderProxiedOAuth() throws Exception {
+ // TODO: We need to disambiguate between oauth and signed.
fetcher.oauthResponses.put(PROXIED_HTML_HREF, new HttpResponse(PROXIED_HTML_CONTENT));
- String content = renderer.render(makeContext("proxied-oauth", SPEC_URL));
+ String content = renderer.render(makeHrefGadget("oauth"));
assertEquals(PROXIED_HTML_CONTENT, content);
}
@Test
- public void doViewAliasing() throws Exception {
- JSONArray aliases = new JSONArray(Arrays.asList("alias"));
- containerConfig.json.put("gadgets.features/views/aliased/aliases", aliases);
- String content = renderer.render(makeContext("alias", SPEC_URL));
- assertEquals(BASIC_HTML_CONTENT, content);
- }
-
- @Test(expected = RenderingException.class)
- public void noSupportedViewThrows() throws RenderingException {
- renderer.render(makeContext("not-real-view", SPEC_URL));
+ public void doPreloading() throws Exception {
+ renderer.render(makeGadget(BASIC_HTML_CONTENT));
+ assertTrue("Preloading not performed.", preloaderService.wasPreloaded);
}
- private static class FakeGadgetSpecFactory implements GadgetSpecFactory {
- public GadgetSpec getGadgetSpec(GadgetContext context) throws GadgetException {
- return new GadgetSpec(context.getUrl(), GADGET);
- }
-
- public GadgetSpec getGadgetSpec(URI uri, boolean ignoreCache) {
- throw new UnsupportedOperationException();
- }
- }
+ // TODO: rewriting
private static class FakeContentFetcherFactory extends ContentFetcherFactory {
private final Map<Uri, HttpResponse> plainResponses = Maps.newHashMap();
+ private final Map<Uri, HttpResponse> signedResponses = Maps.newHashMap();
private final Map<Uri, HttpResponse> oauthResponses = Maps.newHashMap();
public FakeContentFetcherFactory() {
@@ -199,6 +159,8 @@
response = plainResponses.get(request.getUri());
break;
case SIGNED:
+ response = signedResponses.get(request.getUri());
+ break;
case OAUTH:
response = oauthResponses.get(request.getUri());
break;
@@ -221,17 +183,4 @@
return null;
}
}
-
- private static class FakeContainerConfig extends ContainerConfig {
- private final JSONObject json = new JSONObject();
-
- public FakeContainerConfig() throws ContainerConfigException {
- super(null);
- }
-
- @Override
- public Object getJson(String container, String parameter) {
- return json.opt(parameter);
- }
- }
}
Added: incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/RenderDispatcherTest.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/RenderDispatcherTest.java?rev=699010&view=auto
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/RenderDispatcherTest.java (added)
+++ incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/RenderDispatcherTest.java Thu Sep 25 08:58:19 2008
@@ -0,0 +1,232 @@
+/*
+ * 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.render;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.apache.shindig.common.ContainerConfig;
+import org.apache.shindig.common.ContainerConfigException;
+import org.apache.shindig.common.uri.Uri;
+import org.apache.shindig.gadgets.Gadget;
+import org.apache.shindig.gadgets.GadgetContext;
+import org.apache.shindig.gadgets.GadgetException;
+import org.apache.shindig.gadgets.GadgetSpecFactory;
+import org.apache.shindig.gadgets.spec.GadgetSpec;
+
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.net.URI;
+import java.util.Arrays;
+
+/**
+ * Tests for RenderDispatcher.
+ */
+public class RenderDispatcherTest {
+ private static final Uri SPEC_URL = Uri.parse("http://example.org/gadget.xml");
+ private static final Uri TYPE_URL_HREF = Uri.parse("http://example.org/gadget.php");
+ private static final String BASIC_HTML_CONTENT = "Hello, World!";
+ private static final String GADGET =
+ "<Module>" +
+ " <ModulePrefs title='foo'/>" +
+ " <Content view='html' type='html'>" + BASIC_HTML_CONTENT + "</Content>" +
+ " <Content view='url' type='url' href='" + TYPE_URL_HREF + "'/>" +
+ " <Content view='alias' type='html'>" + BASIC_HTML_CONTENT + "</Content>" +
+ "</Module>";
+
+ private final FakeHtmlRenderer htmlRenderer = new FakeHtmlRenderer();
+ private final FakeGadgetSpecFactory gadgetSpecFactory = new FakeGadgetSpecFactory();
+ private FakeContainerConfig containerConfig;
+ private RenderDispatcher renderer;
+
+ @Before
+ public void setUp() throws Exception {
+ containerConfig = new FakeContainerConfig();
+ renderer = new RenderDispatcher(htmlRenderer, gadgetSpecFactory, containerConfig);
+ }
+
+ private GadgetContext makeContext(final String view, final Uri specUrl) {
+ return new GadgetContext() {
+ @Override
+ public URI getUrl() {
+ return specUrl.toJavaUri();
+ }
+
+ @Override
+ public String getView() {
+ return view;
+ }
+ };
+ }
+
+ @Test
+ public void renderTypeHtml() {
+ RenderingResults results = renderer.render(makeContext("html", SPEC_URL));
+ assertEquals(RenderingResults.Status.OK, results.getStatus());
+ assertEquals(BASIC_HTML_CONTENT, results.getContent());
+ }
+
+ @Test
+ public void renderTypeUrl() {
+ RenderingResults results = renderer.render(makeContext("url", SPEC_URL));
+ assertEquals(RenderingResults.Status.MUST_REDIRECT, results.getStatus());
+ assertEquals(TYPE_URL_HREF, results.getRedirect());
+ }
+
+ @Test
+ public void renderInvalidUrl() {
+ RenderingResults results = renderer.render(makeContext("url", Uri.parse("doesnotexist")));
+ assertEquals(RenderingResults.Status.ERROR, results.getStatus());
+ assertNotNull("No error message provided for invalid url.", results.getErrorMessage());
+ }
+
+ @Test
+ public void doViewAliasing() throws Exception {
+ JSONArray aliases = new JSONArray(Arrays.asList("some-alias", "alias"));
+ containerConfig.json.put("gadgets.features/views/aliased/aliases", aliases);
+ RenderingResults results = renderer.render(makeContext("aliased", SPEC_URL));
+ assertEquals(RenderingResults.Status.OK, results.getStatus());
+ assertEquals(BASIC_HTML_CONTENT, results.getContent());
+ }
+
+ @Test
+ public void noSupportedViewThrows() {
+ RenderingResults results = renderer.render(makeContext("not-real-view", SPEC_URL));
+ assertEquals(RenderingResults.Status.ERROR, results.getStatus());
+ assertNotNull("No error message provided for invalid view.", results.getErrorMessage());
+ }
+
+ @Test
+ public void handlesGadgetExceptionGracefully() {
+ gadgetSpecFactory.exception = new GadgetException(GadgetException.Code.INVALID_PATH, "foo");
+ RenderingResults results = renderer.render(makeContext("does-not-matter", SPEC_URL));
+ assertEquals(RenderingResults.Status.ERROR, results.getStatus());
+ assertEquals("foo", results.getErrorMessage());
+ }
+
+ @Test
+ public void handlesRenderingExceptionGracefully() {
+ htmlRenderer.exception = new RenderingException("oh no!");
+ RenderingResults results = renderer.render(makeContext("html", SPEC_URL));
+ assertEquals(RenderingResults.Status.ERROR, results.getStatus());
+ assertEquals("oh no!", results.getErrorMessage());
+ }
+
+ @Test
+ public void validateParent() throws Exception {
+ final String parent = "http://example.org/foo";
+ GadgetContext context = new GadgetContext() {
+ @Override
+ public URI getUrl() {
+ return SPEC_URL.toJavaUri();
+ }
+
+ @Override
+ public String getView() {
+ return "html";
+ }
+
+ @Override
+ public String getParameter(String name) {
+ if (name.equals("parent")) {
+ return parent;
+ }
+ return null;
+ }
+ };
+
+ containerConfig.json.put("gadgets.parent",
+ new JSONArray(Arrays.asList("http:\\/\\/example\\.org\\/[a-z]+", "localhost")));
+
+ RenderingResults results = renderer.render(context);
+ assertEquals(RenderingResults.Status.OK, results.getStatus());
+ }
+
+ @Test
+ public void validateBadParent() throws Exception {
+ final String parent = "http://example.org/foo";
+ GadgetContext context = new GadgetContext() {
+ @Override
+ public URI getUrl() {
+ return SPEC_URL.toJavaUri();
+ }
+
+ @Override
+ public String getParameter(String name) {
+ if (name.equals("parent")) {
+ return parent;
+ }
+ return null;
+ }
+ };
+
+ containerConfig.json.put("gadgets.parent",
+ new JSONArray(Arrays.asList("http:\\/\\/example\\.com\\/[a-z]+", "localhost")));
+
+ RenderingResults results = renderer.render(context);
+ assertEquals(RenderingResults.Status.ERROR, results.getStatus());
+ assertNotNull("No error message provided for bad parent.", results.getErrorMessage());
+ }
+
+ private static class FakeGadgetSpecFactory implements GadgetSpecFactory {
+ private GadgetException exception;
+ public GadgetSpec getGadgetSpec(GadgetContext context) throws GadgetException {
+ if (exception != null) {
+ throw exception;
+ }
+ return new GadgetSpec(context.getUrl(), GADGET);
+ }
+
+ public GadgetSpec getGadgetSpec(URI uri, boolean ignoreCache) {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ private static class FakeContainerConfig extends ContainerConfig {
+ private final JSONObject json = new JSONObject();
+
+ public FakeContainerConfig() throws ContainerConfigException {
+ super(null);
+ }
+
+ @Override
+ public Object getJson(String container, String parameter) {
+ return json.opt(parameter);
+ }
+ }
+
+ private static class FakeHtmlRenderer extends HtmlRenderer {
+ private RenderingException exception;
+
+ public FakeHtmlRenderer() {
+ super(null, null);
+ }
+
+ @Override
+ public String render(Gadget gadget) throws RenderingException {
+ if (exception != null) {
+ throw exception;
+ }
+ return gadget.getCurrentView().getContent();
+ }
+ }
+}