<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tapestry 5 Blog &#187; Tapestry</title>
	<atom:link href="http://blog.tapestry5.de/index.php/category/tapestry/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.tapestry5.de</link>
	<description>Thoughts on coding, technology and occasional stuff.</description>
	<lastBuildDate>Wed, 01 Sep 2010 11:06:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Context Values vs. Request Parameters</title>
		<link>http://blog.tapestry5.de/index.php/2010/08/23/context-values-vs-request-parameters/</link>
		<comments>http://blog.tapestry5.de/index.php/2010/08/23/context-values-vs-request-parameters/#comments</comments>
		<pubDate>Mon, 23 Aug 2010 16:14:43 +0000</pubDate>
		<dc:creator>Igor Drobiazko</dc:creator>
				<category><![CDATA[Tapestry]]></category>

		<guid isPermaLink="false">http://blog.tapestry5.de/?p=1799</guid>
		<description><![CDATA[In this post I want to show you some new features introduced in Tapestry 5.2. You&#8217;ll learn how to access request parameters in a easy way. As you probably know Tapestry provides a very nice mechanism to pass some data from one page to another. This mechanism is called page activation context. Before a page [...]]]></description>
			<content:encoded><![CDATA[<p>In this post I want to show you some new features introduced in Tapestry 5.2. You&#8217;ll learn how to access request parameters in a easy way.</p>
<p>As you probably know Tapestry provides a very nice mechanism to pass some data from one page to another. This mechanism is called <em>page activation context</em>. Before a page is rendered Tapestry extracts the context values from the URL, converts the string values to appropriate type and activates the page. Usually a URL to a page looks like the following, whereby 12345 is the <em>page activation context.</em></p>
<p><em>/viewuser/12345/</em></p>
<p>Note that the <em>page activation context</em> is encoded into the request path.</p>
<h2>Mapping Fields to Request Parameters</h2>
<p>Sometimes you might prefer request parameters over page activation context to pass data to a page. An example is a migration of an existing legacy application to Tapestry. It&#8217;s quite common to do this in stages, moving some functionality into Tapestry and leaving other parts, initially, in the other system.  Imagine you want to migrate a single page of your application which is accessed via a URL like:</p>
<p><em>/viewuser?userId=12345</em></p>
<p>You can use the <em>@ActivationRequestParameter</em> annotation to map a field of a page (not a component) to a request parameter. When a page is activated, the mapped fields will receive their values from request parameters before <em>onActivate()</em> event handler method is invoked. The annotation value is used to specify the name of the request parameter, which is mapped to the field. If no such value is provided, then the name of the field is taken as the name of the request parameter. For the following page Tapestry will extract the value from the <em>userId</em> request parameter, transform the string value to a <em>User</em> instance and assign the value to the <em>user</em> property.</p>
<pre class="brush: java;">public class ViewUser {

   @Property
   @ActivationRequestParameter("userId")
   private User user;
}</pre>
<p>The assigned value can be accessed in the page template in a usual way:</p>
<pre class="brush: xml;">&lt;html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd"&gt;
    &lt;body&gt;
        User: ${user.name}
        &lt;br/&gt;
        &lt;t:pagelink page="viewuser"&gt;refresh&lt;/t:pagelink&gt;
    &lt;/body&gt;
&lt;/html&gt;</pre>
<p>The <em>@ActivationRequestParameter</em> annotation may be considered as an alternative to <em>@Persist</em> annotation. This annotation tells Tapestry to persist a field value from one request to the next. The main difference to the <em>@Persist</em> annotation is that the value is not stored into a session, onto the client, etc. The value is rescued as a request parameter. When Tapestry generates a component event or page render link for a page, it will identify all fields annotated with <em>@ActivationRequestParameter</em> and add their values as request parameters to the link. Open the <em>ViewUser</em> page in your browser with a valid user id as request parameter and roll your mouse over the <em>refresh</em> link. You will see in the statusbar of your browser that the user id has been appended to the URL of the link automatically.</p>
<h2>Accessing Request Parameters in Handler Methods</h2>
<p>Alternatively you can use the <em>@RequestParameter</em> annotation to access the request parameters. The main difference is that <em>@RequestParameter</em> annotation may be placed only on method parameters as shown in the following example. The annotation doesn&#8217;t persist the request parameter between two requests.</p>
<pre class="brush: java;">public class ViewUser {
   @Property
   private User user;

   void onActivate(@RequestParameter("userId") User user) {
      this.user = user;
   }
}</pre>
<p>The <em>@RequestParameter</em> annotation may be placed on handler methods of both pages and components. The main use case for the annotations are probably methods handling ajax request.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tapestry5.de/index.php/2010/08/23/context-values-vs-request-parameters/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tapestry 5.2 Preview</title>
		<link>http://blog.tapestry5.de/index.php/2010/08/11/tapestry-5-2-preview/</link>
		<comments>http://blog.tapestry5.de/index.php/2010/08/11/tapestry-5-2-preview/#comments</comments>
		<pubDate>Wed, 11 Aug 2010 15:52:38 +0000</pubDate>
		<dc:creator>Igor Drobiazko</dc:creator>
				<category><![CDATA[Tapestry]]></category>

		<guid isPermaLink="false">http://blog.tapestry5.de/?p=1744</guid>
		<description><![CDATA[Tapestry team is pleased to announce Tapestry 5.2.0 Alpha release. Read the news in Howard&#8217;s announcement and on Tapestry&#8217;s site. We have fixed a lot of bugs and added some cool new stuff. Release notes can be found here. In this post I&#8217;ll give you a preview of some new features. Improvements to Live Class Reloading With [...]]]></description>
			<content:encoded><![CDATA[<p>Tapestry team is pleased to announce Tapestry 5.2.0 Alpha release. Read the news in <a title="Tapestry 5.2 leaves the gate " href="http://tapestryjava.blogspot.com/2010/08/tapestry-52-leaves-gate.html" target="_blank">Howard&#8217;s announcement</a> and on <a title="Tapestry 5.2 announcement" href="http://tapestry.apache.org/news.html#a20100809" target="_blank">Tapestry&#8217;s site</a>. We have fixed a lot of bugs and added some cool new stuff. Release notes can be found <a title="Tapestry 5.2 Release Notes" href="https://issues.apache.org/jira/secure/ReleaseNote.jspa?version=12314122&amp;styleName=Html&amp;projectId=12310833&amp;Create=Create" target="_blank">here</a>. In this post I&#8217;ll give you a preview of some new features.</p>
<h2>Improvements to Live Class Reloading</h2>
<p>With Tapestry you can see the changes to your pages and components immediately. You just change you class, reload the page and see the result. No redeploy, no restart required! In Tapestry 5.2 the Live Class Reloading feature has been enhanced to reload your service implementation classes. That means Tapestry will boost the developer&#8217;s productivity to a higher level than before. Read <a title="Live Class Reloading in Tapestry 5.2" href="http://tapestryjava.blogspot.com/2010/03/live-service-reloading-in-tapestry-52.html" target="_blank">here</a> for more details.</p>
<h2>New Components</h2>
<p>Two components have been added:</p>
<ul>
<li><a title="Error" href="http://tapestry.apache.org/tapestry5.2-dev/tapestry-core/ref/org/apache/tapestry5/corelib/components/Error.html" target="_blank">Error</a>: Same as <a title="Errors" href="http://tapestry.apache.org/tapestry5/tapestry-core/ref/org/apache/tapestry5/corelib/components/Errors.html" target="_blank">Errors</a> but presents validation errors of a single field</li>
<li><a title="Trigger" href="http://tapestry.apache.org/tapestry5.2-dev/tapestry-core/ref/org/apache/tapestry5/corelib/components/Trigger.html" target="_blank">Trigger</a>: Triggers an arbitrary event during rendering. This is often useful to add JavaScript to a page or a component (via calls to the RenderSupport environmental).</li>
</ul>
<h2>New Mixins</h2>
<p>Two mixins have been added:</p>
<ul>
<li><a title="RenderClientId" href="http://tapestry.apache.org/tapestry5.2-dev/tapestry-core/ref/org/apache/tapestry5/corelib/mixins/RenderClientId.html" target="_blank">RenderClientId</a>: Forces a client element to render its client id by ensuring that <a title="ClientElement.getClientId()" href="http://tapestry.apache.org/tapestry5.2-dev/apidocs/org/apache/tapestry5/ClientElement.html#getClientId()" target="_blank">ClientElement.getClientId()</a> is called.</li>
<li><a title="RenderNotification" href="http://tapestry.apache.org/tapestry5.2-dev/tapestry-core/ref/org/apache/tapestry5/corelib/mixins/RenderNotification.html" target="_blank">RenderNotification</a>: This mixin triggers event notifications to identify when it enters the <em>BeginRender</em> and <em>AfterRender</em> render phases. The <a title="MarkupWriter" href="http://tapestry.apache.org/tapestry5.2-dev/apidocs/org/apache/tapestry5/MarkupWriter.html" target="_blank">MarkupWriter</a> is passed as the event context. The most common use of this is to handle the <em>afterRender</em> event to generate client-side JavaScript for content just rendered via a Block (this is a common Ajax use case related to partial page rendering).</li>
</ul>
<h2>JSR-303 Bean Validation Integration</h2>
<p>An integration library for JSR-303 Bean Validation API has been added. Now you can annotate your pages, component and entities with JSR-303 annotations. Tapestry will perform the validation according to the specified validation constraints. Read <a title="Tapestry / JSR 303" href="http://blog.tapestry5.de/index.php/2010/01/04/tapestry-and-jsr-303-bean-validation-api/" target="_blank">here</a> and <a title="Tapestry / JSR 303" href="http://blog.tapestry5.de/index.php/2010/02/26/tapestry-and-jsr-303-bean-validation-api-now-with-client-side-validation/" target="_blank">here</a>.</p>
<h2>New Annotation for Contribute Methods</h2>
<p>The <a title="@Contribute annotation" href="http://tapestry.apache.org/tapestry5.2-dev/apidocs/org/apache/tapestry5/ioc/annotations/Contribute.html" target="_blank">@Contribute</a> annotation has been introduced as an alternative to the naming convention for <em>contribute methods</em>. The annotation allows your <em>contribute methods</em> to be arbitrary named. You don&#8217;t have to follow the naming convention for contribute methods anymore. Just name your contribute method as you like and annotate it with <a title="@Contribute annotation" href="http://tapestry.apache.org/tapestry5.2-dev/apidocs/org/apache/tapestry5/ioc/annotations/Contribute.html" target="_blank">@Contribute</a> (plus some marker annotations).</p>
<h2>New Annotations to Access Request Parameters</h2>
<p>New annotations have been added to make the access of request parameters easier:</p>
<ul>
<li><a title="@RequestParameter annotation" href="http://tapestry.apache.org/tapestry5.2-dev/apidocs/org/apache/tapestry5/annotations/RequestParameter.html" target="_blank">@RequestParameter</a>: may be placed on parameters of event handler methods. Before invoking the handler method Tapestry will extract the parameter values from the request, transform the string values to the type of the method parameter automatically and pass the transformed value to the method.</li>
<li><a title="@ActivationRequestParameter annotation" href="http://tapestry.apache.org/tapestry5.2-dev/apidocs/org/apache/tapestry5/annotations/ActivationRequestParameter.html" target="_blank">@ActivationRequestParameter</a>: may be used to map a field of a page (not a component) to a request parameter. When Tapestry generate component event or page render links for the page, it will identify all fields annotated with <a title="@ActivationRequestParameter annotation" href="http://tapestry.apache.org/tapestry5.2-dev/apidocs/org/apache/tapestry5/annotations/ActivationRequestParameter.html" target="_blank">@ActivationRequestParameter</a> and add their values as request parameters to the link. When a page is activated, the mapped fields will receive their values from request parameters before <em>onActivate</em> event handler method is invoked.</li>
</ul>
<h2>New Page Lifecycle Event</h2>
<p>The <em>pageReset</em> event has been added to the page lifecycle. A page is reset when the page is accessed from another page; component event links and page render links that target the same page do not cause a reset, but linking from one page to another will cause a reset on the destination page when it is rendered. The reset lifecycle event occurs after page activation, allowing the page to reset its internal state to the match its activation context. Note that on pages that have such reset logic will have an additional query parameter added to the page render URL in some cases.</p>
<h2>New Events for Link Decoration</h2>
<p>During generation of component event or page render links Tapestry will fire two events to involve you as page/component author into the link generation process. The new events are:</p>
<ul>
<li><em>decoratePageRenderLink</em>: triggered during page render link generation. The first context parameter is the <a title="Link" href="http://tapestry.apache.org/tapestry5.1/apidocs/org/apache/tapestry5/Link.html" target="_blank">Link</a> object, the second is the <a title="PageRenderRequestParameters" href="http://tapestry.apache.org/tapestry5.1/apidocs/org/apache/tapestry5/services/PageRenderRequestParameters.html" target="_blank">PageRenderRequestParameters</a> from which the Link was created. The event is triggered on the actively rendering page. You can provide an event handler method for that event if you want to modify the link targeting the page.</li>
<li><em>decoreateComponentEventLink</em>: triggered during component event link generation. The first context parameter is the <a title="Link" href="http://tapestry.apache.org/tapestry5.1/apidocs/org/apache/tapestry5/Link.html" target="_blank">Link</a> object, the second is the <a title="ComponentEventRequestParameters" href="http://tapestry.apache.org/tapestry5.1/apidocs/org/apache/tapestry5/services/ComponentEventRequestParameters.html" target="_blank">ComponentEventRequestParameters</a> from which the Link was created. The event is triggered on the actively rendering page, not necessarily the page containing the component. You can provide an event handler method for that event if you want to modify the link triggering a component event.</li>
</ul>
<h2>URL Rewriting API Deprecated</h2>
<p>The URL Rewriting API has been deprecated in favour of <a title="LinkTransformer" href="http://tapestry.apache.org/tapestry5.2-dev/apidocs/org/apache/tapestry5/services/linktransform/LinkTransformer.html" target="_blank">LinkTransformer</a> service. That service is a facade around <a title="ComponentEventLinkTransformer" href="http://tapestry.apache.org/tapestry5.2-dev/apidocs/org/apache/tapestry5/services/linktransform/ComponentEventLinkTransformer.html" target="_blank">ComponentEventLinkTransformer</a> and <a title="PageRenderLinkTransformer" href="http://tapestry.apache.org/tapestry5.2-dev/apidocs/org/apache/tapestry5/services/linktransform/PageRenderLinkTransformer.html" target="_blank">PageRenderLinkTransformer</a> services. You can contribute implementations of these services to transform component event and page render requests.</p>
<h2>Template Parser Changed</h2>
<p>In the past Tapestry used StAX XML parser for parsing templates. This caused some incompatibilities with Google App Engine and in OSGi environments. Now Tapestry uses a standard SAX parser.</p>
<h2>Page Pool Deprecated</h2>
<p>The page pool has been deprecated. Now Tapestry maintains for every page only one instance which is shared between threads. The values of the mutable fields are stored in a per-thread Map of keys and values so that a single page instance can be used across multiple threads without any synchronization issues. As of 5.2 the page pool is switched off but you can configure Tapestry to use it. Read <a title="Everyone out of the Pool! Tapestry goes singleton!" href="http://tapestryjava.blogspot.com/2010/07/everyone-out-of-pool-tapestry-goes.html" target="_blank">here</a> for more details.</p>
<h2>JMX Support and Remote Management of the Pool Settings</h2>
<p>If you configure Tapestry to use the page pool, you can change the settings of the pool remotely. Tapestry provides now a JMX support library which can be used to expose objects as MBeans. This library is used to register an MBean for managing pool settings. Read <a title="Remote Pool Management" href="http://blog.tapestry5.de/index.php/2010/05/28/remote-page-pool-management/" target="_blank">here</a> for more details.</p>
<h2>Upgrade to Spring 3</h2>
<p>Tapestry&#8217;s Spring integration library depends now on Spring 3.</p>
<h2>Upgrade to Hibernate 3.5.4</h2>
<p>Tapestry&#8217;s Hibernate integration library depends now on Hibernate 3.5.4.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tapestry5.de/index.php/2010/08/11/tapestry-5-2-preview/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Extending Template Lookup Mechanism</title>
		<link>http://blog.tapestry5.de/index.php/2010/08/06/extending-template-lookup-mechanism/</link>
		<comments>http://blog.tapestry5.de/index.php/2010/08/06/extending-template-lookup-mechanism/#comments</comments>
		<pubDate>Fri, 06 Aug 2010 16:18:24 +0000</pubDate>
		<dc:creator>Igor Drobiazko</dc:creator>
				<category><![CDATA[Tapestry]]></category>

		<guid isPermaLink="false">http://blog.tapestry5.de/?p=1667</guid>
		<description><![CDATA[As you probably know Tapestry&#8217;s localization support provides localized component templates. A page or a component may have several locale-specific templates. When rendering a component Tapestry will search for a localized version of each component template and use the closest match. For example you could have MyPage_fr.tml for French users, MyPage_de.tml for German users and MyPage.tml [...]]]></description>
			<content:encoded><![CDATA[<p>As you probably know Tapestry&#8217;s localization support provides localized component templates. A page or a component may have several locale-specific templates. When rendering a component Tapestry will search for a localized version of each component template and use the closest match. For example you could have <em>MyPage_fr.tml</em> for French users, <em>MyPage_de.tml</em> for German users and <em>MyPage.tml</em> for all other users.</p>
<p>In my Tapestry workshops I&#8217;m often asked how to extend the template lookup mechanism. Some Tapestry based applications have a use case to provide different flavors of a single page template. Imagine you want your app do be used on mobile phones. In this case you need to provide an alternative rendering for your pages. It is almost impossible to  create a template which looks good on standard web browser and mobile devices. Thus you need to provide different templates for a single page.</p>
<h2>Extending Template Lookup Mechanism</h2>
<p>This is the point at which Tapestry&#8217;s extensibility comes into play. As you know you can easily override almost every part of Tapestry by replacing a particular service. Now let me show you how to extend Tapestry&#8217;s template lookup mechanism in Tapestry 5.2. The discussed mechanism was also available in prior versions but it was a part of the internal API. You can use the  internal API only at your own risk because we can change in the future releases. In 5.2 this mechanism became a public API. Now it is safe to extend it without to fear any upgrade problems. Let&#8217;s see it.</p>
<p>The key part of Tapestry&#8217;s template lookup mechanism is the <em>ComponentTemplateLocator</em> service which is used to locate both page and component templates. The service implementation is a chain-of-command and can be configured by <em>ComponentTemplateLocator</em> instances. Tapestry contributes two implementations of <em>ComponentTemplateLocator</em> to the chain:</p>
<ul>
<li><em>Default</em>: Searches for a template on the classpath</li>
<li><em>Page</em>: Searches for page templates in the application context (root folder of your WAR file)</li>
</ul>
<p> Now let&#8217;s contribute a command which will locate a page template based on a classifier. Such a classifier can be a string identifying the flavor of the template to render the page. For example if you want to render the page <em>MyPage</em> on iPhone you may provide a classifier like <em>iphone</em> to retrieve the template <em>MyPage_iphone.tml</em>. If the client is on the Palm phone, the classifier <em>palm</em> can be used to retrieve the template <em>MyPage_palm.tml</em>. If the classifier is not available, the default template <em>MyPage.tml</em> will be rendered.</p>
<p>Let&#8217;s create a per-thread service named <em>TemplateClassifierSource</em>, which is responsible for identifying the client and providing a corresponding classifier. The implementation details are not interesting.</p>
<pre class="brush: java;">public interface TemplateClassifierSource {
    String getClassifier();
}</pre>
<p>Our implementation of <em>ComponentTemplateLocator</em> will use the <em>TemplateClassifierSource</em> service to identify the proper template for the page. In the following example we first retrieve the page class name and resolve the page name from it. Then we calculate the name of the template resource and load the resource from context root. We also try to find a localized version of the template. Thus we can provide templates like <em>MyPage_iphone_de.tml</em>. If no template was found we return <em>null</em>. In this case the next command in the <em>ComponentTemplateLocator</em> chain will try to locate the template.</p>
<pre class="brush: java;">public class ClassifierPageTemplateLocator
            implements ComponentTemplateLocator {
   @Inject
   @ContextProvider
   private AssetFactory contextAssetFactory;

   @Inject
   private ComponentClassResolver resolver;

   @Inject
   private TemplateClassifierSource classifierSource;

   public Resource locateTemplate(ComponentModel model,
                                  Locale locale) {
      String className = model.getComponentClassName();

      if (!className.contains(".pages.")) {
         return null;
      }

      String logicalName = this.resolver
            .resolvePageClassNameToPageName(className);

      String path = String.format("%s_%s.%s",
            logicalName,
            this.classifierSource.getClassifier(),
            TapestryConstants.TEMPLATE_EXTENSION);

      Resource contextRoot =
            this.contextAssetFactory.getRootResource();

      Resource resource = contextRoot.forFile(path);

      if (resource != null) {
         return resource.forLocale(locale);
      }

      return null;
   }
}</pre>
<h2>Contributing ComponentTemplateLocator</h2>
<p>Next we contribute our <em>ComponentTemplateLocator</em> before the locator with id <em>Page</em>.</p>
<pre class="brush: java;">public class AppModule {

   public static void bind(ServiceBinder binder) {
      binder.bind(TemplateClassifierSource.class,
                  TemplateClassifierSourceImpl.class);
   }

   public static void contributeComponentTemplateLocator(
      OrderedConfiguration&lt;ComponentTemplateLocator&gt; config) {

      config.addInstance("Classifier",
                         ClassifierPageTemplateLocator.class,
                         "before:Page");
   }
}</pre>
<h2>Comparing To JSF Renderers</h2>
<p>If you are familiar with JavaServer Faces technology, you will recognize that the described mechanism is comparable to JSF Component Renderers. Both Tapestry and JSF allow you to render a component in different ways. The big difference is the fact that JSF Renderers don&#8217;t have templates. You code the rendering of the component inside your Java classes. Isn&#8217;t it the reason why we don&#8217;t use Servlets anymore? However, in Tapestry you define the look and feel of a component in a template. Another disadvantage of JSF Renderers is that they are limited to components. There is no way in JSF to achieve the same for a Facelet page.</p>
<h2>Summary</h2>
<p>In this article you learned how to extend Tapestry&#8217;s template lookup mechanism. Note that we covered only the lookup of page templates from application context root. You can enhance the mechanism to locate component templates on the classpath.</p>
<p>The described mechanism is very flexible. Instead of coding a classifier into the template name, one could store the specific templates into a subfolder and use the classifier as folder name.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tapestry5.de/index.php/2010/08/06/extending-template-lookup-mechanism/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>More Tapestry Talks in September</title>
		<link>http://blog.tapestry5.de/index.php/2010/08/04/more-tapestry-talks-in-september/</link>
		<comments>http://blog.tapestry5.de/index.php/2010/08/04/more-tapestry-talks-in-september/#comments</comments>
		<pubDate>Tue, 03 Aug 2010 20:58:43 +0000</pubDate>
		<dc:creator>Igor Drobiazko</dc:creator>
				<category><![CDATA[Tapestry]]></category>

		<guid isPermaLink="false">http://blog.tapestry5.de/?p=1659</guid>
		<description><![CDATA[It looks like September is going to be a successful Tapestry month. First of all because we are planing to release Tapestry 5.2 in September. Besides that I&#8217;ll be speaking on Tapestry three times. As already blogged I&#8217;ll be giving a Tapestry talk at Herbstcampus on September 14th. In addition I&#8217;ll be speaking on Tapestry [...]]]></description>
			<content:encoded><![CDATA[<p>It looks like September is going to be a successful Tapestry month. First of all because we are planing to release Tapestry 5.2 in September. Besides that I&#8217;ll be speaking on Tapestry three times. As already blogged I&#8217;ll be giving a <a title="Herbstcampus" href="http://blog.tapestry5.de/index.php/2010/07/26/tapestry-talk-at-herbstcampus/" target="_blank">Tapestry talk at Herbstcampus</a> on September 14th. In addition I&#8217;ll be speaking on Tapestry at <a title="WebAppDays" href="http://webappdays.de/" target="_blank">WebAppDays</a>, a conference on web development. The conference takes place in Düsseldorf, Germany between 27th and 28th September. The program looks very promising. There will be talks on Dojo, Spring Roo, Grails, GlassFish,  CouchDB and many more. Check out the preliminary program <a title="WebAppDays Program" href="http://webappdays.de/sprecher" target="_blank">here</a>.</p>
<p>At WebAppDays I&#8217;ll be giving two talks on Tapestry. The first one will be an introduction to Tapestry, the second one will be a talk similar to <a title="JSF 2.0 vs. Tapestry 5" href="http://blog.tapestry5.de/index.php/2010/03/30/jazoon-2010-talk-javaserver-faces-2-0-vs-tapestry-5/">JavaServer Faces 2.0 vs. Tapestry 5</a> talk I was giving at Jazoon 2010. This time the comparison will be more fun because the JSF part of the talk will be presented by Andy Bosch, a JSF guru in Germany.</p>
<p>I&#8217;m looking forward to visit WebAppDays.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tapestry5.de/index.php/2010/08/04/more-tapestry-talks-in-september/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Reading Annotations of Service Implementation Classes</title>
		<link>http://blog.tapestry5.de/index.php/2010/07/28/reading-annotations-of-service-implementation-classes/</link>
		<comments>http://blog.tapestry5.de/index.php/2010/07/28/reading-annotations-of-service-implementation-classes/#comments</comments>
		<pubDate>Wed, 28 Jul 2010 17:45:51 +0000</pubDate>
		<dc:creator>Igor Drobiazko</dc:creator>
				<category><![CDATA[Tapestry]]></category>

		<guid isPermaLink="false">http://blog.tapestry5.de/?p=1641</guid>
		<description><![CDATA[Today I committed some changes for Tapestry 5.2 that allow you to access annotations placed on service implementation classes. As you probably know Tapestry creates proxies for services. The proxy implements the service interface and delegates method invocations to the actual service instance. When you inject a service into your page, component or another service [...]]]></description>
			<content:encoded><![CDATA[<p>Today I committed some changes for Tapestry 5.2 that allow you to access annotations placed on service implementation classes. As you probably know Tapestry creates proxies for services. The proxy implements the service interface and delegates method invocations to the actual service instance. When you inject a service into your page, component or another service you get a proxy which creates an instance of the service implementation class on demand. The first time a method is invoked on the proxy, the actual service is instantiated and initialized.</p>
<p>Until today Tapestry&#8217;s proxies did not expose annotations of service implementation classes. If you have placed annotations on a service implementation class you was not able to read them reflectively. The reason was the way how proxy classes were fabricated. Tapestry just skipped copying annotations from implementation class to proxy. This caused some problems when integrating third party libraries into Tapestry applications. For example imagine you want to expose your service as a web service and place the <a title="@WebService" href="http://download-llnw.oracle.com/javaee/5/api/javax/jws/WebService.html" target="_blank">@WebService</a> on the service implementation class. Because the annotation was not copied to the service proxy class, your service was not identified as web service.</p>
<pre class="brush: java;">import javax.jws.WebService;
import javax.jws.WebMethod;

@WebService
public class CalculatorImpl implements Calculator {  

   @WebMethod
   public int add( int x, int y )  {
      return x + y;
   }
}</pre>
<p>As of version 5.2 the annotations from service implementation class will be placed on the proxy class if this implementation is bound to its interface inside a <em>bind</em> method.</p>
<pre class="brush: java;">public class AppModule {  

   public static void bind(ServiceBinder binder)  {
      binder.bind(Calculator.class, CalculatorImpl.class);
   }
}</pre>
<p>In case of <em>build</em> methods annotations are still lost. For build methods there is no way to determine the implementation class at proxy creation time. A proxy invokes the <em>build</em> method to instantiate the actual service on demand. At this time you know the implementation class but it&#8217;s just too late. The proxy class already have been fabricated.</p>
<pre class="brush: java;">public class AppModule {  

   public static Calculator buildCalculator()  {
      return new CalculatorImpl();
   }
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.tapestry5.de/index.php/2010/07/28/reading-annotations-of-service-implementation-classes/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Tapestry Talk at Herbstcampus</title>
		<link>http://blog.tapestry5.de/index.php/2010/07/26/tapestry-talk-at-herbstcampus/</link>
		<comments>http://blog.tapestry5.de/index.php/2010/07/26/tapestry-talk-at-herbstcampus/#comments</comments>
		<pubDate>Mon, 26 Jul 2010 18:13:34 +0000</pubDate>
		<dc:creator>Igor Drobiazko</dc:creator>
				<category><![CDATA[Tapestry]]></category>

		<guid isPermaLink="false">http://blog.tapestry5.de/?p=1609</guid>
		<description><![CDATA[I was invited to present Tapestry 5 at Herbstcampus in Nürnberg, Germany. Herbstcampus is a conference for software developers, architects, and project managers with a technology focus in .NET and Java. My talk Fliegede Teppiche &#8211; Moderne Webanwendungen mit Tapestry 5 (Flying carpets &#8211; Modern web applications with Tapestry 5) takes place on September 14th, [...]]]></description>
			<content:encoded><![CDATA[<p>I was invited to present Tapestry 5 at <a title="Herbstcampus" href="http://www.herbstcampus.com" target="_blank">Herbstcampus</a> in Nürnberg, Germany. Herbstcampus is a conference for software developers, architects, and project managers with a technology focus in .NET and Java. My talk <a title="Talk" href="http://www.herbstcampus.com/hc10/program/sessions.html#74" target="_blank">Fliegede Teppiche &#8211; Moderne Webanwendungen mit Tapestry 5 </a> (Flying carpets &#8211; Modern web applications with Tapestry 5) takes place on September 14th, 2010. If you are living in Bavaria, this is a chance to learn Tapestry in a 70 minutes session. I’ll give an overview over Tapestry concepts and new features in the upcoming release 5.2. As always I will show a lot of demos.<a href="http://blog.tapestry5.de/wp-content/uploads/2010/07/herbstcampus.gif"><br />
</a><br />
<a title="Herbstcampus" href="http://www.herbstcampus.com" target="_blank"><img class="aligncenter size-medium wp-image-1624" title="Herbstcampus" src="http://blog.tapestry5.de/wp-content/uploads/2010/07/herbstcampus-299x41.gif" alt="" width="299" height="41" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tapestry5.de/index.php/2010/07/26/tapestry-talk-at-herbstcampus/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Advanced Service Builders in Tapestry IoC: Chain of Responsibility Pattern</title>
		<link>http://blog.tapestry5.de/index.php/2010/07/20/advanced-service-builders-in-tapestry-ioc-chain-of-responsibility-pattern/</link>
		<comments>http://blog.tapestry5.de/index.php/2010/07/20/advanced-service-builders-in-tapestry-ioc-chain-of-responsibility-pattern/#comments</comments>
		<pubDate>Tue, 20 Jul 2010 19:45:55 +0000</pubDate>
		<dc:creator>Igor Drobiazko</dc:creator>
				<category><![CDATA[Tapestry]]></category>

		<guid isPermaLink="false">http://blog.tapestry5.de/?p=1460</guid>
		<description><![CDATA[In the article Advanced Service Builders in Tapestry IoC: Strategy Pattern I described how to implement the Strategy pattern with Tapestry. In this post I&#8217;ll cover the Gang of Four Chain of Responsibility Pattern. I&#8217;ll start with a simple example that demonstrates how to implement the pattern in Tapestry. At the end of the article, [...]]]></description>
			<content:encoded><![CDATA[<p>In the article <a title="Strategy Pattern" href="http://blog.tapestry5.de/index.php/2010/05/20/advanced-service-builders-in-tapestry-ioc-strategy-pattern/" target="_blank">Advanced Service Builders in Tapestry IoC: Strategy Pattern</a> I described how to implement the Strategy pattern with Tapestry. In this post I&#8217;ll cover the<em> Gang of Four Chain of Responsibility Pattern</em>. I&#8217;ll start with a simple example that demonstrates how to implement the pattern in Tapestry. At the end of the article, I&#8217;ll show you how the <em>Chain of Responsibility Pattern</em> is used inside Tapestry.</p>
<h2>The use case</h2>
<p>Suppose you need to support several authentication mechanisms in your application. Let&#8217;s say you need to support authentication based on both HTTP Basic authentication header (<a title="RFC 1945" href="http://www.ietf.org/rfc/rfc1945.txt" target="_blank">RFC 1945</a>) and HTTP Digest authentication header (<a title="RFC 2617" href="http://www.ietf.org/rfc/rfc2617.txt" target="_blank">RFC 2617</a>). Probably you would specify a service interface like <em>AuthenticationService</em>:</p>
<pre class="brush: java;">public interface AuthenticationService {
   boolean isAuthenticated();
}</pre>
<p>You would also provide two implementations of the service. The implementation details are not interesting yet.</p>
<ul>
<li><em>HttpBasicAuthenticationService</em>: authentication based on HTTP Basic authentication header</li>
</ul>
<ul>
<li><em>HttpDigestAuthenticationService</em>: authentication based on HTTP Digest authentication header</li>
</ul>
<p>Both implementations can be bound to their interface in the application module. Note that you need to provide the service id to disambiguate both implementations of the <em>AuthenticationService</em> interface.</p>
<pre class="brush: java;">public class AppModule {

   public static void bind(ServiceBinder binder) {

      binder.bind(AuthenticationService.class,
                  HttpBasicAuthenticationService.class)
            .withId("HttpBasic");</pre>
<pre class="brush: java;">      binder.bind(AuthenticationService.class,
                  HttpDigestAuthenticationService.class)
            .withId("HttpDigest");
   }
}</pre>
<h2>Naive Approach</h2>
<p>Now let&#8217;s first have a look at a naive usage of the <em>AuthenticationService</em> service. Let&#8217;s implement a simple <a title="Dispatcher" href="http://tapestry.apache.org/tapestry5.1/apidocs/org/apache/tapestry5/services/ComponentRequestFilter.html" target="_blank">ComponentRequestFilter</a> which is responsible for recognizing whether an incoming request is authenticated or not.  In the following example we need to inject both implementations of <em>AuthenticationService</em> service using the <a title="@InjectService annotation" href="http://tapestry.apache.org/tapestry5.1/apidocs/org/apache/tapestry5/ioc/annotations/InjectService.html" target="_blank">@InjectService</a> annotation. The value of the annotation is used to identify the service to be injected. When a component event request is handled or a page is rendered we check if the request is authenticated by invoking both services <em>HttpBasic</em> and <em>HttpDigest</em> one after another. If the request is unauthenticated, the filter will set the <em>WWW-Authenticate</em> header and send a 401 HTTP error indicating the request requires HTTP authentication.</p>
<pre class="brush: java;">public class AuthenticationFilter implements ComponentRequestFilter {

   @InjectService("HttpBasic")
   private AuthenticationService basicAuthService;

   @InjectService("HttpDigest")
   private AuthenticationService digestAuthService;

   @Inject
   private Response response;

   public void handleComponentEvent(
         ComponentEventRequestParameters parameters,
         ComponentRequestHandler handler) throws IOException {

      if (isAuthenticated()) {
         handler.handleComponentEvent(parameters);
      }
   }

   public void handlePageRender(
         PageRenderRequestParameters parameters,
         ComponentRequestHandler handler) throws IOException {

      if (isAuthenticated()) {
         handler.handlePageRender(parameters);
      }

   }

   private boolean isAuthenticated() throws IOException {

      if (this.basicAuthService.isAuthenticated()) {
         return true;
      }

      if (this.digestAuthService.isAuthenticated()) {
         return true;
      }

      this.response.setHeader("WWW-Authenticate",
            "Basic realm=\"Tapestry\"");

      this.response.sendError(HttpServletResponse.SC_UNAUTHORIZED,
            "Request unauthorized");

      return false;
   }
}</pre>
<p>Injecting both services <em>HttpBasic</em> and <em>HttpDigest</em> and invoking them one after another is not really nice. If you decide to provide a further authentication mechanism in the future, you&#8217;ll have to change the <em>AuthenticationFilter</em> class. Imagine you decided to support the authentication based on a <em>Remember-Me-Token</em>. In this case you need to provide a new implementation of <em>AuthenticationService</em> interface which will be injected into <em>AuthenticationFilter</em> using the service id. Now you have three different instances of <em>AuthenticationService</em> that are invoked one after another.</p>
<h2>Chain of Responsibility</h2>
<p>Now let me show you how to improve our example. We&#8217;ll implement the <em>AuthenticationService</em> as a <em>Chain of Responsibility</em>. Instead of providing different implementations of <em>AuthenticationService</em> interface with dfferent service ids, we use the <a title="ChainBuilder" href="http://tapestry.apache.org/tapestry5.1/apidocs/org/apache/tapestry5/ioc/services/ChainBuilder.html" target="_blank">ChainBuilder</a> service to build a chain of <em>AuthenticationService</em> inside a <em>build method</em>.</p>
<p>The <a title="ChainBuilder" href="http://tapestry.apache.org/tapestry5.1/apidocs/org/apache/tapestry5/ioc/services/ChainBuilder.html" target="_blank">ChainBuilder</a> service is used to assemble a <em>Chain Of Command</em> implementation of an interface (the <em>command interface</em>) from an ordered list of objects implementing that interface (the <em>commands</em>). The commands of the chain are contributed to the service configuration.</p>
<pre class="brush: java;">public class AppModule {

   public static void contributeAuthenticationService(
       OrderedConfiguration&lt;AuthenticationService&gt; config) {

      config.addInstance("HttpBasic",
              HttpBasicAuthenticationService.class);</pre>
<pre class="brush: java;">      config.addInstance("HttpDigest",
              HttpDigestAuthenticationService.class);
   }

   public static AuthenticationService buildAuthenticationService(
         List&lt;AuthenticationService&gt; configuration,
         ChainBuilder chainBuilder) {

      return chainBuilder.build(AuthenticationService.class,
                                configuration);
   }
}</pre>
<p>The result is that there is a single instance of <em>AuthenticationService</em> service inside the <a title="Registry" href="http://tapestry.apache.org/tapestry5.1/apidocs/org/apache/tapestry5/ioc/Registry.html" target="_blank">Registry</a>. You don&#8217;t need to disambiguate different instances of the service by providing unique ids and don&#8217;t have to care which instance to inject. You just inject the <em>AuthenticationService</em> service and use it. Note that we are not using the <a title="@InjectService annotation" href="http://tapestry.apache.org/tapestry5.1/apidocs/org/apache/tapestry5/ioc/annotations/InjectService.html" target="_blank">@InjectService</a> annotation anymore. Now it is fine to use the <a title="@Inject annotation" href="http://tapestry.apache.org/tapestry5.1/apidocs/org/apache/tapestry5/ioc/annotations/Inject.html" target="_blank">@Inject</a> annotation. Tapestry will call the <em>Chain of Command</em> behind the scenes for you. Now <em>AuthenticationFilter</em> can be simplified.</p>
<pre class="brush: java;">public class AuthenticationFilter implements ComponentRequestFilter {

   @Inject
   private AuthenticationService authenticationService;

   @Inject
   private Response response;

   public void handleComponentEvent(
         ComponentEventRequestParameters parameters,
         ComponentRequestHandler handler) throws IOException {

      if (isAuthenticated()) {
         handler.handleComponentEvent(parameters);
      }
   }

   public void handlePageRender(
         PageRenderRequestParameters parameters,
         ComponentRequestHandler handler) throws IOException {

      if (isAuthenticated()) {
         handler.handlePageRender(parameters);
      }

   }

   private boolean isAuthenticated() throws IOException {

      if (this.authenticationService.isAuthenticated()) {
         return true;
      }

      this.response.setHeader("WWW-Authenticate",
            "Basic realm=\"Tapestry\"");

      this.response.sendError(HttpServletResponse.SC_UNAUTHORIZED,
            "Request unauthorized");

      return false;
   }
}</pre>
<p>Now that you know how to create a <em>Chain of Command</em> with Tapestry, let me explain you how Tapestry works down the list of commands.</p>
<h2>ChainBuilder Service</h2>
<p>As you already learned, the <a title="ChainBuilder" href="http://tapestry.apache.org/tapestry5.1/apidocs/org/apache/tapestry5/ioc/services/ChainBuilder.html" target="_blank">ChainBuilder</a> service creates a <em>Chain Of Command</em> based on a <em>command interface </em>and <em>commands</em>. Behind the scenes Tapestry generates an implementation of the <em>command interface </em>at runtime. For each method in the interface, the chain implementation will call the corresponding method on each <em>command</em> object in turn.  There are several situations when a chain is terminated:</p>
<ul>
<li>If the return type of the interface method is <em>boolean</em> and a command in the chain returned <em>true</em>.</li>
<li>If the return type of the interface method is numeric and a command in the chain returned a non-zero value.</li>
<li>If the return type of the interface method is other than <em>boolean</em> or numeric and a command in the chain returned a non-null value.</li>
<li>If a command in the chain throws an Exception.</li>
</ul>
<p>Note that in case of <em>void</em> methods only throwing an Exception can terminate the chain.</p>
<p>Now let me explain how chains can be terminated. In the following example you can see <em>HttpBasicAuthenticationService</em> service. It first checks if the <em>Authorization</em> header is set. If the header is not available, then <em>false</em> is returned. In this case the next command in the chain is invoked. If the header is present the command executions continues. If the credentials are available and valid, then <em>true</em> is returned. This terminsates the chain.</p>
<pre class="brush: java;">public class HttpBasicAuthenticationService implements AuthenticationService {
   @Inject
   private Request request;

   public boolean isAuthenticated() {
      String header = this.request.getHeader("Authorization");

      if (header == null || !header.startsWith("Basic ")) {
         return false;
      }

      String[] tokens = getCredentials(header);

      if (tokens.length != 2) {
         return false;
      }

      return tokens[0].equals("igor")
                  &amp;&amp; tokens[1].equals("secret");

   }

   public String[] getCredentials(String header) {
      ...
   }
}</pre>
<h2>Real Life Example</h2>
<p>Now that you know how to implement the <em>Chain Of Command Pattern</em> let me show you how this pattern is used inside Tapestry. As you know Tapestry performs the transformation of the page and component classes at runtime. This bytecode transformation is performed by the <a title="ComponentClassTransformWorker" href="http://tapestry.apache.org/tapestry5/apidocs/org/apache/tapestry5/services/ComponentClassTransformWorker.html" target="_blank">ComponentClassTransformWorker</a> service which is implemented as a <em>Chain of Command</em>. The commands of the chain transform a component or page class in turn. For example there is an internal implementation of the  <a title="ComponentClassTransformWorker" href="http://tapestry.apache.org/tapestry5/apidocs/org/apache/tapestry5/services/ComponentClassTransformWorker.html" target="_blank">ComponentClassTransformWorker</a> interface which is responsible for transforming a component or a page class in that way that you as page author can inject services into that component or page via <a title="@Inject annotation" href="http://tapestry.apache.org/tapestry5.1/apidocs/org/apache/tapestry5/ioc/annotations/Inject.html" target="_blank">@Inject</a> annotation. Another command in the chain is responsible for identifying parameters via the <a title="@Parameter annotation" href="http://tapestry.apache.org/tapestry5/apidocs/org/apache/tapestry5/annotations/Parameter.html" target="_blank">@Parameter</a> annotation on component fields. Almost for every annotation, used in a component or a page, there is a specialized command which is a part of the class transformation chain.</p>
<p>Here is see an extract from <a title="TapestryModule" href="http://tapestry.apache.org/tapestry5/apidocs/org/apache/tapestry5/services/TapestryModule.html" target="_blank">TapestryModule</a>:</p>
<pre class="brush: java;">public class TapestryModule {

    public void contributeComponentClassTransformWorker(
        OrderedConfiguration&lt;ComponentClassTransformWorker&gt;
                     configuration){

        configuration.addInstance("Inject",
                                  InjectWorker.class);
        configuration.addInstance("InjectService",
                                  InjectServiceWorker.class);
        configuration.addInstance("InjectPage",
                                  InjectPageWorker.class);

        ...

        configuration.add("OnEvent", new OnEventWorker());

        ...
        configuration.addInstance("Parameter",
                                  ParameterWorker.class,
                                  "after:Inject*");
   }

   public ComponentClassTransformWorker buildComponentClassTransformWorker(
         List&lt;ComponentClassTransformWorker&gt; configuration,
         ChainBuilder chainBuilder) {

      return chainBuilder.build(
                           ComponentClassTransformWorker.class,
                           configuration);
   }
}</pre>
<h2>Summary</h2>
<p>In this post I described how to implement <em>Chain of Responsibility Pattern</em> using Tapestry IoC. Based on the authentication example you learned how to decouple a sender of a request and its receiver by giving more than one service a chance to handle the request.</p>
<p>In the next post of this series I&#8217;ll cover further advance techniques for building services. You&#8217;ll learn how to use <em>Shadow services</em>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tapestry5.de/index.php/2010/07/20/advanced-service-builders-in-tapestry-ioc-chain-of-responsibility-pattern/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Registry Startup</title>
		<link>http://blog.tapestry5.de/index.php/2010/06/16/registry-startup/</link>
		<comments>http://blog.tapestry5.de/index.php/2010/06/16/registry-startup/#comments</comments>
		<pubDate>Wed, 16 Jun 2010 05:49:42 +0000</pubDate>
		<dc:creator>Igor Drobiazko</dc:creator>
				<category><![CDATA[Tapestry]]></category>

		<guid isPermaLink="false">http://blog.tapestry5.de/?p=1403</guid>
		<description><![CDATA[In web applications it&#8217;s often necessary to execute extra logic at application startup. When your application is starting, you might want to schedule a task for one-time or repeated execution. A typical use case is the initialization of the database. Imagine you deliver a demo version of your application to a customer in order to [...]]]></description>
			<content:encoded><![CDATA[<p>In web applications it&#8217;s often necessary to execute extra logic at application startup. When your application is starting, you might want to schedule a task for one-time or repeated execution. A typical use case is the initialization of the database. Imagine you deliver a demo version of your application to a customer in order to convince him that you did a better job than your competitors. When the customer drops the WAR file into the servlet container, the application should be usable immediately. In this case you might want to create some demo data (e.g. demo accounts with default credentials) at start time.</p>
<p>In Tapestry you can execute some logic at <a title="Registry" href="http://tapestry.apache.org/tapestry5.1/apidocs/org/apache/tapestry5/ioc/Registry.html" target="_blank">Registry</a> startup by making contributions to the <em>RegistryStartup</em> service configuration. The values contributed are <a title="Runnable" href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Runnable.html" target="_blank">Runnable</a> objects. Here is an example:</p>
<pre class="brush: java;">public class AppModule {

  public static void contributeRegistryStartup(
         OrderedConfiguration&lt;Runnable&gt; configuration,
         DatabaseStartup dbStartup) {

      configuration.add("DbStartup", new Runnable() {
          dbStartup.init();
      }, "before:*");
  }
}</pre>
<h2>Startup Methods in Tapestry 5.2</h2>
<p>In Tapestry 5.2 the way of providing extra logic to be executed at <a title="Registry" href="http://tapestry.apache.org/tapestry5.1/apidocs/org/apache/tapestry5/ioc/Registry.html" target="_blank">Registry</a> startup has been simplified. Instead of making contributions to the <em>RegistryStartup</em> service configuration you can provide startup methods inside your modules. As you can see in the following example you just annotate an arbitrary module method with @Startup annotation and that&#8217;s it. Tapestry will detect these methods and invoke them after the registry has been started.</p>
<pre class="brush: java;">public class AppModule {

  @Startup
  public static void initApplication(DatabaseStartup dbStartup) {
      dbStartup.init();
  }
}</pre>
<p>Note that <em>RegistryStartup</em> service configuration is ordered. Providing the order constraint it&#8217;s possible to control in what order the contributions are executed. In contrast the order of startup methods is determined by the alphabetical order of the method names. You should not rely on that. The alphabetical ordering of module methods is a part of the internal API and may be changed in the upcoming releases.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tapestry5.de/index.php/2010/06/16/registry-startup/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Manning Publications translates my Tapestry 5 book</title>
		<link>http://blog.tapestry5.de/index.php/2010/06/11/manning-publications-translates-my-tapestry-5-book/</link>
		<comments>http://blog.tapestry5.de/index.php/2010/06/11/manning-publications-translates-my-tapestry-5-book/#comments</comments>
		<pubDate>Thu, 10 Jun 2010 22:55:49 +0000</pubDate>
		<dc:creator>Igor Drobiazko</dc:creator>
				<category><![CDATA[Tapestry]]></category>

		<guid isPermaLink="false">http://blog.tapestry5.de/?p=1375</guid>
		<description><![CDATA[I&#8217;m pleased to announce the amazing news. Manning Publications Co. will translate my Tapestry 5 book into English. Tapestry folks have been waiting for a book on Tapestry 5 for a long time and I&#8217;m excited to finally move forward with this book. We have a great team. Joachim Van der Auwera will translate the [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m pleased to announce the amazing news. <a title="Manning" href="http://www.manning.com/" target="_blank">Manning Publications Co.</a> will translate my <a title="Tapestry 5 Boook" href="http://www.amazon.de/gp/product/3827328446/ref=s9_simh_gw_p14_i1?pf_rd_m=A3JWKAKR8XB7XF&amp;pf_rd_s=center-1&amp;pf_rd_r=0K9HQ9YY1NAX93E735RG&amp;pf_rd_t=101&amp;pf_rd_p=463375193&amp;pf_rd_i=301128" target="_blank">Tapestry 5 book</a> into English. Tapestry folks have been waiting for a book on Tapestry 5 for a long time and I&#8217;m excited to finally move forward with this book.</p>
<p>We have a great team.<a title="Joachim Van der Auwera" href="http://www.progs.be/cv.html" target="_blank"> Joachim Van der Auwera</a> will translate the German copy into English. I&#8217;ll update the translated book with the Tapestry 5.2 contents. There is a lot of innovative stuff in the 5.2 trunk the world should know about. I&#8217;m also going to extend some chapters which were covered in the German version not in the depth. Maybe some of the articles from this blog will be available in the book. The German version has around 430 pages. The Manning book on Tapestry will get additional 50 &#8211; 70 pages. Finally <a title="Howard Lewis Ship" href="http://www.howardlewisship.com/" target="_blank">Howard Lewis Ship</a> is interested in joining the project as technical editor. If Howard will be available he will review whether the book covers his vision of Tapestry.</p>
<p>I would like to thank Angelika Ritthaler from<a title="Addison Wesley" href="http://addison-wesley.de/" target="_blank"> Addison Wesley</a> and Christina Rudloff from <a title="Manning" href="http://www.manning.com/" target="_blank">Manning Publications  Co.</a> for making this book real.</p>
<p>Stay tuned!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tapestry5.de/index.php/2010/06/11/manning-publications-translates-my-tapestry-5-book/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>First Impressions From Jazoon</title>
		<link>http://blog.tapestry5.de/index.php/2010/06/04/first-impressions-from-jazoon/</link>
		<comments>http://blog.tapestry5.de/index.php/2010/06/04/first-impressions-from-jazoon/#comments</comments>
		<pubDate>Fri, 04 Jun 2010 06:38:58 +0000</pubDate>
		<dc:creator>Igor Drobiazko</dc:creator>
				<category><![CDATA[Tapestry]]></category>

		<guid isPermaLink="false">http://blog.tapestry5.de/?p=1350</guid>
		<description><![CDATA[The Jazoon 2010 is closed. I enjoyed the most of the talks and met some folks. My talk JavaServer Faces 2.0 vs. Tapestry 5 took place on Thursday, 3 June in the arena 7. Unfortunately my presentation will not be available as video since only talks in the largest arena 5 has been recorded. The [...]]]></description>
			<content:encoded><![CDATA[<p>The Jazoon 2010 is closed. I enjoyed the most of the talks and met some folks. My talk <a title="JSF 2.0 vs. Tapestry 5" href="http://blog.tapestry5.de/index.php/2010/03/30/jazoon-2010-talk-javaserver-faces-2-0-vs-tapestry-5/">JavaServer Faces 2.0 vs. Tapestry 5</a> took place on Thursday, 3 June in the arena 7. Unfortunately my presentation will not be available as video since only talks in the largest arena 5 has been recorded. The slides of the talk are available <a title="Slides" href="http://blog.tapestry5.de/wp-content/uploads/2010/06/JSF-2.0-vs-Tapestry-5.pdf" target="_blank">here</a>. However, I enjoyed the conference and will submit some presentation proposals next year again.</p>
<p>Directly after my talk <a title="Roger Kitains" href="http://www.java.net/blogs/rogerk" target="_blank">Roger  Kitains</a>, a JSF co-specification lead, was giving a presentation <a title="Exploring HTML5 With JavaServer Faces 2.0" href="http://jazoon.com/Conference/Thursday/Kitain" target="_blank">Exploring  HTML5 With JavaServer Faces 2.0</a>. He was attending my presentation and I had the pleasure to discuss Tapestry and JSF with him. Roger told me he enjoyed my talk and was impressed by Tapestry. He likes Tapestry&#8217;s annotation-based approach and implicit type conversion which probably will be adapted in the upcoming JSF version.</p>
<p>Also <a title="Andy Bosch" href="http://jazoon.com/Conference/Thursday/Bosch" target="_blank">Andy Bosch</a>, another JSF guru, was attending my talk. He was impressed by the Live Class Reloading feature. Probably we&#8217;ll give together a JSF vs. Tapestry talk in the future. I believe that such a talk would be very funny. I would concentrate on Tapestry part and he would present JSF.</p>
<p>I also had a chance to meet <a title="Evgeni Kabanov" href="http://www.ekabanov.net/" target="_blank">Evgeni Kabanov</a>, the founder and CTO of <a title="ZeroTurnaround" href="http://www.zeroturnaround.com/" target="_blank">ZeroTurnaround</a>, who gave an amazing <a title="Did you really get classloaders?" href="http://jazoon.com/Conference/Tuesday/Kabanov" target="_blank">talk on class loaders</a>. I was interested in his talk and was not disappointed. We discovered Zurich together and had the pleasure to discuss the <a title="Live Class Reloading" href="http://tapestry.apache.org/tapestry5.1/guide/reload.html" target="_blank">Live Class Realoading</a> in Tapestry and <a title="JRebel" href="http://www.zeroturnaround.com/jrebel/" target="_blank">JRebel</a> during a dinner in a Japanese restaurant. By the way, if some of the readers is not using Tapestry but wants to be productive, you should give JRebel a try.</p>
<p>As summary of my talk I will publish a series of articles on JSF vs. Tapestry topic in order to share with you the result of my research.</p>
<p>Here are some pics which has been taken during my presentation.</p>
<p><a href="http://blog.tapestry5.de/wp-content/uploads/2010/06/jazoon1.jpg"><img class="aligncenter size-full wp-image-1353" title="jazoon1" src="http://blog.tapestry5.de/wp-content/uploads/2010/06/jazoon1.jpg" alt="" width="500" height="333" /></a></p>
<p><a href="http://blog.tapestry5.de/wp-content/uploads/2010/06/jazoon2.jpg"><img class="aligncenter size-full wp-image-1354" title="jazoon2" src="http://blog.tapestry5.de/wp-content/uploads/2010/06/jazoon2.jpg" alt="" width="500" height="333" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tapestry5.de/index.php/2010/06/04/first-impressions-from-jazoon/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
