| <?xml version="1.0" encoding="UTF-8"?> |
| <!-- |
| Copyright 2005 The Apache Software Foundation |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| --> |
| <document> |
| <properties> |
| <title>Property Injection</title> |
| </properties> |
| <body> |
| |
| <section name="Property Injection"> |
| <p> |
| Tapestry 4.0 introduces an entirely new concept into Tapestry application |
| development: property injection. By use of the |
| <a href="spec.html#spec.inject"><inject></a> |
| element in page and component specifications, it is possible to add new properties |
| to pages or components, using the |
| <a href="spec.html#spec.inject"><inject></a> |
| element in the page or component specification. |
| </p> |
| |
| <p> |
| The new properties that are created often are more than just wrappers around an |
| instance variable; in many cases they create complex synthetic accessor methods. |
| </p> |
| |
| <p> |
| There are different |
| <em>types</em> |
| of injected properties, defined by the type attribute of the |
| <a href="spec.html#spec.inject"><inject></a> |
| element. The type determines how the object attribute is interpreted, and otherwise |
| guides how code for the property is generated at runtime. The default type is |
| <strong>object</strong> |
| . |
| </p> |
| |
| <p> |
| Like so much in Tapestry, this list is open to extension. The |
| <a href="../tapestry-framework/hivedoc/config/tapestry.enhance.InjectWorkers.html"> |
| tapestry.enhance.InjectWorkers |
| </a> |
| configuration point defines the available types of injection. The |
| <a href="../tapestry-framework/hivedoc/config/tapestry.enhance.EnhancementWorkers.html"> |
| tapestry.enhance.EnhancementWorkers |
| </a> |
| configuration point defines an entire pipeline used to perform runtime code |
| enhancement (of which property injection is a critical phase). |
| </p> |
| |
| <p> |
| In addition, many other elements support a property attribute; this is the name of a |
| property to create that holds the corresponding object. For example, the |
| <a href="spec.html#spec.bean"><bean></a> |
| element's property allows access to a managed bean; the bean is |
| <em>still</em> |
| created on first reference. Components and assets may also be injected in this way. |
| </p> |
| |
| |
| <subsection name="meta injection"> |
| |
| |
| <p> |
| The meta injection type provides a page or component with access to its meta |
| data. Meta data for a component is primarily provided as |
| <a href="spec.html#spec.meta"><meta></a> |
| tags in the component or page specification. |
| </p> |
| |
| <p> |
| However, meta-data may be specified elsewhere; the search starts in the |
| component (or page) specification, but if not defined there, the search |
| continues inside the component's namespace (its application or library |
| specification). If no value is found there, the search continues in the list of |
| application property sources. In other words, there are multiple places to set |
| defaults, which can be overridden. |
| </p> |
| |
| <p> |
| Beyond wide searching, the other added value for the meta property injection is |
| <em>type coercion</em> |
| . Meta data always starts as simple strings, but your properties may be of any |
| type. Tapestry will attempt to coerce the string value to your desired type. |
| </p> |
| |
| <p> |
| For example, perhaps you want to use meta-data to control the number of items |
| from some large list that is displayed on a single page. You can define the |
| meta-data, and the property in your page or component specification: |
| </p> |
| |
| <source xml:space="preserve"> |
| |
| <meta key="page.size" value="15"/> |
| |
| <inject property="pageSize" type="meta" object="page.size"/> |
| |
| </source> |
| |
| <p>You can access the this meta data value in code by defining a property:</p> |
| |
| <source xml:space="preserve"> |
| |
| public abstract int getPageSize(); |
| |
| </source> |
| |
| </subsection><!-- injection.meta --> |
| |
| <subsection name="object injection"> |
| |
| |
| <p> |
| The most common kind of injection, because "object" is the default injection |
| type. The object is a HiveMind object. The |
| <a href="hivemind.html">HiveMind integration documentation</a> |
| covers this type of injection in more detail. |
| </p> |
| |
| <p> |
| |
| </p> |
| |
| </subsection><!-- injection.object --> |
| |
| <subsection name="page injection"> |
| |
| |
| <p> |
| Page injection allows a page to be injected into another page (or component). |
| Beneather the covers, the logic simply accesses the |
| <a |
| href="../apidocs/org/apache/tapestry/IRequestCycle.html"> |
| IRequestCycle |
| </a> |
| object and obtains the page from it, and adds a cast if necessary. |
| </p> |
| |
| <p> |
| The property type can be Object, |
| <a href="../apidocs/org/apache/tapestry/IPage.html">IPage</a> |
| , or any type assignable to |
| <a href="../apidocs/org/apache/tapestry/IPage.html">IPage</a> |
| . |
| </p> |
| |
| <p> |
| This is often used with |
| <a href="listenermethods.html">listener method</a> |
| s. For example: |
| </p> |
| |
| <source xml:space="preserve"> |
| <inject property="detailsPage" type="page" object="Details"/> |
| </source> |
| |
| <source xml:space="preserve"> |
| public abstract Details getDetailsPage(); |
| |
| public IPage doShowDetails(long productId) |
| { |
| Details details = getDetailsPage(); |
| |
| details.setProductId(productId); |
| |
| return details; |
| } |
| </source> |
| |
| <p> |
| This is a common idiom: getting a page and casting it to its real type, invoking |
| methods upon it, then returning it (from the listener method), so that it is |
| activated to render the response. |
| </p> |
| |
| </subsection><!-- injection.page --> |
| |
| <subsection name="script injection"> |
| |
| |
| <p> |
| Tapestry includes extensive support for creating client-side JavaScript. At the |
| core of this are specialized script templates. These templates must be parsed |
| into |
| <a href="../apidocs/org/apache/tapestry/IScript.html"> |
| IScript |
| </a> |
| objects in order to be used. The script injection type hides the details of this |
| process, and simply represents the parsed script template as a read-only |
| property. |
| </p> |
| |
| <p> |
| The object is the relative path to the script template; it is evaluated relative |
| to the page or component specification (typically, it is another file in the |
| same folder). |
| </p> |
| |
| <p>This example is from the Palette component:</p> |
| |
| <source xml:space="preserve"> |
| <inject property="script" type="script" object="Palette.script"/> |
| </source> |
| |
| <p>The script can then be executed from the Java code:</p> |
| |
| <source xml:space="preserve"> |
| public abstract IScript getScript(); |
| |
| . . . |
| |
| PageRenderSupport pageRenderSupport = TapestryUtils.getPageRenderSupport(cycle, this); |
| |
| getScript().execute(cycle, pageRenderSupport, _symbols); |
| </source> |
| |
| </subsection><!-- injection.script --> |
| |
| <subsection name="state injection"> |
| |
| |
| <p> |
| This style of injection allows easy access to |
| <a href="state.html#state.aso">Application State Objects</a> |
| , objects which store various kinds of global information (information needed on |
| many pages). |
| </p> |
| |
| </subsection> |
| |
| <subsection name="state-flag injection"> |
| |
| |
| <p> |
| Using the |
| <a href="#injection.state">state</a> |
| injection can force the creation of an application state object; this type of |
| injection will create a |
| <em>read only</em> |
| boolean property that indicates |
| <em>if</em> |
| an application state object already exists. |
| </p> |
| |
| <p> |
| This is used to |
| <em>prevent</em> |
| the creation of an application state object until it is absolutely needed. |
| </p> |
| |
| <p> |
| For example; in a situtation where the user may or may not be logged in, you |
| would inject a state flag and the state in two properties and check the state |
| flag |
| <em>first</em> |
| : |
| </p> |
| |
| <source xml:space="preserve"> |
| // <inject> type state-flag in the XML |
| public abstract boolean getUserIdentityExists(); |
| |
| // <inject> type state in the XML |
| public abstract WizardState getUserIdentity(); |
| |
| public void doOperation() |
| { |
| if (getUserIdentityExists() && getUserIdentity().isLoggedIn()) |
| { |
| . . . |
| } |
| else |
| { |
| . . . |
| } |
| } |
| </source> |
| </subsection><!-- injection.state-flag --> |
| </section> |
| </body> |
| </document> |