Modified: tapestry/tapestry5/trunk/src/site/apt/guide/event.apt URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/src/site/apt/guide/event.apt?rev=753411&r1=753410&r2=753411&view=diff ============================================================================== --- tapestry/tapestry5/trunk/src/site/apt/guide/event.apt (original) +++ tapestry/tapestry5/trunk/src/site/apt/guide/event.apt Fri Mar 13 21:11:16 2009 @@ -1,269 +1,269 @@ - --- - Component Events - --- - -Component Events - - Component events are the means by which components are made aware of behaviors by the user, such - as clicking links and submitting forms. - - Component events are used for two purposes: - - * They represent requests initiated by the user, triggered by links and forms in the client web browser. - These are described more fully in {{{pagenav.html}page navigation}} and in - {{{request.html}requst processing}}. - - * They represent flow-of-control within a request, allowing one component to notify its container - about some kind of circumstance ("a form was submitted"), or to collect some piece for data - from the container. - - [] - - Often, a navigation request (originating with the user) will spawn a number of flow-of-control - requests. For example, a Form component will be triggered by an action request, and will then - send notification events to announce when the form submission is about to be processed, and - whether it was succesful or not. - - In Tapestry 4, you would configure a parameter of a component with the name of a method to invoke - when a certain event occured, usually a request from the client. - - This has some limitations, including the fact that only a single method could be invoked, and that - it tied together a component and a method based on a method name, which required careful coordination - between the template and the Java code. - - Tapestry 5 introduces the concept of <event handler methods>, identified via a naming convention, or - via the - {{{../apidocs/org/apache/tapestry5/annotations/OnEvent.html}OnEvent annotation}}. Event handler methods - may have any visibility, even private. Normally they are given package private visibility, to support testing. - - Rather than configure a component to invoke a particular method, you identify one or more - methods to listen for events from that component. A single event handler method may receive notifications from - many different components. - - For example, here's a portion of a page (let's call it "Chooser") that lets the user choose a number between 1 and 10: - -+---+ -<p> Choose a number from 1 to 10: </p> - -<p> - <t:count end="10" value="index"> - <a t:id="select" t:type="actionlink" context="index">${index}</t:comp> - </t:count> -</p> -+---+ - - The ActionLink component creates an action URL. - - The URL identifies the page that contains the component ("chooser"), the type of event - (unless it is "action", the default and most common event type), - the id of the component within the page ("select"), plus the additional context value(s). - - A sample URL: <<<http://localhost:8080/chooser.select/3>>>. - - When there are additional context values, they are appended to the path. - - This demonstrates a critical difference between Tapestry and a more traditional, action oriented framework. - This URL doesn't say what happens when the link is clicked, it identifies <which component is responsible> - when the link is clicked. - - There's no simple mapping from URL to a piece of code; instead the component sends notifications, in the form - of invocations of event handler methods, and Tapestry ensures that the correct bit of code, code that you supply, - gets invoked. - - - A Java method can be invoked when the link for the component is clicked by the user: - -+---+ - @OnEvent(component = "select") - void valueChosen(int value) - { - this.value = value; - } -+---+ - - Tapestry has done two things here: - - * It has identified method valueChosen() as the method to invoke. - - * It has converted the context value from a string to an integer and passed it into the method. - - [] - - In the above example, the valueChosen() method will be invoked on the default event, "action", that originates - in component <<<select>>> (and has at least one context value). - - Some components can emit more than one type of event, in which case you will want to be more specific: - -+---+ - @OnEvent(value = "action", component = "select") - void valueChosen(int value) - { - this.value = value; - } -+---+ - - The value attribute of the OnEvent annotation is the name of the event to match. - - "action" is the name of the default event type; the ActionLink and Form components each use this event type. - If you omit the component part of the OnEvent annotation, then you'll recieve notifications from - <all> contained components, possibly including nested components (due to event bubbling). - - As elsewhere, the comparison of event type and component id is caseless. - - You should qualify exactly which component(s) you wish to recieve events from. Using @OnEvent on a method - and not specifying a specific component id means that the method will be invoked for events from <any> component. - -Event Handler Method Convention Names - - As an alternative to the use of annotations, you may name your events in a specific fashion, and Tapestry will invoke your methods just as if - they were annotated. - - This style of event handler methods start with the prefix "on", followed by the name of the action. You may then continue by adding "From" and - a capitalized component id (remember that Tapestry is case insensitive about event names and component ids). - - The previous example may be rewritten as: - -+---+ - void onActionFromSelect(int value) - { - this.value = value; - } -+---+ - - Note from Howard: I've found that I prefer the naming convention approach, and reserve the annotation just for situations that don't otherwise fit. - -Event Handler Method Return Values - - For page navigation events (originating in components such as ActionLink and Form), - the value returned from an event handler method {{{pagenav.html}determines how Tapestry will render a response}}. - -Multiple Method Matches - - In some cases, you may have multiple event methods match a single event. - - The order is as follows: - - * Base class methods before sub-class methods. - - * Matching methods within a class in alphabetical order. - - * For a single method name with multiple overrides, by number of parameters, descending. - - [] - - There's only rare cases where it makes sense for more than one method to handle an event. - - When a sub-class overrides an event handler method of a base class, the event handler method is only invoked once, along with - any other base class methods. The subclass can change the <implementation> of the base class method via an override, but - can't change the <timing> of when that method is invoked. See {{{https://issues.apache.org/jira/browse/TAPESTRY-2311}TAPESTRY-2311}}. - -Event Context - - The context values (the context parameter to the ActionLink component) can be any object. - However, only a simple conversion to string occurs. This is in contrast to Tapestry 4, which had - an elaborate type mechanism with the odd name "DataSqueezer". - - Again, whatever your value is (string, number, date), it is converted into a plain string. - This results in a more readable URL. - - If you have multiple context values (by binding a list or array of objects to the ActionLink's - context parameter), then each one, in order, will be added to the URL. - - When an event handler method is invoked, the strings are converted back into - values, or even objects. A - {{{../apidocs/org/apache/tapestry5/ValueEncoder.html}ValueEncoder}} is used to convert between client-side strings - and server-side objects. The {{{../apidocs/org/apache/tapestry5/services/ValueEncoderSource.html}ValueEncoderSource}} service - provides the necessary value encoders. - -* Method Matching - - An event handler method will only be invoked - <if the context contains at least as many values as the method has parameters>. Methods with too many parameters - will be silently skipped. - -* Collections - - To designate that an event handler method should be invoked regardless of how many context parameters are available, - change the method to accept a <single> parameter of type Object[], type List, or type - {{{../apidocs/org/apache/tapestry5/EventContext.html}EventContext}}. - -Event Bubbling - - The event will bubble up the hierarchy, until it is aborted. The event is aborted - when an event handler method returns a non-null value. - - Returning a boolean value from an event handler method is special. Returning true will abort the event - with no result; use this when the event is fully handled without a return value and no further event handlers - (in the same component, or in containing components) should be invoked. - - Returning false is the same as returning null. - -Event Method Exceptions - - Event methods are allowed to throw any exception (not just runtime exceptions). If an event method does - throw an exception, Tapestry will catch the thrown exception and ultimately display the exception report - page. - - In other words, there's no need to do this: - -+---+ - void onActionFromRunQuery() - { - try - { - dao.executeQuery(); - } - catch (JDBCException ex) - { - throw new RuntimeException(ex); - } - } -+---+ - - Instead, you may simply say: - -+---+ - void onActionFromRunQuery() throws JDBCException - { - dao.executeQuery(); - } -+----+ - - - Your event handler method may even declare that it "throws Exception" if that is more convienient. - - -Intercepting Event Exceptions - - When an event handler method throws an exception (checked or runtime), Tapestry gives the component and - its containing page a chance to handle the exception, before continuing on to - report the exception. - - Tapestry fires a new event, of type "exception", passing the thrown exception as the context. In fact, - the exception is wrapped inside a - {{{../apidocs/org/apache/tapestry5/runtime/ComponentEventException.html}ComponentEventException}}, from which - you may extract the event type and context. - - Thus: - ---- - Object onException(Throwable cause) - { - message = cause.getMessage(); - - return this; - } ---- - - The return value of the exception event handler <replaces> the return value of original event handler method. - For the typical case (an exception thrown by an "activate" or "action" event), this will be - a {{{pagenav.html}navigational response}} such as a page instance or page name. - - This can be handy for handling cases where the data in the URL is misformatted. - - In the above example, the navigational response is the page itself. - - If there is no exception event handler, or the exception event handler returns null (or is void), then - then the exception will be passed to the - {{{../apidocs/org/apache/tapestry5/services/RequestExceptionHandler.html}RequestExceptionHandler}} service, + --- + Component Events + --- + +Component Events + + Component events are the means by which components are made aware of behaviors by the user, such + as clicking links and submitting forms. + + Component events are used for two purposes: + + * They represent requests initiated by the user, triggered by links and forms in the client web browser. + These are described more fully in {{{pagenav.html}page navigation}} and in + {{{request.html}requst processing}}. + + * They represent flow-of-control within a request, allowing one component to notify its container + about some kind of circumstance ("a form was submitted"), or to collect some piece for data + from the container. + + [] + + Often, a navigation request (originating with the user) will spawn a number of flow-of-control + requests. For example, a Form component will be triggered by an action request, and will then + send notification events to announce when the form submission is about to be processed, and + whether it was succesful or not. + + In Tapestry 4, you would configure a parameter of a component with the name of a method to invoke + when a certain event occured, usually a request from the client. + + This has some limitations, including the fact that only a single method could be invoked, and that + it tied together a component and a method based on a method name, which required careful coordination + between the template and the Java code. + + Tapestry 5 introduces the concept of <event handler methods>, identified via a naming convention, or + via the + {{{../apidocs/org/apache/tapestry5/annotations/OnEvent.html}OnEvent annotation}}. Event handler methods + may have any visibility, even private. Normally they are given package private visibility, to support testing. + + Rather than configure a component to invoke a particular method, you identify one or more + methods to listen for events from that component. A single event handler method may receive notifications from + many different components. + + For example, here's a portion of a page (let's call it "Chooser") that lets the user choose a number between 1 and 10: + ++---+ +<p> Choose a number from 1 to 10: </p> + +<p> + <t:count end="10" value="index"> + <a t:id="select" t:type="actionlink" context="index">${index}</t:comp> + </t:count> +</p> ++---+ + + The ActionLink component creates an action URL. + + The URL identifies the page that contains the component ("chooser"), the type of event + (unless it is "action", the default and most common event type), + the id of the component within the page ("select"), plus the additional context value(s). + + A sample URL: <<<http://localhost:8080/chooser.select/3>>>. + + When there are additional context values, they are appended to the path. + + This demonstrates a critical difference between Tapestry and a more traditional, action oriented framework. + This URL doesn't say what happens when the link is clicked, it identifies <which component is responsible> + when the link is clicked. + + There's no simple mapping from URL to a piece of code; instead the component sends notifications, in the form + of invocations of event handler methods, and Tapestry ensures that the correct bit of code, code that you supply, + gets invoked. + + + A Java method can be invoked when the link for the component is clicked by the user: + ++---+ + @OnEvent(component = "select") + void valueChosen(int value) + { + this.value = value; + } ++---+ + + Tapestry has done two things here: + + * It has identified method valueChosen() as the method to invoke. + + * It has converted the context value from a string to an integer and passed it into the method. + + [] + + In the above example, the valueChosen() method will be invoked on the default event, "action", that originates + in component <<<select>>> (and has at least one context value). + + Some components can emit more than one type of event, in which case you will want to be more specific: + ++---+ + @OnEvent(value = "action", component = "select") + void valueChosen(int value) + { + this.value = value; + } ++---+ + + The value attribute of the OnEvent annotation is the name of the event to match. + + "action" is the name of the default event type; the ActionLink and Form components each use this event type. + If you omit the component part of the OnEvent annotation, then you'll recieve notifications from + <all> contained components, possibly including nested components (due to event bubbling). + + As elsewhere, the comparison of event type and component id is caseless. + + You should qualify exactly which component(s) you wish to recieve events from. Using @OnEvent on a method + and not specifying a specific component id means that the method will be invoked for events from <any> component. + +Event Handler Method Convention Names + + As an alternative to the use of annotations, you may name your events in a specific fashion, and Tapestry will invoke your methods just as if + they were annotated. + + This style of event handler methods start with the prefix "on", followed by the name of the action. You may then continue by adding "From" and + a capitalized component id (remember that Tapestry is case insensitive about event names and component ids). + + The previous example may be rewritten as: + ++---+ + void onActionFromSelect(int value) + { + this.value = value; + } ++---+ + + Note from Howard: I've found that I prefer the naming convention approach, and reserve the annotation just for situations that don't otherwise fit. + +Event Handler Method Return Values + + For page navigation events (originating in components such as ActionLink and Form), + the value returned from an event handler method {{{pagenav.html}determines how Tapestry will render a response}}. + +Multiple Method Matches + + In some cases, you may have multiple event methods match a single event. + + The order is as follows: + + * Base class methods before sub-class methods. + + * Matching methods within a class in alphabetical order. + + * For a single method name with multiple overrides, by number of parameters, descending. + + [] + + There's only rare cases where it makes sense for more than one method to handle an event. + + When a sub-class overrides an event handler method of a base class, the event handler method is only invoked once, along with + any other base class methods. The subclass can change the <implementation> of the base class method via an override, but + can't change the <timing> of when that method is invoked. See {{{https://issues.apache.org/jira/browse/TAPESTRY-2311}TAPESTRY-2311}}. + +Event Context + + The context values (the context parameter to the ActionLink component) can be any object. + However, only a simple conversion to string occurs. This is in contrast to Tapestry 4, which had + an elaborate type mechanism with the odd name "DataSqueezer". + + Again, whatever your value is (string, number, date), it is converted into a plain string. + This results in a more readable URL. + + If you have multiple context values (by binding a list or array of objects to the ActionLink's + context parameter), then each one, in order, will be added to the URL. + + When an event handler method is invoked, the strings are converted back into + values, or even objects. A + {{{../apidocs/org/apache/tapestry5/ValueEncoder.html}ValueEncoder}} is used to convert between client-side strings + and server-side objects. The {{{../apidocs/org/apache/tapestry5/services/ValueEncoderSource.html}ValueEncoderSource}} service + provides the necessary value encoders. + +* Method Matching + + An event handler method will only be invoked + <if the context contains at least as many values as the method has parameters>. Methods with too many parameters + will be silently skipped. + +* Collections + + To designate that an event handler method should be invoked regardless of how many context parameters are available, + change the method to accept a <single> parameter of type Object[], type List, or type + {{{../apidocs/org/apache/tapestry5/EventContext.html}EventContext}}. + +Event Bubbling + + The event will bubble up the hierarchy, until it is aborted. The event is aborted + when an event handler method returns a non-null value. + + Returning a boolean value from an event handler method is special. Returning true will abort the event + with no result; use this when the event is fully handled without a return value and no further event handlers + (in the same component, or in containing components) should be invoked. + + Returning false is the same as returning null. + +Event Method Exceptions + + Event methods are allowed to throw any exception (not just runtime exceptions). If an event method does + throw an exception, Tapestry will catch the thrown exception and ultimately display the exception report + page. + + In other words, there's no need to do this: + ++---+ + void onActionFromRunQuery() + { + try + { + dao.executeQuery(); + } + catch (JDBCException ex) + { + throw new RuntimeException(ex); + } + } ++---+ + + Instead, you may simply say: + ++---+ + void onActionFromRunQuery() throws JDBCException + { + dao.executeQuery(); + } ++----+ + + + Your event handler method may even declare that it "throws Exception" if that is more convienient. + + +Intercepting Event Exceptions + + When an event handler method throws an exception (checked or runtime), Tapestry gives the component and + its containing page a chance to handle the exception, before continuing on to + report the exception. + + Tapestry fires a new event, of type "exception", passing the thrown exception as the context. In fact, + the exception is wrapped inside a + {{{../apidocs/org/apache/tapestry5/runtime/ComponentEventException.html}ComponentEventException}}, from which + you may extract the event type and context. + + Thus: + +--- + Object onException(Throwable cause) + { + message = cause.getMessage(); + + return this; + } +--- + + The return value of the exception event handler <replaces> the return value of original event handler method. + For the typical case (an exception thrown by an "activate" or "action" event), this will be + a {{{pagenav.html}navigational response}} such as a page instance or page name. + + This can be handy for handling cases where the data in the URL is misformatted. + + In the above example, the navigational response is the page itself. + + If there is no exception event handler, or the exception event handler returns null (or is void), then + then the exception will be passed to the + {{{../apidocs/org/apache/tapestry5/services/RequestExceptionHandler.html}RequestExceptionHandler}} service, which (in default configuraton) will be render the exception page. \ No newline at end of file
Propchange: tapestry/tapestry5/trunk/src/site/apt/guide/event.apt ------------------------------------------------------------------------------ svn:eol-style = native Modified: tapestry/tapestry5/trunk/src/site/apt/guide/inject.apt URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/src/site/apt/guide/inject.apt?rev=753411&r1=753410&r2=753411&view=diff ============================================================================== --- tapestry/tapestry5/trunk/src/site/apt/guide/inject.apt (original) +++ tapestry/tapestry5/trunk/src/site/apt/guide/inject.apt Fri Mar 13 21:11:16 2009 @@ -1,136 +1,136 @@ - ---- - Injection with Components - ---- - -Injection with Components - - A key concept in Tapestry is the use of <injection>. The - {{{../../tapestry-ioc/index.html}Tapestry IoC container}} makes use of one form - of injection, via parameters to service builder methods. - - For components, Tapestry takes a completely different tack: injection directly into - instance variables. - -Inject Annotation - - The {{{../apidocs/org/apache/tapestry5/ioc/annotations/Inject.html}Inject annotation}} is used to identify fields that will contain injected services and other resources. - - Tapestry allows for two kinds of injection: - - * Explicit injection, where the particular service to be injected is specified. - - * Default injection, where Tapestry determines the object to inject into the field based on its type. - - [] - - - In both cases, the field is transformed into a read only value. As elsewhere in Tapestry, this transformation occurs - at runtime (which is very important in terms of being able to test your components). - Attempting to update an injected field will result in a runtime exception. - - In addition, there are a few special cases that are triggered by specific field types, or additional annotations, - in addition, to Inject, on a field. - -* Asset Injection - - When the - {{{../apidocs/org/apache/tapestry5/annotations/Path.html}Path}} annotation is also present, then the injected value - (relative to the component) will be a localized {{{assets.html}asset}}. - - Symbols in the annotation value are expanded. - -* Block Injection - - For field type {{{../apidocs/org/apache/tapestry5/Block.html}Block}}, the value of the Inject annotation is the - id of the {{{templates.apt}\<block\> element}} within the component's template. Normally, the id of the block is determined from the field name - (after stripping out leading "_" and "$" characters). Where that is not appropriate, an - {{{../apidocs/org/apache/tapestry5/annotations/Id.html}Id}} annotation can be supplied: - -+---+ - @Inject - private Block foo; - - @Inject - @Id("bar") - private Block barBlock; -+---+ - - The first injection will inject the Block with id "foo" (as always, case is ignored). The second injection will inject the Block with id "bar". - - -* Resource Injection - - For a particular set of field types, Tapestry will inject a <resource> related to the component, such as its Locale. - - A very common example occurs when a component needs access to its - {{{../apidocs/org/apache/tapestry5/ComponentResources.html}resources}}. The component - can define a field of the appropriate type - and use the Inject annotation without a value: - -+----+ -...@inject -private ComponentResources resources; -+----+ - - Tapestry uses the type of the field, ComponentResources, to determine what to inject into this field. - - The following types are supported for resources injection: - - [java.lang.String] - The complete id of the component, which incorporates the complete class name of the containing page and the nested - id of the component within the page. - - [java.util.Locale] - The locale for the component (all components within a page use the same locale). - - [org.slf4j.Logger] - A Logger instance configured for the component, based on the component's class name. - {{{http://www.slf4j.org/}SLF4J}} is a wrapper around Log4J or other logging toolkits. - - [org.apache.tapestry5.ComponentResources] - The resources for the component, often used to generate links related to the component. - - [org.apache.tapestry5.ioc.Messages] - The component message catalog for the component, from which - {{{localization.html}localized}} messages can be generated. - - -Explicit Service Injection - - Here, a specific object is requested. A {{{../apidocs/org/apache/tapestry5/annotations/Service.html}Service}} annotation - is used to identify the service name. - - Example: - -+----+ -...@inject -...@service("Request") -private Request request; -+----+ - - This is generally not necessary; you should always be able to identify the service to be injected just by type, not - by explicit id. Explicit ids have the disadvantage of not being refactoring-safe: this won't happen with the Request service, - but perhaps in your own ... if you rename the service interface and rename the service id to match, your existing - injections using the explicit service id will break. - -Default Injection - - When the type and/or other annotations are not sufficient to identify the object or service to inject, Tapestry falls back on two remaining steps. It assumes - that the field type will be used to identify a service, by the service interface. - - First, the object provider created by the Alias service is consulted. This object provider is used to disambiguate injections when there is more - than one service that implements the same service interface. - - Second, a search for a unique service that implements the interface occurs. This will fail if either there are no services that implement the interface, - or there is more than one. In the latter case, you must disambiguate, either with a contribution to the Alias service, or by explicitly - identifying the service with the @Service annotation. - - -Defining New Injection Logic - - Annonymous injection is controlled by the - {{{../apidocs/org/apache/tapestry5/services/InjectionProvider.html}InjectionProvider}} - service. The configuration for this service is a - {{{../../tapestry-ioc/command.html}chain of command}} for handling component injections. - + ---- + Injection with Components + ---- + +Injection with Components + + A key concept in Tapestry is the use of <injection>. The + {{{../../tapestry-ioc/index.html}Tapestry IoC container}} makes use of one form + of injection, via parameters to service builder methods. + + For components, Tapestry takes a completely different tack: injection directly into + instance variables. + +Inject Annotation + + The {{{../apidocs/org/apache/tapestry5/ioc/annotations/Inject.html}Inject annotation}} is used to identify fields that will contain injected services and other resources. + + Tapestry allows for two kinds of injection: + + * Explicit injection, where the particular service to be injected is specified. + + * Default injection, where Tapestry determines the object to inject into the field based on its type. + + [] + + + In both cases, the field is transformed into a read only value. As elsewhere in Tapestry, this transformation occurs + at runtime (which is very important in terms of being able to test your components). + Attempting to update an injected field will result in a runtime exception. + + In addition, there are a few special cases that are triggered by specific field types, or additional annotations, + in addition, to Inject, on a field. + +* Asset Injection + + When the + {{{../apidocs/org/apache/tapestry5/annotations/Path.html}Path}} annotation is also present, then the injected value + (relative to the component) will be a localized {{{assets.html}asset}}. + + Symbols in the annotation value are expanded. + +* Block Injection + + For field type {{{../apidocs/org/apache/tapestry5/Block.html}Block}}, the value of the Inject annotation is the + id of the {{{templates.apt}\<block\> element}} within the component's template. Normally, the id of the block is determined from the field name + (after stripping out leading "_" and "$" characters). Where that is not appropriate, an + {{{../apidocs/org/apache/tapestry5/annotations/Id.html}Id}} annotation can be supplied: + ++---+ + @Inject + private Block foo; + + @Inject + @Id("bar") + private Block barBlock; ++---+ + + The first injection will inject the Block with id "foo" (as always, case is ignored). The second injection will inject the Block with id "bar". + + +* Resource Injection + + For a particular set of field types, Tapestry will inject a <resource> related to the component, such as its Locale. + + A very common example occurs when a component needs access to its + {{{../apidocs/org/apache/tapestry5/ComponentResources.html}resources}}. The component + can define a field of the appropriate type + and use the Inject annotation without a value: + ++----+ +...@inject +private ComponentResources resources; ++----+ + + Tapestry uses the type of the field, ComponentResources, to determine what to inject into this field. + + The following types are supported for resources injection: + + [java.lang.String] + The complete id of the component, which incorporates the complete class name of the containing page and the nested + id of the component within the page. + + [java.util.Locale] + The locale for the component (all components within a page use the same locale). + + [org.slf4j.Logger] + A Logger instance configured for the component, based on the component's class name. + {{{http://www.slf4j.org/}SLF4J}} is a wrapper around Log4J or other logging toolkits. + + [org.apache.tapestry5.ComponentResources] + The resources for the component, often used to generate links related to the component. + + [org.apache.tapestry5.ioc.Messages] + The component message catalog for the component, from which + {{{localization.html}localized}} messages can be generated. + + +Explicit Service Injection + + Here, a specific object is requested. A {{{../apidocs/org/apache/tapestry5/annotations/Service.html}Service}} annotation + is used to identify the service name. + + Example: + ++----+ +...@inject +...@service("Request") +private Request request; ++----+ + + This is generally not necessary; you should always be able to identify the service to be injected just by type, not + by explicit id. Explicit ids have the disadvantage of not being refactoring-safe: this won't happen with the Request service, + but perhaps in your own ... if you rename the service interface and rename the service id to match, your existing + injections using the explicit service id will break. + +Default Injection + + When the type and/or other annotations are not sufficient to identify the object or service to inject, Tapestry falls back on two remaining steps. It assumes + that the field type will be used to identify a service, by the service interface. + + First, the object provider created by the Alias service is consulted. This object provider is used to disambiguate injections when there is more + than one service that implements the same service interface. + + Second, a search for a unique service that implements the interface occurs. This will fail if either there are no services that implement the interface, + or there is more than one. In the latter case, you must disambiguate, either with a contribution to the Alias service, or by explicitly + identifying the service with the @Service annotation. + + +Defining New Injection Logic + + Annonymous injection is controlled by the + {{{../apidocs/org/apache/tapestry5/services/InjectionProvider.html}InjectionProvider}} + service. The configuration for this service is a + {{{../../tapestry-ioc/command.html}chain of command}} for handling component injections. + \ No newline at end of file Propchange: tapestry/tapestry5/trunk/src/site/apt/guide/inject.apt ------------------------------------------------------------------------------ svn:eol-style = native Propchange: tapestry/tapestry5/trunk/src/site/apt/guide/layout.apt ------------------------------------------------------------------------------ svn:eol-style = native Propchange: tapestry/tapestry5/trunk/src/site/apt/guide/lifecycle.apt ------------------------------------------------------------------------------ svn:eol-style = native Propchange: tapestry/tapestry5/trunk/src/site/apt/guide/localization.apt ------------------------------------------------------------------------------ svn:eol-style = native Propchange: tapestry/tapestry5/trunk/src/site/apt/guide/logging.apt ------------------------------------------------------------------------------ svn:eol-style = native Modified: tapestry/tapestry5/trunk/src/site/apt/guide/mixins.apt URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/src/site/apt/guide/mixins.apt?rev=753411&r1=753410&r2=753411&view=diff ============================================================================== --- tapestry/tapestry5/trunk/src/site/apt/guide/mixins.apt (original) +++ tapestry/tapestry5/trunk/src/site/apt/guide/mixins.apt Fri Mar 13 21:11:16 2009 @@ -1,136 +1,136 @@ - --- - Component Mixins - --- - -Component Mixins - - Tapestry 5 includes a radical feature, <component mixins>. Component mixins are a tricky concept; it basically allows - a true component to be mixed together with special limited components called mixins. The component plus its mixins are - represented as just a single tag in the component template, but all the behavior of all the elements. - - The planned uses for this are to add validation to user input fields, or to add Ajax effects and behaviors to all - sorts of components. - - You can think of a mixin as a kind of mashup for a component; it combines the behavior of the component - with the behavior of the mixin, and bundles it all in one place. - - Mixins are used in two different scenarios: <Instance mixins> and <Implementation mixins>. - -Mixin Classes - - Mixin classes are stored in a <<<mixins>>> sub-package, below the application (or library) - root package. This parallels where component and page classes are stored. - - Other than that, mixin classes are exactly the same as any other component class. - -Mixin Limitations - - Currently, mixins are allowed to do anything a component can do, including parameters, - render phase methods. - - Mixins may not have a template. They integrate with the component strictly in terms of invoking - render phase methods. - - Mixins may have persistent fields, but currently, this is not implemented perfectly (there is a potential - for a name clash between a mixin and the component or another mixin). Use persistent fields with - mixins with care ... or better yet, delegate persistence to the container using parameters. - - Mixins may not, themselves, have mixins. - - -Instance Mixins - - An instance mixin is a mixin applied to a specific <instance> of a component. This can be done - in the {{{templates.html}component template}} with the mixins attribute of the - \<comp\> element. This is a comma-separated list of mixin names. - - Alternately, when the {{{../apidocs/org/apache/tapestry5/annotations/Component.html}Component annotation}} - is used to define the component type, you may specify the mixins in two ways: - - * The {{{../apidocs/org/apache/tapestry5/annotations/Mixins.html}Mixins annotation}} allows a list - of mixin names to be specified. - - * The {{{../apidocs/org/apache/tapestry5/annotations/MixinClasses.html}MixinClasses annotation}} - allows a set of mixin class to be specified directly. - - [] - - The former is often less verbose, and allows core mixins to be overridden with application-specific - mixins. The later format is more specific and more friendly in terms of refactoring (renaming a - mixin class will rename the entry in the MixinClasses annotation as well). - - Example: - -+----+ - - @Component(parameters=. . .) @Mixins({"Autocomplete", "DefaultFromCookie"}) - private TextField userId; -+----+ - - This example defines a component of type TextField and mixes in the <hypothetical> Autocomplete - and DefaultFromCookie mixins. - - -Implementation Mixins - - Implementation mixins, mixins which apply to all isntances of a component, are added using the - {{{../apidocs/org/apache/tapestry5/annotations/Mixin.html}Mixin annotation}}. This annotation - defines a field that will containg the mixin instance. - -+---+ -public class AutocompleteField extendes TextField -{ - @Mixin - private Autocomplete autocompleteMixin; - - . . . -} -+---+ - - Often, the type of the field is the exact mixin class to be instantiated. - - In other cases, such as when the field's type is an interface or a base class, the value - attribute of the annotation will be used to determine the mixin class name: - -+---+ -public class AutocompleteField extendes TextField -{ - @Mixin("Autocomplete") - private Object autocompleteMixin; - - . . . -} -+---+ - -Mixin Parameters - - Mixins are allowed to have parameters, just like components. - - When binding parameters (either in the template, or using the parameters attribute - of the Component annotation). - - Tapestry will match each parameter name against the parameters defined by each class - (which is to say, the component and each mixin). - - If the component and a mix both define a parameter with the same name, then the component wins: - the component's parameter will be bound, and the mixin's parameter will be unbound. - - Alternately, you may prefix the name of the parameter with the <unqualified> name of the Mixin class; - this eliminates the ambiguity. Example: - -+-----+ - @Component(parameters={"Autocomplete.id=auto", . . . }) @Mixins("Autocomplete", "DefaultFromCookie"}) - private TextField userId; -+-----+ - - -Render Phase Ordering - - All mixins for a component execute their render phase methods <before> the component's render phase - methods for most phases. However, in the later phases (AfterRender, CleanupRender) the order of executing - is reversed. - - Exception: Mixins whose class is annotated with - {{{../apidocs/org/apache/tapestry5/annotations/MixinAfter.html}MixinAfter}} are ordered - <after> the component, not before. + --- + Component Mixins + --- + +Component Mixins + + Tapestry 5 includes a radical feature, <component mixins>. Component mixins are a tricky concept; it basically allows + a true component to be mixed together with special limited components called mixins. The component plus its mixins are + represented as just a single tag in the component template, but all the behavior of all the elements. + + The planned uses for this are to add validation to user input fields, or to add Ajax effects and behaviors to all + sorts of components. + + You can think of a mixin as a kind of mashup for a component; it combines the behavior of the component + with the behavior of the mixin, and bundles it all in one place. + + Mixins are used in two different scenarios: <Instance mixins> and <Implementation mixins>. + +Mixin Classes + + Mixin classes are stored in a <<<mixins>>> sub-package, below the application (or library) + root package. This parallels where component and page classes are stored. + + Other than that, mixin classes are exactly the same as any other component class. + +Mixin Limitations + + Currently, mixins are allowed to do anything a component can do, including parameters, + render phase methods. + + Mixins may not have a template. They integrate with the component strictly in terms of invoking + render phase methods. + + Mixins may have persistent fields, but currently, this is not implemented perfectly (there is a potential + for a name clash between a mixin and the component or another mixin). Use persistent fields with + mixins with care ... or better yet, delegate persistence to the container using parameters. + + Mixins may not, themselves, have mixins. + + +Instance Mixins + + An instance mixin is a mixin applied to a specific <instance> of a component. This can be done + in the {{{templates.html}component template}} with the mixins attribute of the + \<comp\> element. This is a comma-separated list of mixin names. + + Alternately, when the {{{../apidocs/org/apache/tapestry5/annotations/Component.html}Component annotation}} + is used to define the component type, you may specify the mixins in two ways: + + * The {{{../apidocs/org/apache/tapestry5/annotations/Mixins.html}Mixins annotation}} allows a list + of mixin names to be specified. + + * The {{{../apidocs/org/apache/tapestry5/annotations/MixinClasses.html}MixinClasses annotation}} + allows a set of mixin class to be specified directly. + + [] + + The former is often less verbose, and allows core mixins to be overridden with application-specific + mixins. The later format is more specific and more friendly in terms of refactoring (renaming a + mixin class will rename the entry in the MixinClasses annotation as well). + + Example: + ++----+ + + @Component(parameters=. . .) @Mixins({"Autocomplete", "DefaultFromCookie"}) + private TextField userId; ++----+ + + This example defines a component of type TextField and mixes in the <hypothetical> Autocomplete + and DefaultFromCookie mixins. + + +Implementation Mixins + + Implementation mixins, mixins which apply to all isntances of a component, are added using the + {{{../apidocs/org/apache/tapestry5/annotations/Mixin.html}Mixin annotation}}. This annotation + defines a field that will containg the mixin instance. + ++---+ +public class AutocompleteField extendes TextField +{ + @Mixin + private Autocomplete autocompleteMixin; + + . . . +} ++---+ + + Often, the type of the field is the exact mixin class to be instantiated. + + In other cases, such as when the field's type is an interface or a base class, the value + attribute of the annotation will be used to determine the mixin class name: + ++---+ +public class AutocompleteField extendes TextField +{ + @Mixin("Autocomplete") + private Object autocompleteMixin; + + . . . +} ++---+ + +Mixin Parameters + + Mixins are allowed to have parameters, just like components. + + When binding parameters (either in the template, or using the parameters attribute + of the Component annotation). + + Tapestry will match each parameter name against the parameters defined by each class + (which is to say, the component and each mixin). + + If the component and a mix both define a parameter with the same name, then the component wins: + the component's parameter will be bound, and the mixin's parameter will be unbound. + + Alternately, you may prefix the name of the parameter with the <unqualified> name of the Mixin class; + this eliminates the ambiguity. Example: + ++-----+ + @Component(parameters={"Autocomplete.id=auto", . . . }) @Mixins("Autocomplete", "DefaultFromCookie"}) + private TextField userId; ++-----+ + + +Render Phase Ordering + + All mixins for a component execute their render phase methods <before> the component's render phase + methods for most phases. However, in the later phases (AfterRender, CleanupRender) the order of executing + is reversed. + + Exception: Mixins whose class is annotated with + {{{../apidocs/org/apache/tapestry5/annotations/MixinAfter.html}MixinAfter}} are ordered + <after> the component, not before. \ No newline at end of file Propchange: tapestry/tapestry5/trunk/src/site/apt/guide/mixins.apt ------------------------------------------------------------------------------ svn:eol-style = native Propchange: tapestry/tapestry5/trunk/src/site/apt/guide/pagenav.apt ------------------------------------------------------------------------------ svn:eol-style = native