You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by th...@apache.org on 2014/01/09 19:47:45 UTC
git commit: TAP5-938: Expose ability to render a portion of a page (a
Block, Component, etc.) without using internal services
Updated Branches:
refs/heads/master 10425b8ee -> 8b7be0060
TAP5-938: Expose ability to render a portion of a page (a Block,
Component, etc.) without using internal services
Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/8b7be006
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/8b7be006
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/8b7be006
Branch: refs/heads/master
Commit: 8b7be0060db3b4995896211eae26242559ece227
Parents: 10425b8
Author: Thiago H. de Paula Figueiredo <th...@apache.org>
Authored: Thu Jan 9 16:47:22 2014 -0200
Committer: Thiago H. de Paula Figueiredo <th...@apache.org>
Committed: Thu Jan 9 16:47:22 2014 -0200
----------------------------------------------------------------------
.../services/PartialTemplateRendererImpl.java | 71 +++++++++++++++
.../tapestry5/modules/TapestryModule.java | 1 +
.../services/PartialTemplateRenderer.java | 66 ++++++++++++++
.../test/app1/PartialTemplateRendererDemo.tml | 25 ++++++
.../app1/PartialTemplateRendererTests.groovy | 63 +++++++++++++
.../tapestry5/integration/app1/pages/Index.java | 4 +-
.../app1/pages/PartialTemplateRendererDemo.java | 94 ++++++++++++++++++++
7 files changed, 323 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/8b7be006/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PartialTemplateRendererImpl.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PartialTemplateRendererImpl.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PartialTemplateRendererImpl.java
new file mode 100644
index 0000000..4a8f62f
--- /dev/null
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PartialTemplateRendererImpl.java
@@ -0,0 +1,71 @@
+// Copyright 2014, The Apache Software Foundation
+//
+// 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.tapestry5.internal.services;
+
+import org.apache.tapestry5.MarkupWriter;
+import org.apache.tapestry5.dom.Document;
+import org.apache.tapestry5.ioc.services.TypeCoercer;
+import org.apache.tapestry5.runtime.RenderCommand;
+import org.apache.tapestry5.services.PartialTemplateRenderer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PartialTemplateRendererImpl implements PartialTemplateRenderer
+{
+
+ final private static Logger LOGGER = LoggerFactory.getLogger(PartialTemplateRendererImpl.class);
+
+ final private TypeCoercer typeCoercer;
+
+ public PartialTemplateRendererImpl(TypeCoercer typeCoercer)
+ {
+ super();
+ this.typeCoercer = typeCoercer;
+ }
+
+ public Document renderAsDocument(Object object)
+ {
+ RenderCommand renderCommand = toRenderCommand(object);
+ MarkupWriter markupWriter = new MarkupWriterImpl();
+ RenderQueueImpl renderQueue = new RenderQueueImpl(LOGGER);
+ renderQueue.push(renderCommand);
+ renderQueue.run(markupWriter);
+ return markupWriter.getDocument();
+ }
+
+ public String render(Object object)
+ {
+ return renderAsDocument(object).toString();
+ }
+
+ private RenderCommand toRenderCommand(Object object)
+ {
+ RenderCommand renderCommand = null;
+ if (object instanceof RenderCommand)
+ {
+ renderCommand = (RenderCommand) object;
+ }
+ else {
+ try {
+ renderCommand = typeCoercer.coerce(object, RenderCommand.class);
+ }
+ catch (RuntimeException e) {
+ throw new IllegalArgumentException(
+ String.format("Couldn't find a coercion from %s to RenderCommand", object.getClass().getName()), e);
+ }
+ }
+ return renderCommand;
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/8b7be006/tapestry-core/src/main/java/org/apache/tapestry5/modules/TapestryModule.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/modules/TapestryModule.java b/tapestry-core/src/main/java/org/apache/tapestry5/modules/TapestryModule.java
index 4393236..0939811 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/modules/TapestryModule.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/modules/TapestryModule.java
@@ -371,6 +371,7 @@ public final class TapestryModule
binder.bind(ValueEncoderSource.class, ValueEncoderSourceImpl.class);
binder.bind(PathConstructor.class, PathConstructorImpl.class);
binder.bind(DateUtilities.class, DateUtilitiesImpl.class);
+ binder.bind(PartialTemplateRenderer.class, PartialTemplateRendererImpl.class);
}
// ========================================================================
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/8b7be006/tapestry-core/src/main/java/org/apache/tapestry5/services/PartialTemplateRenderer.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/services/PartialTemplateRenderer.java b/tapestry-core/src/main/java/org/apache/tapestry5/services/PartialTemplateRenderer.java
new file mode 100644
index 0000000..e4a595a
--- /dev/null
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/services/PartialTemplateRenderer.java
@@ -0,0 +1,66 @@
+// Copyright 2014, The Apache Software Foundation
+//
+// 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.tapestry5.services;
+
+import org.apache.tapestry5.Block;
+import org.apache.tapestry5.alerts.Alert;
+import org.apache.tapestry5.dom.Document;
+import org.apache.tapestry5.dom.Element;
+import org.apache.tapestry5.ioc.services.TypeCoercer;
+import org.apache.tapestry5.runtime.RenderCommand;
+
+/**
+ * <p>
+ * Service that provides methods that render {@link Block}s (<code><t:block>>)</code>,
+ * component instances and {@link RenderCommand}s to a {@link String} or
+ * {@link Document org.apache.tapestry5.dom.Document} in a programatic way.
+ * </p>
+ * <p>
+ * This service was created for situations in which a page or component needs to generate some markup
+ * that wouldn't be rendered normally, but for external use, such as e-mails, returning
+ * HTML for AJAX requests or passing HTML instead of plain string for an {@link Alert}.
+ * </p>
+ * <p>
+ * The name of this interface comes from <a href="https://issues.apache.org/jira/browse/TAP5-938">TAP5-938</a>:
+ * <em>Expose ability to render a portion of a page (a Block, Component, etc.) without using internal services</em>.
+ * </p>
+ * @since 5.4
+ */
+public interface PartialTemplateRenderer
+{
+
+ /**
+ * <p>
+ * Renders an object, probably a {@link Block} or component instance, to a string.
+ * This method supposes any kind of initialization needed
+ * was already done. CSS and JavaScript inclusions or importings are ignored.
+ * The object must implement {@link RenderCommand} or being able to be coerced to it
+ * by {@link TypeCoercer}.
+ * <p>
+ * @param object an object, probably a {@link Block} or component instance or {@link RenderCommand}.
+ * @throws IllegalArgumentException if the object isn't a {@link RenderCommand} and cannot be coerced to it by {@link TypeCoercer}.
+ */
+ String render(Object object);
+
+ /**
+ * Renders an object to a {@link Document} following the same rules as {@link #render(Object)}
+ * This method supposes any kind of initialization needed
+ * was already done. CSS and JavaScript inclusions or importings are ignored.
+ *
+ * @param renderCommand a {@link RenderCommand}.
+ * @return a {@link Document}.
+ */
+ Document renderAsDocument(Object object);
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/8b7be006/tapestry-core/src/test/app1/PartialTemplateRendererDemo.tml
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/app1/PartialTemplateRendererDemo.tml b/tapestry-core/src/test/app1/PartialTemplateRendererDemo.tml
new file mode 100644
index 0000000..6f41863
--- /dev/null
+++ b/tapestry-core/src/test/app1/PartialTemplateRendererDemo.tml
@@ -0,0 +1,25 @@
+<t:border xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd"
+ xmlns:p="tapestry:parameter">
+
+ <t:block id="someBlock">
+ <!-- One component that generates a good amount of markup -->
+ <t:beandisplay t:id="insideBlock" t:object="object"/>
+ </t:block>
+
+ <div id="original">
+ <t:delegate to="block:someblock"/>
+ </div>
+
+ <div id="serviceRenderedBlock">
+ <t:outputRaw value="serviceRenderedBlock"/>
+ </div>
+
+ <div id="originalBeanDisplay">
+ <t:beandisplay t:id="beanDisplay" t:object="object"/>
+ </div>
+
+ <div id="serviceRenderedComponent">
+ <t:outputRaw value="serviceRenderedComponent"/>
+ </div>
+
+</t:border>
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/8b7be006/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/PartialTemplateRendererTests.groovy
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/PartialTemplateRendererTests.groovy b/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/PartialTemplateRendererTests.groovy
new file mode 100644
index 0000000..5943a69
--- /dev/null
+++ b/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/PartialTemplateRendererTests.groovy
@@ -0,0 +1,63 @@
+// Copyright 2014 The Apache Software Foundation
+//
+// 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.tapestry5.integration.app1
+
+import org.apache.tapestry5.services.PartialTemplateRenderer;
+import org.testng.annotations.Test
+import org.junit.Assert;
+
+/**
+ * Tests the {@link PartialTemplateRenderer} service.
+ *
+ * @since 5.4
+ */
+class PartialTemplateRendererTests extends App1TestCase {
+
+ @Test
+ void render_block() {
+
+ open "/partialtemplaterendererdemo"
+
+ assertEquals(getAttribute("css=#original dl@class"), getAttribute("css=#serviceRenderedBlock dl@class"))
+
+ // checking whether service-rendered block is the same as the original
+ for (int i = 1; i <= getXpathCount("//div[@id='original']/dl/*"); i++) {
+
+ assertEquals(
+ getAttribute("//div[@id='original']/dl/*[" + i + "]@class"),
+ getAttribute("//div[@id='serviceRenderedBlock']/dl/*[" + i + "]/@class"))
+
+ assertEquals(
+ getText("//div[@id='original']/dl/*[" + i + "]"),
+ getText("//div[@id='serviceRenderedBlock']/dl/*[" + i + "]"))
+
+ }
+
+ // checking whether service-rendered component is the same as the original
+ for (int i = 1; i <= getXpathCount("//div[@id='original']/dl/*"); i++) {
+
+ assertEquals(
+ getAttribute("//div[@id='originalBeanDisplay']/dl/*[" + i + "]@class"),
+ getAttribute("//div[@id='serviceRenderedComponent']/dl/*[" + i + "]/@class"))
+
+ assertEquals(
+ getText("//div[@id='originalBeanDisplay']/dl/*[" + i + "]"),
+ getText("//div[@id='serviceRenderedComponent']/dl/*[" + i + "]"))
+
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/8b7be006/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java
index a3f2337..3d276ca 100644
--- a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java
@@ -547,7 +547,9 @@ public class Index
new Item("UnknownActivationContextDemo", "Unknown Activation Context Demo", "Page refuse to serve if called with an unknown activation context (TAP5-2070)",
"Unwanted", "context"),
- new Item("ModuleConfigurationCallbackDemo", "ModuleConfigurationCallback Demo", "Shows an example of changing the Require.js configuration using JavaScriptSupport.addModuleConfigurationDemo()")
+ new Item("ModuleConfigurationCallbackDemo", "ModuleConfigurationCallback Demo", "Shows an example of changing the Require.js configuration using JavaScriptSupport.addModuleConfigurationDemo()"),
+
+ new Item("PartialTemplateRendererDemo", "PartialTemplateRenderer Demo", "Shows some examples of rendering blocks and components to a String using PartialTemplateRenderer")
);
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/8b7be006/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/PartialTemplateRendererDemo.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/PartialTemplateRendererDemo.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/PartialTemplateRendererDemo.java
new file mode 100644
index 0000000..ecd2fb3
--- /dev/null
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/PartialTemplateRendererDemo.java
@@ -0,0 +1,94 @@
+// Copyright 2009-2013 The Apache Software Foundation
+//
+// 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.tapestry5.integration.app1.pages;
+
+import java.util.Date;
+
+import org.apache.tapestry5.Block;
+import org.apache.tapestry5.annotations.InjectComponent;
+import org.apache.tapestry5.annotations.Property;
+import org.apache.tapestry5.corelib.components.BeanDisplay;
+import org.apache.tapestry5.ioc.annotations.Inject;
+import org.apache.tapestry5.services.PartialTemplateRenderer;
+
+public class PartialTemplateRendererDemo
+{
+
+ @Inject
+ @Property
+ private Block someBlock;
+
+ @Inject
+ private PartialTemplateRenderer partialTemplateRenderer;
+
+ @InjectComponent
+ private BeanDisplay beanDisplay;
+
+ @Property
+ private Pojo object;
+
+ void setupRender() {
+ object = new Pojo();
+ object.setDate(new Date(21342345234444L));
+ object.setString(String.valueOf(System.currentTimeMillis()));
+ object.setInteger((int) (System.currentTimeMillis() % 234123));
+ }
+
+ public String getServiceRenderedBlock() {
+ return partialTemplateRenderer.render(someBlock);
+ }
+
+ public String getServiceRenderedComponent() {
+ return partialTemplateRenderer.render(beanDisplay);
+ }
+
+ public static class Pojo
+ {
+ private int integer;
+ private String string;
+ private Date date;
+
+ public int getInteger()
+ {
+ return integer;
+ }
+
+ public void setInteger(int i)
+ {
+ this.integer = i;
+ }
+
+ public String getString()
+ {
+ return string;
+ }
+
+ public void setString(String s)
+ {
+ this.string = s;
+ }
+
+ public Date getDate()
+ {
+ return date;
+ }
+
+ public void setDate(Date date)
+ {
+ this.date = date;
+ }
+
+ }
+}