Author: buildbot
Date: Sat Jan 14 17:20:00 2017
New Revision: 1004892
Log:
Production update by buildbot for tapestry
Modified:
websites/production/tapestry/content/cache/main.pageCache
websites/production/tapestry/content/meta-programming-page-content.html
Modified: websites/production/tapestry/content/cache/main.pageCache
==============================================================================
Binary files - no diff available.
Modified:
websites/production/tapestry/content/meta-programming-page-content.html
==============================================================================
--- websites/production/tapestry/content/meta-programming-page-content.html
(original)
+++ websites/production/tapestry/content/meta-programming-page-content.html Sat
Jan 14 17:20:00 2017
@@ -65,7 +65,7 @@
</div>
<div id="content">
- <div id="ConfluenceContent"><h1
id="Meta-ProgrammingPageContent-Meta-ProgrammingPageContent">Meta-Programming
Page Content</h1><p>It is likely that you have some cross-cutting concerns
across your pages, specific features you would like to "mix in" to your pages
without getting tied into knots by inheritance. This is one of those areas
where Tapestry shines.</p><p>This specific example is adapted from a real
client requirement: the client was concerned about other sites wrapping his
content in a frameset and making the site content appear to be theirs. Not all
pages (in some cases, that would be an advantage) but specific pages in the
application. For those pages, the following behaviors were
required:</p><ul><li>Set the X-Frame-Options response header to
"DENY"</li><li>Include JavaScript to "pop" the page out of a frame, if in
one</li></ul><p>Again, this <em>could</em> be done by having a specific
base-class that included a <code>beginRender()</code> method, but I t
hink you'll see that the meta-programming approach is nearly as easy and much
more flexible.</p><h2
id="Meta-ProgrammingPageContent-ComponentMeta-Data">Component
Meta-Data</h2><p>In Tapestry, every component (and remember, pages are
components) has <em>meta data</em>: an extra set of key/value pairs stored in
the component's <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ComponentResources.html">ComponentResources</a>.</p><p>By
hooking into the component class transformation pipeline, we can change an
annotation into meta-data that can be accessed by a filter.</p><h2
id="Meta-ProgrammingPageContent-DefiningtheAnnotation">Defining the
Annotation</h2><div class="code panel pdl" style="border-width: 1px;"><div
class="codeHeader panelHeader pdl" style="border-bottom-width:
1px;"><b>ForbidFraming.java</b></div><div class="codeContent panelContent pdl">
+ <div id="ConfluenceContent"><h1
id="Meta-ProgrammingPageContent-Meta-ProgrammingPageContent">Meta-Programming
Page Content</h1><p>It is likely that you have some cross-cutting concerns
across your pages, specific features you would like to "mix in" to your pages
without getting tied into knots by inheritance. This is one of those areas
where Tapestry shines.</p><p>This specific example is adapted from a real
client requirement: the client was concerned about other sites wrapping his
content in a frameset and making the site content appear to be theirs. Not all
pages (in some cases, that would be an advantage) but specific pages in the
application. For those pages, the following behaviors were
required:</p><ul><li>Set the X-Frame-Options response header to
"DENY"</li><li>Include JavaScript to "pop" the page out of a frame, if in
one</li></ul><p>Again, this <em>could</em> be done by having a specific
base-class that included a <code>beginRender()</code> method, but the
meta-programming approach is nearly as easy and much more flexible.</p><h2
id="Meta-ProgrammingPageContent-ComponentMeta-Data">Component
Meta-Data</h2><p>In Tapestry, every component (and remember, pages are
components) has <em>meta data</em>: an extra set of key/value pairs stored in
the component's <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ComponentResources.html">ComponentResources</a>.</p><p>By
hooking into the component class transformation pipeline, we can change an
annotation into meta-data that can be accessed by a filter.</p><h2
id="Meta-ProgrammingPageContent-DefiningtheAnnotation">Defining the
Annotation</h2><div class="code panel pdl" style="border-width: 1px;"><div
class="codeHeader panelHeader pdl" style="border-bottom-width:
1px;"><b>ForbidFraming.java</b></div><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">package com.fnord.annotations;
import java.lang.annotation.Documented;
@@ -135,7 +135,7 @@ public class ForbidFramingModule {
FnordSymbols.FORBID_FRAMING));
}
</pre>
-</div></div><p>If the ForbidFraming annotation has attributes, we would
provided an implementation of MetaDataExtractor that examined those attributes
to set the meta-data value. Since it has no annotations, the <a
class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/meta/FixedExtractor.html">FixedExtractor</a>
class. The argument is the meta-data key, and the default value is
"true".</p><h2
id="Meta-ProgrammingPageContent-PluggingIntoPageRendering">Plugging Into Page
Rendering</h2><p>The work we ultimately want to do occurs when rendering a
page. Tapestry defines a <a href="pipelinebuilder-service.html">pipeline</a>
for that overall process. The point of a pipeline is that we can add filters to
it. We'll add a filter that checks for the meta-data key and adds the response
header and JavaScript.</p><p>The service is <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/MarkupRenderer
.html">MarkupRenderer</a>, which (being a pipeline service), takes a
configuration of filters (in this case, <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/MarkupRendererFilter.html">MarkupRendererFilter</a>.</p><p>We
contribute into the pipeline; the order is important: since the filter will
need to write JavaScript, it must be added <em>after</em> the built-in filter
that provides the <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/javascript/JavaScriptSupport.html">JavaScriptSupport</a>
environmental object.</p><div class="code panel pdl" style="border-width:
1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width:
1px;"><b>ForbidFramingModule.java (partial)</b></div><div class="codeContent
panelContent pdl">
+</div></div><p>If the ForbidFraming annotation had attributes, we would have
provided an implementation of MetaDataExtractor that examined those attributes
to set the meta-data value. Since it has no attributes, the <a
class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/meta/FixedExtractor.html">FixedExtractor</a>
class can be used. The argument is the meta-data key, and the default value is
"true".</p><h2
id="Meta-ProgrammingPageContent-PluggingIntoPageRendering">Plugging Into Page
Rendering</h2><p>The work we ultimately want to do occurs when rendering a
page. Tapestry defines a <a href="pipelinebuilder-service.html">pipeline</a>
for that overall process. The point of a pipeline is that we can add filters to
it. We'll add a filter that checks for the meta-data key and adds the response
header and JavaScript.</p><p>The service is <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/service
s/MarkupRenderer.html">MarkupRenderer</a>, which (being a pipeline service),
takes a configuration of filters (in this case, <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/MarkupRendererFilter.html">MarkupRendererFilter</a>.</p><p>We
contribute into the pipeline; the order is important: since the filter will
need to write JavaScript, it must be added <em>after</em> the built-in filter
that provides the <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/javascript/JavaScriptSupport.html">JavaScriptSupport</a>
environmental object.</p><div class="code panel pdl" style="border-width:
1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width:
1px;"><b>ForbidFramingModule.java (partial)</b></div><div class="codeContent
panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"> @Contribute(MarkupRenderer.class)
public static void addFilter(
OrderedConfiguration<MarkupRendererFilter> configuration) {
@@ -143,7 +143,7 @@ public class ForbidFramingModule {
"after:JavascriptSupport");
}
</pre>
-</div></div><p>How do you know what filters are built-in and where to add your
own? The right starting point is the JavaDoc for the method of TapestryModule
that contributes the base set: <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/TapestryModule.html#contributeMarkupRenderer(org.apache.tapestry5.ioc.OrderedConfiguration,
boolean, java.lang.String, boolean,
org.apache.tapestry5.ioc.services.SymbolSource,
org.apache.tapestry5.services.AssetSource,
org.apache.tapestry5.services.javascript.JavaScriptStackSource,
org.apache.tapestry5.internal.services.javascript.JavaScriptStackPathConstructor,
org.apache.tapestry5.services.ValidationDecoratorFactory,
org.apache.tapestry5.Asset))">contributeMarkupRenderer()</a></p><h2
id="Meta-ProgrammingPageContent-ImplementingtheFilter">Implementing the
Filter</h2><p>Everything comes together in the filter:</p><div class="code
panel pdl" style="border-width: 1px;"><div class="codeHeader panel
Header pdl" style="border-bottom-width:
1px;"><b>ForbidFramingFilter.java</b></div><div class="codeContent panelContent
pdl">
+</div></div><p>How do you know what filters are built-in and where to add your
own? The right starting point is the JavaDoc for the method of TapestryModule
that contributes the base set: <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/modules/TapestryModule.html">contributeMarkupRenderer()</a></p><h2
id="Meta-ProgrammingPageContent-ImplementingtheFilter">Implementing the
Filter</h2><p>Everything comes together in the filter:</p><div class="code
panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl"
style="border-bottom-width: 1px;"><b>ForbidFramingFilter.java</b></div><div
class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">package com.fnord.services.forbidframing;
import org.apache.tapestry5.MarkupWriter;
@@ -201,7 +201,7 @@ public class ForbidFramingFilter impleme
}
}
</pre>
-</div></div><h2
id="Meta-ProgrammingPageContent-Conclusion">Conclusion</h2><p>That's it: with
the above code, simply adding the @ForbidFraming annotation to a page will add
the response header and associated JavaScript; no inheritance hassles. This
basic pattern can be applied to a wide range of cross-cutting concerns, such as
security, transaction management, logging, or virtually any other kind of
situation that would normally be solved with inheritance or ugly boilerplate
code.</p><div class="confluence-information-macro
confluence-information-macro-note"><span class="aui-icon aui-icon-small
aui-iconfont-warning confluence-information-macro-icon"></span><div
class="confluence-information-macro-body"><p>The code in this example was
designed for Tapestry 5.2. Some names were changed to maintain the anonymity of
the client (whose project is still secret at the time of
writing).</p></div></div></div>
+</div></div><h2
id="Meta-ProgrammingPageContent-Conclusion">Conclusion</h2><p>That's it: with
the above code, simply adding the @ForbidFraming annotation to a page will add
the response header and associated JavaScript; no inheritance hassles. This
basic pattern can be applied to a wide range of cross-cutting concerns, such as
security, transaction management, logging, or virtually any other kind of
situation that would normally be solved with inheritance or ugly boilerplate
code.</p><div class="confluence-information-macro
confluence-information-macro-note"><span class="aui-icon aui-icon-small
aui-iconfont-warning confluence-information-macro-icon"></span><div
class="confluence-information-macro-body"><p>The code in this example was
designed for Tapestry version 5.2 and later.</p></div></div></div>
</div>
<div class="clearer"></div>