[jira] Created: (TAP5-1357) Add ServletException to signature of HttpServletRequestFilter#service

2010-11-26 Thread Alexander Gavrilov (JIRA)
Add ServletException to signature of HttpServletRequestFilter#service
-

 Key: TAP5-1357
 URL: https://issues.apache.org/jira/browse/TAP5-1357
 Project: Tapestry 5
  Issue Type: Improvement
  Components: tapestry-core
Affects Versions: 5.2.4
Reporter: Alexander Gavrilov


It's common practice to wrap some native javax.servlet.Filter implementations 
into HttpServletRequestFilter and contribute that adapter to 
HttpServletRequestHandler. Signatures of both Interfaces almost match, but   
HttpServletRequestFilter  does not declare ServletException  as possible 
catched exception in the signature. This means that it's required to wrap 
ServletExcpetion into some RuntimeException wrapper to rethrow it. As i c there 
is no propblem to add this kind of ecxeption without break of existig 
functionality. 

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.



[jira] Updated: (TAP5-1357) Add ServletException to signature of HttpServletRequestFilter#service

2010-11-26 Thread Alexander Gavrilov (JIRA)

 [ 
https://issues.apache.org/jira/browse/TAP5-1357?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Alexander Gavrilov updated TAP5-1357:
-

Fix Version/s: 5.2.5

 Add ServletException to signature of HttpServletRequestFilter#service
 -

 Key: TAP5-1357
 URL: https://issues.apache.org/jira/browse/TAP5-1357
 Project: Tapestry 5
  Issue Type: Improvement
  Components: tapestry-core
Affects Versions: 5.2.4
Reporter: Alexander Gavrilov
 Fix For: 5.2.5


 It's common practice to wrap some native javax.servlet.Filter implementations 
 into HttpServletRequestFilter and contribute that adapter to 
 HttpServletRequestHandler. Signatures of both Interfaces almost match, but   
 HttpServletRequestFilter  does not declare ServletException  as possible 
 catched exception in the signature. This means that it's required to wrap 
 ServletExcpetion into some RuntimeException wrapper to rethrow it. As i c 
 there is no propblem to add this kind of ecxeption without break of existig 
 functionality. 

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.



[jira] Updated: (TAP5-1357) Add ServletException to signature of HttpServletRequestFilter#service

2010-11-26 Thread Thiago H. de Paula Figueiredo (JIRA)

 [ 
https://issues.apache.org/jira/browse/TAP5-1357?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Thiago H. de Paula Figueiredo updated TAP5-1357:


Fix Version/s: (was: 5.2.5)

The fix version is only set when a fix is committed to SVN.

 Add ServletException to signature of HttpServletRequestFilter#service
 -

 Key: TAP5-1357
 URL: https://issues.apache.org/jira/browse/TAP5-1357
 Project: Tapestry 5
  Issue Type: Improvement
  Components: tapestry-core
Affects Versions: 5.2.4
Reporter: Alexander Gavrilov

 It's common practice to wrap some native javax.servlet.Filter implementations 
 into HttpServletRequestFilter and contribute that adapter to 
 HttpServletRequestHandler. Signatures of both Interfaces almost match, but   
 HttpServletRequestFilter  does not declare ServletException  as possible 
 catched exception in the signature. This means that it's required to wrap 
 ServletExcpetion into some RuntimeException wrapper to rethrow it. As i c 
 there is no propblem to add this kind of ecxeption without break of existig 
 functionality. 

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.



[CONF] Apache Tapestry Developer Information

2010-11-26 Thread confluence







Developer Information
Page edited by Bob Harner


Comment:
Added links to child pages


 Changes (2)
 



Information needed by Tapestry developers. 
This is a list of information useful to people _developing_ Tapestry itself (rather than developers _using_ Tapestry).  * [Confluence Site Setup] --  * [Release Process] * [Developer Bible] 

Full Content

This is a list of information useful to people developing Tapestry itself (rather than developers using Tapestry).


	Confluence Site Setup 
	Release Process
	Developer Bible





Change Notification Preferences

View Online
|
View Changes









[CONF] Apache Tapestry Page Lifecycle

2010-11-26 Thread confluence







Page Lifecycle
Page
comment added by  Bob Harner



   I believe this page needs to be rewritten for the new approach in 5.2 of not pooling pages.  This will nee dto be done by someone with a better understanding of the mechanisms involved than I have.




   
Change Notification Preferences
   
   View Online
   









[CONF] Apache Tapestry Page Lifecycle

2010-11-26 Thread confluence







Page Lifecycle
Comment edited by Bob Harner
 :

Changes (1)




I believe this page needs to be rewritten for the new approach in 5.2 of _not_ pooling pages.  This will nee d to be done by someone with a better understanding of the mechanisms involved than I have. 

Full Content
  
I believe this page needs to be rewritten for the new approach in 5.2 of not pooling pages.  This will need to be done by someone with a better understanding of the mechanisms involved than I have.



   
Change Notification Preferences
   
   View Online
   









[CONF] Apache Tapestry Component Rendering

2010-11-26 Thread confluence







Component Rendering
Page edited by Bob Harner


Comment:
Removed initial focus on Tapestry 4.  Reduced heading sizes for consistency with other pages.  (h1 should only be used as the top-most heading, if at all)


 Changes (21)
 



h1. Component Rendering  
h2. Tapestry 4 Approach 
Rendering of components in Tapestry 5 is based on a _state machine_ and a _queue_ (instead of the tail recursion used in Tapestry 4). This breaks the rendering process up into tiny pieces that can easily be implemented or overridden. Dont worry, in practice, it is a breathtakingly small amount of code to write. 
 
Rendering was a recursive process. Each component implemented a render() method (inherited from an IRender interface). Components would invoke render() on the objects in their template, including other components. 
h2. Rendering Phases 
 
[Bruce Tate|http://blog.rapidred.com/] has said if you get vertigo, dont stand at the edge of a JavaServer Faces stack trace and look down. The same applies to Tapestry 4. Once you have heavily nested, looping components, the stack trace can get quite deep.  h2. Tapestry 5 Approach  Rendering of components is based on a _state machine_ and a _queue_ instead of tail recursion. This breaks the rendering process up into tiny pieces that can easily be implemented or overriden. Dont worry, in practice, it is a breathtakingly small amount of code to write.  h1. Rendering Phases  
The rendering of each component is divided into a number of phases, illustrated below.  
...
Whats really mind blowing is that the template and body of a component will often contain ... more components! That means that many different components will be in different phases of their own state machine.  
h23. SetupRender 
 [...@setuprender|http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/SetupRender.html] -- This is where you can perform any one-time per-render setup for your component. This is a good place to read component parameters and use them to set temporary instance variables.  
h23. BeginRender 
 [...@beginrender|http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/BeginRender.html] -- For components that render a tag, the start tag should be rendered here (the close tag should be rendered inside the AfterRender phase). The component can also prevent the template and/or body from being rendered by returning false. 
...
If no methods are annotated with BeginRender, then no special output occurs during this phase, but the template (if present) or body (if no template is present, but the component has a body) will be rendered.  
h23. BeforeRenderTemplate 
 [...@beforerendertemplate|http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/BeforeRenderTemplate.html] -- This phase exists to allow a component to decorate its template (creating markup around the template generated markup), or to allow a component to skip its template.  
h2.BeforeRenderBody 
h3. BeforeRenderBody 
 [...@beforerenderbody|http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/BeforeRenderBody.html] -- This phase is associated with a components body (the portion of its containers template that the component occupies). The BeforeRenderBody phase allows the component the ability to skip the body, while still rendering the rest of the components template (if any). 
...
If no methods are annotated with BeforeRenderBody, then the body will be rendered by default. Again, this occurs when the body element of the components template is reached, or automatically if the component has no template (but the component does have a body).  
h23. AfterRenderBody 
 [...@afterrenderbody|http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/AfterRenderBody.html] -- This phase is executed after the body is rendered; this only occurs for components with a body.  
h23. AfterRender 
 [...@afterrender|http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/AfterRender.html] -- This phase complements BeginRender, and is often used to render the close tag that matches the start tag rendered in the BeginRender phase. In any case, the AfterRender phase can continue on to CleanupRender, or revert back to BeginRender (as in our Count component example, above). 
...
If no methods are annotated with AfterRender, then no special output occurs, and the CleanupRender phase is triggered.  
h23. CleanupRender 
 

[CONF] Apache Tapestry Component Rendering

2010-11-26 Thread confluence







Component Rendering
Page edited by Bob Harner


Comment:
Better wording on the render phase descriptions, and clarified the duplicate-annotation-within-a-single-class paragraph


 Changes (9)
 



...
h3. SetupRender  
[...@setuprender|http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/SetupRender.html] -- This The SetupRender phase (see [...@setuprender|http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/SetupRender.html]) is where you can perform any one-time per-render setup for your component. This is a good place to read component parameters and use them to set temporary instance variables. 
 h3. BeginRender  
[...@beginrender|http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/BeginRender.html] -- The BeginRender phase (see [...@beginrender|http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/BeginRender.html]) occurs at the start of the rendering of the component. For components that render a tag, the start tag should be rendered here (the close tag should be rendered inside the AfterRender phase). The component can also prevent the template and/or body from being rendered by returning false. 
 Components may or may not have a template. If a component has a template, and the template includes a body element, then the BeforeRenderBody phase will be triggered (giving the component the option of rendering its body or not). 
...
h3. BeforeRenderTemplate  
[...@beforerendertemplate|http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/BeforeRenderTemplate.html] -- This The BeforeRenderTemplate phase (see [...@beforerendertemplate|http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/BeforeRenderTemplate.html]) exists to allow a component to decorate its template (creating markup around the template generated markup), or to allow a component to skip its template. 
 h3. BeforeRenderBody  
[...@beforerenderbody|http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/BeforeRenderBody.html] -- This The BeforeRenderBody phase (see [...@beforerenderbody|http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/BeforeRenderBody.html]) is associated with a components body (the portion of its containers template that the component occupies). The BeforeRenderBody phase allows the component the ability to skip the body, while still rendering the rest of the components template (if any). 
 If no methods are annotated with BeforeRenderBody, then the body will be rendered by default. Again, this occurs when the body element of the components template is reached, or automatically if the component has no template (but the component does have a body). 
...
h3. AfterRenderBody  
[...@afterrenderbody|http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/AfterRenderBody.html] -- This The AfterRenderBody phase (see [...@afterrenderbody|http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/AfterRenderBody.html]) is executed after the body is rendered; this only occurs for components with a body. 
 h3. AfterRender  
[...@afterrender|http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/AfterRender.html] -- This The AfterRender phase (see [...@afterrender|http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/AfterRender.html]) complements BeginRender, and is often used to render the close tag that matches the start tag rendered in the BeginRender phase. In any case, the AfterRender phase can continue on to CleanupRender, or revert back to BeginRender (as in our Count component example, above). 
 If no methods are annotated with AfterRender, then no special output occurs, and the CleanupRender phase is triggered. 
...
h3. CleanupRender  
[...@cleanuprender|http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/CleanupRender.html] -- This The CleanupRender phase (see [...@cleanuprender|http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/CleanupRender.html]) is the counterpart to SetupRender, allowing final cleanup to occur. 
 h2. Using Method Names instead of Annotations 
...
h2. Within a Single Class  
Currently, methods are sorted alphabetically. Methods with the same name are sorted by number of parameters. Even so, this is not a great idea ... just define one method, and have it call the other methods in the order you desire. 
Currently, rendering methods having the same 

[CONF] Apache Tapestry Injection

2010-11-26 Thread confluence







Injection
Page
comment added by  Bob Harner



   The Default Injection section near the bottom make references to the Alias service.  Does this need to be updated for 5.2 to refer to ServiceOverrides?




   
Change Notification Preferences
   
   View Online
   









[CONF] Apache Tapestry Page Life Cycle

2010-11-26 Thread confluence







Page Life Cycle
Page edited by Bob Harner


Comment:
Renamed Lifecycle to Life Cycle, spelling  @ for annotations


 Changes (12)
 



h1. Page Lifecycle 
h1. Page Life Cycle 
 In Tapestry, you are free to develop your presentation objects, page and components classes, as ordinary objects, complete with instance variables and so forth. 
...
A page instance will be checked out of the pool for a short period of time: a few milliseconds to service a typical request. Because of this, it is generally the case that Tapestry can handle a large number of end users with a relatively small pool of page instances.  
h12. Comparison to JavaServer Pages 
 JSPs also use a caching mechanism; the JSP itself is compiled into a Java servlet class, and acts as a singleton. 
...
Tapestry can also take advantage of its more coarse grained caching to optimize how data moves, via parameters, between components. This means that Tapestry pages will actually speed up after they render the first time.  
h12. Page Pool Configuration 
 Tapestrys page pool is used to store page instances. The pool is keyed on the name of the page (such as start) and the _locale_ for the page (such as en or fr). 
...
If performance is absolute and you have lots of memory, then increase the soft and hard limit and reduce the soft wait. This encourages Tapestry to create more page instances and not wait as long to re-use existing instances.  
h1. Page Lifecycle Methods 
h2. Page Life Cycle Methods 
 
There are a few situations where it is useful for a component to perform some operations, usually some kind of initialization or caching, based on the life cycle of the page. 
 
The page life cycle is quite simple. When first needed, a page is loaded. Loading a page involves instantiating the components of the page and connecting them together. 
 Once a page is loaded, it is _attached_ to the current request. Remember that there will be many threads, each handling its own request. In many cases, there will be multiple copies of the same page attached to different requests (and different threads). This is how Tapestry keeps you from worrying about multi-threading issues ... the objects involved in any request are reserved to _just_ that request (and _just_ that thread). 
...
You have the choice of attaching an annotation to a method, or simply naming the method correctly.  
Page life cycle methods should take no parameters and return void. 
 The annotations / method names are:  
* [@PageLoaded|http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/PageLoaded.html] annotation, or method name pageLoaded 
* [@PageAttached|http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/PageAttached.html] annotation, or method name pageAttached 
* [@PageDetached|http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/PageDetached.html] annotation, or method name pageDetached 

Full Content

Page Life Cycle

In Tapestry, you are free to develop your presentation objects, page and components classes, as ordinary objects, complete with instance variables and so forth.

This is somewhat revolutionary in terms of web development in Java. Using servlets, or Struts, your presentation objects (Servlets, or Struts Actions, or the equivalent in other frameworks) are stateless singletons. That is, a single instance is created, and all incoming requests are threaded through that single instance.

Because multiple requests are handled by many different threads, this means that the single instance's variable are useless ... any value written into an instance variable would immediately be overwritten by a different thread. Thus, it is necessary to use the Servlet API's HttpServletRequest object to store per-request data, and the HttpSession object to store data between requests.

Tapestry takes a very different approach.

In Tapestry, you will have many different instances of any particular page, each either in use for a single request (on a single thread), or waiting in a page pool to be used.

By reserving page instances to particular threads, all the difficult, ugly issues related to multi-threading go by the wayside. Instead, familiar, simple coding practices (using ordinary methods and fields) can be used.

However, there's a risk: it would be a disaster if data could "bleed" from one request to another. Imagine the outcome in a banking application if the first user's account number and password became 

[CONF] Apache Tapestry Injection FAQ

2010-11-26 Thread confluence







Injection FAQ
Page edited by Howard M. Lewis Ship


 Changes (1)
 



...
Environmentals are a form of loosely connected communication between an outer component (or even a service) and an inner component.  Example: the Form component places a {{FormSupport}} object into the environment.  Other components, such as TextField, use the {{FormSupport}} when rendering to perform functions such as allocate unique control names or register client-side validations.  The TextField doesnt require that the Form component be the immediate container component, or even an ancestor: a Form on one page may, indirectly, communicate with a TextField on some entirely different page. Neither component directly links to the other, the {{FormSupport}} is the conduit that connects them.  
h3. I use @Inject on a field to inject a service, but the field is still null, what happened?  This can happend when you use the wrong @Inject annotation; for example, com.google.inject.Inject instead of org.apache.tapestry5.ioc.annotations.Inject.  This may happen when you have TestNG on the classpath, for example, and your IDE is too helpful.  Double check your imports when things seem weird.  
 {display-footnotes}  

Full Content

Injection

What's the difference between the Component and InjectComponent annotations?

The Component annotation is used to define the type of component, and its parameter bindings. When using Component, the template must not define the type, and any parameter bindings are merged in:



  a t:id="home" class="nav"Back to home/a





  @Component(parameters={ "page=index" })
  private PageLink home;



Here the type of component is defined by the field type. The field name is matched against the t:id in the template. The page parameter is set in the Java class, and the informal class parameter is set in the template.  If the tag in the template was t:pagelink, or if the template tag included the attribute t:type="pagelink", then you would see an exception.

By contrast, InjectComponent expects the component to be already defined, and doesn't allow any configuration of it:



  t:form t:id="login"  /t:form





  @InjectComponent
  private Form login;



Again, we're matching the field name to the component id, and you would get an error if the component is not defined in the template.

What's the difference between the InjectPage and InjectContainer annotations?

The InjectPage annotation is used to inject some page in the application into a field of some other page.  You often see it used from event handler methods:



  @InjectPage
  private ConfirmRegistration confirmRegistration;

  Object onSuccessFromRegistrationForm()
  {
confirmRegistration.setStatus("Registration accepted");
confirmRegistration.setValidationCode(userRegistrationData.getValidationCode());

return confirmRegistration;
  }



This code pattern is used to configure peristent properties of a page before returning it; Tapestry will send a client redirect to the page to present the data.

InjectContainer can be used inside a component or a mixin.  In a component, it injects the immediate container of the component; this is often the top-level page object.

In a mixin, it injects the component to which the mixin is attached.

I get an exception because I have two services with the same interface, how do I handle this?

It's not uncommon to have two or more services that implement the exact same interface. When you inject, you might start by just identifying the type of service to inject:



	@Inject
	private ComponentEventResultProcessor processor;



Which results in the error: Service interface org.apache.tapestry5.services.ComponentEventResultProcessor is matched by 3 services: AjaxComponentEventResultProcessor, ComponentEventResultProcessor, ComponentInstanceResultProcessor. Automatic dependency resolution requires that exactly one service implement the interface.

We need more information than just the service interface type in order to identify which of the three services to inject. One possibility is to inject with the correct service id:



	@InjectService("ComponentEventResultProcessor")
	private ComponentEventResultProcessor processor;



This works ... but it is clumsy. If the service id, "ComponentEventResultProcessor", ever changes, this code will break. It's not refactoring safe.

Instead, we should use marker annotations.  If we look at TapestryModule, where the ComponentEventResultProcessor service is defined, we'll see it identifies the necessary markers:



@Marker(
{ Primary.class, Traditional.class })
public ComponentEventResultProcessor buildComponentEventResultProcessor(
MapClass, ComponentEventResultProcessor configuration)
{
return 

[jira] Commented: (TAP5-1355) Threading issue with SessionStateObjects

2010-11-26 Thread Josh Canfield (JIRA)

[ 
https://issues.apache.org/jira/browse/TAP5-1355?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=12936116#action_12936116
 ] 

Josh Canfield commented on TAP5-1355:
-

Hi Andy.

Sorry, I jumped to solving the immediate problem and didn't step back to 
consider the base problem that was originally being solved. The problem seems 
to be that Tapestry is depending on HttpSessionBindingListener in order to 
manage session attribute lifecycle, and that the behavior is container 
specific. I looked at the Jetty code and it uses .equals, but Tomcat uses != to 
determine whether to call the valueBound method.

The servlet spec is not clear about what the right behavior is for the 
container. I was surprised that the spec is actually self contradictory about 
how the method was even supposed to be called. For instance, in the 2.4 spec 
SRV.7.4 The valueBound method must be called before the object is made 
available via the getAttribute method of the HttpSession interface. and then 
in SRV.15.1.7, the javadoc for HttpSession it says Notifications are sent 
after the binding methods complete. Both Tomcat and Jetty seem take the 
approached defined in the HttpSession docs (maybe I'm reading something wrong 
here.) This means that in a situation where you are accessing the object in a 
multi-threaded manner you could get the object from the session before your 
valueBound method has even run. Threading issues have been left up to the 
developer.

The biggest hole though, there is no specification as far as I can find as to 
what it means to bind an object to the session. Jetty will call valueBound if 
the .equals says it's different, Tomcat only if the object has changed (you 
only bind an object to the session once). Since we have two containers that 
behave differently we can only imagine that other containers will take 
alternating approaches.

To sum up; the prevailing wisdom seems to be that after changing the value 
within a session attribute that calling session.setAttribute() is enough to get 
clustered session attribute replicated. Having spent some time with this code I 
think the dependency on HttpSessionBindingListener should be dropped and 
Tapestry should go with Andy's number two solution. Keeping the dirty/clean 
cycle within Tapestry's code.



 Threading issue with SessionStateObjects
 

 Key: TAP5-1355
 URL: https://issues.apache.org/jira/browse/TAP5-1355
 Project: Tapestry 5
  Issue Type: Bug
  Components: tapestry-core
Affects Versions: 5.2.4
Reporter: Moritz Gmelin
 Attachments: Screenshot.png.jpg, taptest.tgz


 When a page request consists of multiple HTTP request (e.g. page and some 
 dynamically generated images) and all those requests access a 
 SessionStateObject, it happens that a new session (with an empty SSO) is 
 created for some of the request threads.
 I was able to create a very simple example to recreate that problem:
   -A simple page that displays 20 dynamically generated images in a loop.
   -In the page, a SSO, holding a number value is initialized to a random 
 number.
   -Each of the dynamic images read that number and draws it.
   -Make sure that a HTTP-Request is made for every image on the page (by 
 adding some random number to the event link)
 The effect that you'll see after some reloads of the page (maybe you need to 
 reload 30 times) is that some images will draw 0 as SSO value instead of the 
 number set in the page @BeginRender method. Those fields will be marked in 
 red in the demo so you can quickly see them. 
 I definitely beleive that tapestry should take care of this. It is a use case 
 for SSOs that is probably too common to ignore. 
 Why can't this be automatically integrated into the ApplicationStateManager?
  
 The demo has been deployed here
 http://www.avetana.de/taptest/

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.



[CONF] Apache Tapestry Tapestry Inversion of Control Container

2010-11-26 Thread confluence







Tapestry Inversion of Control Container
Page edited by Howard M. Lewis Ship


 Changes (25)
 



...
h3. My service starts a thread; how do I know when the application is shutting down, to stop that thread?  
This same concern applies to any long-lived resource (a thread, a database connection, a JMS queue connection) that a service may hold onto.  Your code needs to know when the application has been undeployed and shutdown.  This is actually quite easy, by using a service builder method.  In adding some post-injection logic to your module class: implementation class. 
 {code:controls=true|linenumbers=true} 
  public MyService buildMyService(ServiceResources resources, RegistryShutdownHub shutdownHub) 
public class MyServiceImpl implements MyService, RegistryShutdownListener 
{ 
final MyServiceImpl service = resources.autobuild(MyServiceImpl.class); 
  private boolean shuttingDown; 
 
shutdownHub.addRegistryShutdownListener(new RegistryShutdownListener() {   public void registryDidShutdown()   { service.shutdown();   } }); 
  private final Thread workerThread; 
 
return service; 
  public MyServiceImpl()   { workerThread = new Thread(. . .); 
  } 
{code} 
 
This code uses the ServiceResources object to build an instance of MyServiceImpl, with all dependencies injected. It also injects Tapestrys RegistryShutdownHub service and adds a listener. The example assumes that the service implementation (but not the service _interface_) includes a {{shutdown()}} method. 
  . . . 
 
A valid alternative to this would be to have MyServiceImpl implement RegistryShutdownListener: 
  @PostInjection   public void startupService(RegistryShutdownHub shutdownHub)   { shutdownHub.addShutdownListener(this);   } 
 
{code:controls=true|linenumbers=true}   public MyService buildMyService(ServiceResources resources, RegistryShutdownHub shutdownHub) 
  public void registryDidShutdown() 
  { 
final MyServiceImpl service = resources.autobuild(MyServiceImpl.class); 
shuttingDown = true; 
 
shutdownHub.addRegistryShutdownListener(service); workerThread.interrupt(); 
  } 
return service; 
} 
{code}  
After Tapestry invokes the constructor of the service implementation, and after it performs any field injections, it invokes post injection methods. The methods must be public and return void.  Parameters to a post injection method represent further injections ... in the above example, the RegistryShutdownHub is injected into the PostInjection method, since it is only used inside that one method.  
{warning} 
It is *not* recommended that MyServiceImpl take RegistryShutdownHub as a constructor parameter and register itself as a listener. Doing so is an example of [unsafe publishing|http://www.ibm.com/developerworks/java/library/j-jtp0618.html]. 
It is *not* recommended that MyServiceImpl take RegistryShutdownHub as a constructor parameter and register itself as a listener inside the constructor. Doing so is an example of [unsafe publishing|http://www.ibm.com/developerworks/java/library/j-jtp0618.html], a remote but potential thread safety issue. 
{warning} 
 This same technique will work for any kind of resource that must be cleaned up or destroyed when the registry shuts down.  {note} Be careful not to invoke methods on any service proxy objects as they will also be shutting down with the Registry. A RegistryShutdownListener should not be reliant on anything outside of itself. {note} 

Full Content

Tapestry Inversion of Control Container

Main article: Tapestry IoC

Why do I need to define an interface for my services?  Why can't I just use the class itself?

First of all: you can do exactly this, but you lose some of the functionality that Tapestry's IoC container provides.

The reason for the split is so that Tapestry can provide functionality for your service around the core service implementation.  It does this by creating proxies: Java classes that implement the service interface.  The methods of the proxy will ultimately invoke the methods of your service implementation.

One of the primary purposes for proxies is to encapsulate the service's life cycle: most services are singletons that are created just in time.  Just in time means only as soon as you invoke a method.  What's going on is that the life cycle proxy (the 

[CONF] Apache Tapestry Documentation Shortcomings

2010-11-26 Thread confluence







Documentation Shortcomings
Page  added by Bob Harner

 

 This is an informal list of the shortcomings in the Tapestry 5 site documentation  things to work on soon.


	Need more cross-linking between the wiki pages, specially between FAQ pages, User Guide pages, Cheat Sheet pages and Cookbook pages that cover the same topic.
	
		Component Cheat Sheet should have, for each of the listed annotations, a link to the corresponding API page.
	
	
	Some pages don't link to all of their child pages
	Move some of the best MoinMoin wiki content into Confluence?




   
Change Notification Preferences
   
   View Online
   








[CONF] Apache Tapestry Component Classes

2010-11-26 Thread confluence







Component Classes
Page edited by Bob Harner


 Changes (1)
 



...
{float}  
*Component classes* in Tapestry 5 are much easier than in Tapestry 4. There are no base classes to extend from, the classes are concrete (not abstract), and theres no XML file. There is still a bit of configuration in the form of Java annotations, but those now go directly onto fields of your class, rather than on abstract getters and setters (the case in Tapestry 4). 
 Classes for pages, for components and for component mixins are all created in an identical way. 
...

Full Content

Component Classes

Related Articles
	Page And Component Classes FAQ
	Component Cheat Sheet



Component classes in Tapestry 5 are much easier than in Tapestry 4. There are no base classes to extend from, the classes are concrete (not abstract), and there's no XML file. There is still a bit of configuration in the form of Java annotations, but those now go directly onto fields of your class, rather than on abstract getters and setters (the case in Tapestry 4).

Classes for pages, for components and for component mixins are all created in an identical way.

Component Class Basics

Creating page and component classes in Tapestry 5 is a breeze.

Unlike Tapestry 4, in Tapestry 5, component classes are not abstract, nor do they extend from framework base classes. They are pure POJOs (Plain Old Java Objects).

There are only a few constraints:


	The classes must be public.
	The classes must be in the correct package, as per the application configuration.
	The class must have a standard public, no arguments constructor.
Here's a very basic component:





package org.example.myapp.components;

import org.apache.tapestry5.MarkupWriter;
import org.apache.tapestry5.annotations.BeginRender;

public class HelloWorld
{
@BeginRender
void renderMessage(MarkupWriter writer)
{
writer.write("Bonjour from HelloWorld component.");
}
}



This component's only job is to write out a fixed message. The @BeginRender annotation is a type of component lifecycle annotation, a method annotation that instructs Tapestry when and under what circumstances to invoke methods of your class.

In another departure from Tapestry 4, these methods are not necessarily public; they can have any visibility you like.

Component Packages

Component classes must exist within an appropriate package (this is necessary for runtime code transformation and class reloading to operate).

These packages exist under the application's root package.

For pages, place classes in root.pages. Page names are mapped to classes within this package.

For components, place classes in root.components. Component types are mapped to classes within this package.

For mixins, place classes in root.mixins. Mixin types are mapped to classes within this package.

In addition, it is common for an application to have base classes, often abstract base classes, that should not be directly referenced. These should not go in the pages, components or mixins packages, because they then look like valid pages, components or mixins. Instead, use the root.base package to store such base classes.

Sub-Folders / Sub-Packages

Classes do not have to go directly inside the package (pages, components, mixins, etc.). It is valid to create a sub-package to store some of the classes. The sub-package name becomes part of the page name or component type. Thus you might define a page component com.example.myapp.pages.admin.CreateUser and the logical page name (which often shows up inside URLs) will be admin/CreateUser.

Tapestry performs some simple optimizations of the logical page name (or component type, or mixin type). It checks to see if the package name is either a prefix or a suffix of the unqualified class name (case insensitively, of course) and removes the prefix or suffix if so. The net result is that a class name such as com.example.myapp.pages.user.EditUser will have a page name of user/Edit (not user/EditUser). The goal here is to provide shorter, more natural URLs.

Pages vs. Components

The distinction in Tapestry 5 between pages and component is very, very small. The only real difference is the package name: root.pages.PageName for pages, and root.components.ComponentType for components.

In Tapestry 4, there was a much greater distinction between pages and components, which showed up as separate interfaces and a hierarchy of abstract implementations to extend your classes from.

In Tapestry 5, the "page" is still somewhat present, but is really an internal Tapestry class. Page components are simply the root component of a page's component tree.

Class Transformation

Tapestry uses your class as a starting point. It transforms your class at runtime. This is necessary for a