You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by jk...@apache.org on 2006/07/03 02:17:31 UTC

svn commit: r418665 [3/6] - in /tapestry/tapestry4/trunk: src/documentation/content/xdocs/ src/documentation/content/xdocs/QuickStart/ src/documentation/content/xdocs/UsersGuide/ src/documentation/content/xdocs/examples/ src/site/ src/site/resources/im...

Added: tapestry/tapestry4/trunk/src/site/xdoc/UsersGuide/friendly-urls.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/src/site/xdoc/UsersGuide/friendly-urls.xml?rev=418665&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/src/site/xdoc/UsersGuide/friendly-urls.xml (added)
+++ tapestry/tapestry4/trunk/src/site/xdoc/UsersGuide/friendly-urls.xml Sun Jul  2 17:17:29 2006
@@ -0,0 +1,455 @@
+<?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>Configuring Friendly URLs</title>
+</properties>
+<body>
+    
+    <p>
+    Earlier versions of Tapestry have had a long-standing tradition of
+    <em>really ugly URLs</em>. Because the framework generates the URLs and
+    is also responsible for parsing and dispatching on them in later requests, it was
+    not seen as an issue.
+    </p>
+    
+    <p>
+    In fact, the ugly URLs <em>do</em> cause some problems:
+    </p>
+    
+    <ul>
+      <li>Since all requests are routed through a single  servlet
+        (typically mapped to <code>/app</code>), J2EE declarative security, which is path-based,
+        is defeated.</li>
+      <li>
+        Ugly URLs tend to be longer than friendly URLs, which can make a difference when creating
+        a WML application.
+      </li>
+     <li>A single directory may contain all the artifacts (HTML templates,  specifications, properties files) for
+      all the pages in an entire application.  There isn't a sanctioned approach to organizing
+      things into subdirectories.</li>
+      <li>The reliance on query parameters means that common search engines will only see
+        a tiny fraction of the application.</li>
+    </ul>
+    
+    <p>
+    Starting with 4.0, <em>friendly URLs</em> are integrated directly into framework (in 3.0 an
+    ambitious, but more limited, patch was required). 
+    </p>
+    
+    <p>
+<strong>Warning:</strong>
+<br/>
+      For security purposes, enabling friendly URLs implies that pages are no longer
+      accessible via their ugly URL counterpart. This is not the case. If a malevolent user
+      can either guess - or via cookies identify - your servlet path, they can construct an
+      ugly URL to a resource that is protected via security and gain access to the protected
+      resource.
+    </p>
+    <p>
+    Friendly URLs are divided into two concerns:
+    </p>
+    
+    <ul>
+      <li>Converting information normally stored as a query parameter into part of the URL path.</li>
+      <li>Parsing the path to restore the information previously encoded.</li>
+    </ul>
+    
+    <p>
+      For example, the ugly URL <code>/app?page=news/Thread&amp;service=page</code> may be converted into
+      the friendly URL <code>/news/Threads.html</code>.  In this case, the <code>page=news/Thread</code> query parameter
+      became the <code>news/Thread</code> portion of the URL, and the <code>service=page</code> query parameter
+      became the <code>.html</code> extension to the URL.
+    </p>
+    
+  <section name="Understanding Tapestry URLs">
+    
+    
+    <p>
+      To understand how to get friendly URLs, you must understand a little about what 
+      information Tapestry packs into URLs.
+    </p>
+    
+    <p>
+    Every request to a Tapestry application is mapped to an <em>engine service</em>. An engine service
+    is something like a servlet, embedded within Tapestry. The <code>service</code> query parameter
+    is used to select an engine service by name.  A number of services are provided with the framework, the most common
+    of which are:
+    </p>
+    
+    <dl>
+      <dt>page</dt>
+      <dd>Activates and renders a specific page.</dd>
+      <dt>direct</dt>
+      <dd>Used with the <a href="site:DirectLink">DirectLink</a> and <a href="site:Form">Form</a> components.</dd>
+      <dt>home</dt>
+      <dd>Default service used when the service parameter is not specified (such as when
+        first accessing the application); activates and renders the Home page.</dd>
+    </dl>
+    
+    <p>
+      Each service is responsible for creating URLs with the correct query parameters.
+      By default, the URL path is always <code>/app</code> and any additional information comes out
+      of the query parameters.  The most common parameters are:
+    </p>
+    
+    <dl>
+      <dt>page</dt>
+      <dd>The name of a page to activate.</dd>
+      <dt>service</dt>
+      <dd>The service responsible for the request.</dd>
+      <dt>component</dt>
+      <dd>The nested component id of a component.</dd>
+      <dt>sp
+        
+      </dt>
+      <dd>
+        Stores listener parameters passed in the URL (used by <a href="site:DirectLink">DirectLink</a> and passed into <a href="listenermethods.html">listener method</a>s, the "sp" is a holdover from 3.0).
+      </dd>
+    </dl>
+    
+    <p>
+      Following this scheme, a typical URL might be
+      <code>/app?component=border.logout&amp;page=news/Thread&amp;service=direct</code>.  Yep, that's UGLY.
+    </p>
+    
+  </section>
+  
+  <section name="Enabling Friendly URLs">
+    
+    
+    <p>
+      To use ordinary ugly URLs, Tapestry requires only a 
+      <a href="configuration.html#configuration.deployment-descriptor">small amount of configuration
+        in web.xml</a>.  Enabling friendly URLs requires adding more
+        configuration to web.xml, and to your <a href="site:hivemind">HiveMind module deployment descriptor</a>.
+    </p>
+    
+    <p>
+      Friendly URLs are controlled by
+      <a href="../tapestry/apidocs/org/apache/tapestry/engine/ServiceEncoder.html">ServiceEncoder</a>s. Getting Tapestry to output friendly URLs is a matter of
+      plugging encoders into the correct pipeline ... this is all done using HiveMind.
+    </p>
+    
+    <subsection name="page-service-encoder">
+      
+      
+      <p>
+        The most common type of encoder is the <code>page-service-encoder</code>, which encodes
+        the <code>page</code> and <code>service</code> parameters.  In your hivemodule.xml:
+      </p>
+      
+      <source xml:space="preserve">
+&lt;contribution configuration-id="tapestry.url.ServiceEncoders"&gt;
+  &lt;page-service-encoder id="page" extension="html" service="page"/&gt;
+&lt;/contribution&gt;</source>
+      
+      <p>
+        This contribution to the <a href="../tapestry/hivedocs/config/tapestry.url.ServiceEncoders.html">tapestry.url.ServiceEncoders</a> configuration point
+        creates a <a href="../tapestry/apidocs/org/apache/tapestry/engine/ServiceEncoder.html">ServiceEncoder</a> that maps the <code>.html</code> extension (on the URL path)
+        to the page service. The <code>id</code> attribute must be unique for all
+        contributed encoders.
+      </p>
+      
+      <p>
+        For Tapestry to recognize the URLs, you must inform the servlet container
+        to send them to the Tapestry application servlet, by adding a mapping
+        to web.xml:
+      </p>
+      <source xml:space="preserve">
+&lt;servlet-mapping&gt;
+  &lt;servlet-name&gt;myapp&lt;/servlet-name&gt;
+  &lt;url-pattern&gt;*.html&lt;/url-pattern&gt;
+&lt;/servlet-mapping&gt;</source>  
+      
+
+<p>
+<strong>Note:</strong>
+<br/>
+  This means that even static HTML pages that are part of your web application will be
+  treated as Tapestry pages; any incoming request that ends with .html will be routed
+  into the Tapestry application. Page specifications are optional, so Tapestry will treat
+  the HTML pages are if they were HTML page templates.  If you want to allow ordinary static
+  content, then you should use another extension such as ".page" or ".tap" (the choice
+  is arbitrary).
+</p>      
+      
+    </subsection>
+    
+    <subsection name="direct-service-encoder">
+      
+      
+      <p>A specialized encoder used <em>exclusively</em>
+        with the direct service. Encodes the page name into the 
+        servlet path, then a comma, then the nested id for the component.  One of two extensions
+        is used, depending on whether the URL is stateful (an HttpSession existed when the link was rendered), or
+        stateless.</p>
+        
+        <p>
+          A typical URL might be:
+          <code>/admin/Menu,border.link.direct</code>.  This indicates a page name of <code>admin/Menu</code> and
+          a component id of <code>border.link</code>.  By convention, the ".direct" extension is for stateless URLs.
+        </p>
+        
+        <p>The hivemodule.xml contribution:</p>
+        
+<source xml:space="preserve">
+&lt;contribution configuration-id="tapestry.url.ServiceEncoders"&gt;
+  &lt;direct-service-encoder id="direct" stateless-extension="direct" stateful-extension="sdirect"/&gt;
+&lt;/contribution&gt;
+</source>        
+
+<p>
+  In  addition, the <code>*.direct</code> and <code>*.sdirect</code> mappings must be added to web.xml:
+</p>
+
+<source xml:space="preserve">
+&lt;servlet-mapping&gt;
+  &lt;servlet-name&gt;myapp&lt;/servlet-name&gt;
+  &lt;url-pattern&gt;*.direct&lt;/url-pattern&gt;
+&lt;/servlet-mapping&gt;
+  
+&lt;servlet-mapping&gt;
+  &lt;servlet-name&gt;myapp&lt;/servlet-name&gt;
+  &lt;url-pattern&gt;*.sdirect&lt;/url-pattern&gt;
+&lt;/servlet-mapping&gt;  </source>
+
+    </subsection>
+    
+    <subsection name="asset-encoder">
+      
+      
+      <p>
+        The <code>asset-encoder</code> is for use with the asset service.  The asset service exposes assets stored
+        on the classpath (i.e., inside JARs) to the client web browser. The asset service receives a request with a
+        resource path, and writes back a binary stream of that resources content.
+      </p>
+      
+      <p>
+        In addition, each request includes a <em>message digest</em>, a string generated from the bytes of the
+        the resource.  This message digest acts as a <em>credential</em>, assuring that only classpath resources
+        explicitly exposed by the application are accessible by the client (this prevents devious users from
+        obtaining Java class files, for example). The message digest can only be computed by the server, using the full
+        content of the actual file.
+      </p>
+      
+      <p>
+        To enable friendly URLs for the asset service, add the following to your hivemodule.xml:
+      </p>
+      
+      <source xml:space="preserve">
+&lt;contribution configuration-id="tapestry.url.ServiceEncoders"&gt;
+  &lt;asset-encoder id="asset" path="/assets"/&gt;
+&lt;/contribution&gt;</source>
+      
+      <p>
+        This contribution will encode asset URLs using the given path.  The provided path, <code>/assets</code> comes first,
+        then the digest string, then the path for the URL.  An example URI would be <code>/assets/91ab6d51232df0384663312f405babbe/org/apache/tapestry/contrib/palette/select_right.gif</code>.
+      </p>
+      
+      <p>
+        In addition you must add a mapping to web.xml:
+      </p>
+      
+<source xml:space="preserve">
+&lt;servlet-mapping&gt;
+  &lt;servlet-name&gt;myapp&lt;/servlet-name&gt;
+  &lt;url-pattern&gt;/assets/*&lt;/url-pattern&gt;
+&lt;/servlet-mapping&gt;</source>      
+      
+      
+      <p>
+        If you choose a different folder than <code>/assets/</code> then be sure to make corresponding changes
+        in both hivemodule.xml and web.xml.
+      </p>
+      
+    </subsection>
+    
+    <subsection name="extension-encoder">
+      
+      
+      <p>
+        The <code>extension-encoder</code> 
+        is used to encode just the <code>service</code> query parameter. The output URL is the service name
+        with a fixed extension (typically, ".svc"), i.e., <code>/home.svc</code> or <code>/restart.svc</code>.
+      </p>
+      
+      <p>In your hivemodule.xml:</p>
+  
+      <source xml:space="preserve">
+&lt;contribution configuration-id="tapestry.url.ServiceEncoders"&gt;
+  &lt;extension-encoder id="extension" extension="svc" after="*"/&gt;
+&lt;/contribution&gt;</source>        
+   
+      
+      <p>
+        The use of the <code>after</code> attribute ensures that this encoder is always executed after
+        any other encoders. Order is important!
+      </p>
+      
+      <p>
+        For this example, another mapping is required in the web.xml:
+      </p>
+      
+      <source xml:space="preserve">
+&lt;servlet-mapping&gt;
+  &lt;servlet-name&gt;myapp&lt;/servlet-name&gt;
+  &lt;url-pattern&gt;*.svc&lt;/url-pattern&gt;
+&lt;/servlet-mapping&gt;</source>      
+    </subsection>
+
+<subsection name="encoder">
+  
+
+  <p>
+    Finally, when one of the pre-defined encoders is insufficient, you can define your own.
+    The &lt;encoder&gt; element allows an arbitrary object that implements the <a href="../tapestry/apidocs/org/apache/tapestry/engine/ServiceEncoder.html">ServiceEncoder</a>
+    interface to be plugged into the pipeline.  The &lt;encoder&gt; element 
+    supports the (required) id attribute, and the optional before and
+    after attributes.
+  </p>    
+  
+  <p>
+    From the Virtual Library example, a custom encoder implementation is used as a 
+    special way to reference
+    the ViewBook and ViewPerson pages using the external service (see the <a href="site:ExternalLink">ExternalLink</a> component for more
+    information about using this engine service).  The end result is
+    that the URLs for these two pages look like
+    <code>/vlib/book/2096</code> rather than <code>/vlib/ViewBook.external?sp=2096</code> or
+    <code>/vlib/app?page=ViewBook&amp;service=external&amp;sp=2096</code>.  Certainly the
+    first option is by far the prettiest.
+  </p>
+    
+  <p>
+    These encoders are configured in hivemodule.xml as follows:
+  </p>
+  
+  <source xml:space="preserve">
+&lt;encoder id="viewbook" before="external" object="instance:ViewPageEncoder,pageName=ViewBook,url=/book"/&gt;
+&lt;encoder id="viewperson" before="external" object="instance:ViewPageEncoder,pageName=ViewPerson,url=/person"/&gt;
+&lt;page-service-encoder id="external" extension="external" service="external"/&gt;    
+</source>  
+
+  <p>
+    The order of the encoders in the pipline is very important, so the use of the before attribute ensures that the specialized encoders for these two pages
+    are allowed to operate before the general purpose external service encoder.
+  </p>
+  
+  <p>
+    The two special pages are mapped in web.xml using their custom URLs:
+  </p>  
+    
+<source xml:space="preserve">  &lt;servlet-mapping&gt;
+    &lt;servlet-name&gt;vlib&lt;/servlet-name&gt;
+    &lt;url-pattern&gt;/book/*&lt;/url-pattern&gt;
+  &lt;/servlet-mapping&gt;
+  &lt;servlet-mapping&gt;
+    &lt;servlet-name&gt;vlib&lt;/servlet-name&gt;
+    &lt;url-pattern&gt;/person/*&lt;/url-pattern&gt;
+  &lt;/servlet-mapping&gt;
+</source>    
+    
+  <p>
+    The implementation of the ViewPageEncoder class is all about an encode() method and a matching decode()
+    method.
+  </p>    
+  
+  <p>
+    The encode() method must check to see if the link being generated is the right page name
+    and the right service, returning (without doing anything) if not.  The link
+    being constructed is represented as an instance of <a href="../tapestry/apidocs/org/apache/tapestry/engine/ServiceEncoding.html">ServiceEncoding</a>:
+  </p>
+  
+  <source xml:space="preserve">
+  public void encode(ServiceEncoding encoding)
+  {
+    if (!isExternalService(encoding))
+      return;
+
+    String pageName = encoding.getParameterValue(ServiceConstants.PAGE);
+
+    if (!pageName.equals(_pageName))
+      return;
+
+    StringBuilder builder = new StringBuilder(_url);
+
+    String[] params = encoding.getParameterValues(ServiceConstants.PARAMETER);
+
+    // params will not be null; in fact, pretty sure it will consist
+    // of just one element (an integer).
+
+    for (String param : params)
+    {
+      builder.append("/");
+      builder.append(param);
+    }
+
+    encoding.setServletPath(builder.toString());
+
+    encoding.setParameterValue(ServiceConstants.SERVICE, null);
+    encoding.setParameterValue(ServiceConstants.PAGE, null);
+    encoding.setParameterValue(ServiceConstants.PARAMETER, null);
+  }
+
+  private boolean isExternalService(ServiceEncoding encoding)
+  {
+    String service = encoding.getParameterValue(ServiceConstants.SERVICE);
+
+    return service.equals(Tapestry.EXTERNAL_SERVICE);
+  }  </source>
+    
+  <p>
+    We cheat just a bit here because we know that the service parameters
+    will be a single numeric string.  You can see exactly how encoder works, by building
+    a new servlet path that encodes information that was stored as query parameters,
+    the setting those query parameters to null
+  </p>
+  
+  <p>
+    The flip side is the decode() method, which works by recognizing the URL
+    generated by the encode() method and restoring the query parameters by
+    parsing the URL:
+  </p>
+  
+  <source xml:space="preserve">  public void decode(ServiceEncoding encoding)
+  {
+    String servletPath = encoding.getServletPath();
+
+    if (!servletPath.equals(_url))
+      return;
+
+    String pathInfo = encoding.getPathInfo();
+
+    String[] params = TapestryUtils.split(pathInfo.substring(1), '/');
+
+    encoding.setParameterValue(ServiceConstants.SERVICE, Tapestry.EXTERNAL_SERVICE);
+    encoding.setParameterValue(ServiceConstants.PAGE, _pageName);
+    encoding.setParameterValues(ServiceConstants.PARAMETER, params);
+  } </source>
+  
+  </subsection>
+  
+    <p>
+      When constructing this style of encoder, it is important to remember that
+      the servlet path does not end with a slash, but tthe path info, if non-null, will start
+      with a slash.
+    </p>
+  
+  </section>
+    
+  </body>
+</document>

Propchange: tapestry/tapestry4/trunk/src/site/xdoc/UsersGuide/friendly-urls.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tapestry/tapestry4/trunk/src/site/xdoc/UsersGuide/hivemind.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/src/site/xdoc/UsersGuide/hivemind.xml?rev=418665&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/src/site/xdoc/UsersGuide/hivemind.xml (added)
+++ tapestry/tapestry4/trunk/src/site/xdoc/UsersGuide/hivemind.xml Sun Jul  2 17:17:29 2006
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+   Copyright 2004, 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>HiveMind Integration</title>
+</properties>
+<body>
+    <p> Tapestry 4.0 is intimately integrated into the <a href="http://jakarta.apache.org/hivemind/">HiveMind</a> microkernel. Building a complex system onto a 
+      dependency injection microkernel such as HiveMind has many benefits; the code is easier to write, test and 
+      maintain. HiveMind's flexible approach makes it easy to provide extension points ... many of the common kinds of 
+      customizations in Tapestry 3.0 that required code changes (such as subclassing <a href="../tapestry/apidocs/org/apache/tapestry/engine/BaseEngine.html">BaseEngine</a>) are now accomplished 
+      by providing objects via a HiveMind module descriptor for your application. </p>
+    <p> In fact, you should not think of HiveMind as just Tapestry's infrastructure, but as infrastructure for your 
+      application as well. A very succesful design pattern in Tapestry is to keep pages and components very simple, and 
+      <em>delegate</em> as much logic as possible out to HiveMind services. Listener methods should ideally do little 
+      more than marshall together the correct information and pass it over to a service (this sidesteps most of the 
+      issues with testing pages and components, which tend to be abstract). </p>
+      
+<p>
+<strong>Warning:</strong>
+<br/>
+  Tapestry 4.0 is <strong>not compatible with HiveMind 1.0</strong>. Tapestry 4.0 may only be used with
+  HiveMind 1.1. The compatibility issues are related to the underlying Javassist library; HiveMind 1.0 and Tapestry 3.0
+  use one version of the library, HiveMind 1.1 and Tapestry 4.0 use a more recent version.
+</p>     
+ 
+    <section name="Injecting Services">
+      
+      <p> But how to get access to those services? Tapestry allows you to <em>inject</em> your pages and components 
+        with HiveMind services (or other objects accessible from within a HiveMind registry). This is accomplished via 
+        the <a href="spec.html#spec.inject">&lt;inject&gt;</a> specification element: </p>
+      <source xml:space="preserve">
+&lt;page-specification class=". . ."&gt;
+
+  &lt;inject property="mailSender" object="service:mymodule.MailSender"/&gt;
+  
+&lt;/page-specification&gt; </source>
+      <p> This would create a new property on your page, mailSender, that would be connected to a HiveMind service, 
+        mymodule.MailSender. The object attribute is an <em>object reference</em>, consisting of a prefix ("service:") 
+        followed by a <em>locator</em>. The prefix identifies how the locator should be interpreted; in this case, as a 
+        full qualified service id. HiveMind itself defines a <a href="http://jakarta.apache.org/hivemind/hivemind/ObjectProviders.html">base set of prefixes</a>, to which 
+        Tapestry adds the following: </p>
+      <table>
+        <tr>
+          <th>Prefix</th>
+          <th>Description</th>
+          <th>Example</th>
+        </tr>
+        <tr>
+          <td>app-property</td>
+          <td>The locator is the name of a property that is resolved using:
+            <ul>
+              <li>The application specification's <a href="spec.html#spec.meta">&lt;meta&gt;</a> properties</li>
+              <li>The servlet's &lt;init-parameter&gt; elements</li>
+              <li>The servlet context's &lt;init-parameter&gt; elements</li>
+              <li>The delegate property source (a <a href="spec.html#spec.extension">&lt;extension&gt;</a>)</li>
+              <li>A HiveMind symbol</li>
+            </ul>
+</td>
+            <td>
+              app-property:org.apache.tapestry.template-extension
+            </td>
+        </tr>
+        <tr>
+          <td>engine-service</td>
+          <td>The locator is the name of an engine service (an instance of <a href="../tapestry/apidocs/org/apache/tapestry/engine/IEngineService.html">IEngineService</a>).</td>
+          <td>engine-service:page</td>
+        </tr>
+        <tr>
+          <td>global-property</td>
+          <td>The locator is the name of global property, defined as a servlet &lt;init-parameter&gt;,
+            a servlet context &lt;init-parameter&gt;,
+            or a HiveMind symbol. </td>
+            <td>global-property:org.apache.tapestry.disable-caching</td>
+        </tr>        
+        <tr>
+          <td>infrastructure</td>
+          <td> The locator is the name of a property provided by the tapestry.Infrastructure service; this service 
+            provides access to the key Tapestry services. </td>
+          <td>infrastructure:applicationSpecification</td>
+        </tr>
+
+      </table>
+      <p>
+<strong>Note:</strong>
+<br/> More prefixes are forthcoming. </p>
+      
+      <p>
+        You can access the service via the property.  You can do this from a <a href="spec.html#spec.binding">&lt;binding&gt;</a> element, or from within
+        the template, using an OGNL expression.  For example:  <code>ognl:mailSender.sendMail(to, subject)</code> would
+        read the to and subject properties of the page, and pass them to the sendMail() method of the mymodule.MailSender service (which has
+        been injected into the mailSender property).
+      </p>
+      
+      <p>
+        From within Java code, you can define an abstract accessor method:
+      </p>
+      
+      <source xml:space="preserve">
+public abstract class MyPage extends BasePage
+{
+  public abstract MailSender getMailSender();
+  
+  . . .
+        
+  public void myListener(IRequestCycle cycle)
+  {
+    String to = getTo();
+    String subject = getSubject();
+          
+    getMailSender().sendMail(to, subject);
+          
+     . . .
+  }
+}</source>
+      
+      
+    </section>
+    <!-- hivemind.inject -->
+     
+    <section name="Bootstrapping the Registry">
+      
+      <p> The <a href="../tapestry/apidocs/org/apache/tapestry/ApplicationServlet.html">ApplicationServlet</a> is responsible for initializing HiveMind's Registry on startup. </p>
+      <p>
+<strong>Note:</strong>
+<br/> The ApplicationServlet takes over all the roles usually supplied by HiveMind's HiveMindFilter. This 
+        includes the initial creation of the HiveMind Registry (as discussed), but also includes cleaning up thread 
+        local information at the end of each request, and shutting down the Registry when the servlet is destroyed. 
+        </p>
+      <p> The ApplicationServlet will create a default registry, consisting of all META-INF/hivemodule.xml files found 
+        on the servlet classpath. This is how the base HiveMind and Tapestry module descriptors are loaded. You may 
+        package module deployment descriptors inside libraries or even in your application WAR. </p>
+      <p> In addition, two other descriptors will be parsed if they exist: </p>
+      <ul>
+        <li>/WEB-INF/<em>applicationId</em>/hivemodule.xml</li>
+        <li>/WEB-INF/hivemodule.xml</li>
+      </ul>
+      <p>
+<strong>Note:</strong>
+<br/>The descriptor will not be recognized if it is located in META-INF/ in the context root of a web application
+            however it will if it is under the WEB-INF/ locations. The META-INF/ location is specific to libraries.</p>
+      <p> Both of these files exist in the web application context; the <em>applicationId</em> is the name of the application 
+        servlet, as given in web.xml deployment descriptor (this is only useful in the very rare case that you package 
+        more than one Tapestry application in a single web application). </p>
+      <p> By subclassing ApplicationServlet and overriding the <code>constructRegistry()</code> method, you can easily 
+        extend these rules, loading additional descriptors from arbitrary locations. </p>
+    </section>
+    <!-- hivemind.bootstrap -->
+  </body>
+</document>

Propchange: tapestry/tapestry4/trunk/src/site/xdoc/UsersGuide/hivemind.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tapestry/tapestry4/trunk/src/site/xdoc/UsersGuide/index.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/src/site/xdoc/UsersGuide/index.xml?rev=418665&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/src/site/xdoc/UsersGuide/index.xml (added)
+++ tapestry/tapestry4/trunk/src/site/xdoc/UsersGuide/index.xml Sun Jul  2 17:17:29 2006
@@ -0,0 +1,392 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    Copyright 2004, 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.
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.2//EN"
+    "http://maven.apache.org/dtd/xdoc_1_0.dtd">
+<document>
+    <properties>
+        <title>Introduction</title>
+    </properties>
+    <body>
+        
+        <section name="Introduction" >
+            <p>
+                Tapestry is a component-based web application framework, written in Java. Tapestry
+                is more than a simple templating system; Tapestry builds on the Java Servlet API to
+                build a platform for creating dynamic, interactive web sites. More than just another
+                templating language, Tapestry is a real framework for building complex applications
+                from simple, reusable components. Tapestry offloads much of the error-prone work in
+                creating web applications into the framework itself, taking over mundane tasks such
+                as dispatching incoming requests, constructing and interpretting URLs encoded with
+                information, handling localization and internationalization and much more besides.
+            </p>
+
+            <p>
+                The "mantra" of Tapestry is "objects, methods and properties". That is, rather than
+                have developers concerned about the paraphanlia of the Servlet API: requests,
+                responses, sessions, attributes, parameters, URLs and so on, Tapestry focuses the
+                developer on objects (including Tapestry pages and components, but also including
+                the domain objects of the application), methods on those objects, and JavaBeans
+                properties of those objects. That is, in a Tapestry application, the actions of the
+                user (clicking links and submitting forms) results in changes to object properties
+                combined with the invocation of user-supplied methods (containing application
+                logic). Tapestry takes care of the plumbing necessary to connect these user actions
+                with the objects.
+            </p>
+
+            <p>
+                This can take some getting used to. You don't write servlets in Tapestry, you write
+                <a href="listenermethods.html">listener method</a>
+                s. You don't build URLs to servlets either -- you use an existing component (such as
+                <a href="site:DirectLink">DirectLink</a>
+                ) and configure its
+                <code>listener</code>
+                parameter to invoke your listener method. What does a listener method do? It
+                interacts with backend systems (often, stateless session EJBs) or does other
+                bookkeeping related to the request and selects a new page to provide a response to
+                the user ... basically, the core code at the center of a servlet. In Tapestry, you
+                write much less code because all the boring, mechanical plumbing (creating URLs,
+                dispatching incoming requests, managing server-side state, and so forth) is the
+                responsibility of the framework.
+            </p>
+
+            <p>
+                This is not to say the Servlet API is inaccessible; it is simply not
+                <em>relevant</em>
+                to a typical Tapestry user.
+            </p>
+
+            <p>
+                This document describes many of the internals of Tapestry. It is not a tutorial,
+                that is available as a separate document. Instead, this is a guide to some of the
+                internals of Tapestry, and is intended for experienced developers who wish to
+                leverage Tapestry fully.
+            </p>
+
+            <p>
+                Tapestry is currently in release 4.0, and has come a long way in the last couple of
+                years. Tapestry's focus is still on generating dynamic HTML pages, although there's
+                plenty of support for XHTML, WML and other types of markup as well.
+            </p>
+
+            <p>
+                Nearly all of Tapestry's API is described in terms of interfaces, with default
+                implementations supplied. By substituting new objects with the correct interfaces,
+                the behavior of the framework can be changed significantly. A common example is to
+                override where page and component specifications are stored (perhaps in a database).
+            </p>
+
+            <p>
+                Finally, Tapestry boasts extremely complete JavaDoc API documentation. This document
+                exists to supplement that documentation, to fill in gaps that may not be obvious.
+                The JavaDoc is often the best reference.
+            </p>
+
+            <subsection name="An overview of Tapestry" >
+                <p>
+                    Perhaps the hardest part of understanding Tapestry is the fact that it is
+                    <em>component-centric</em>
+                    not
+                    <em>operation-centric</em>
+                    . Most web technologies (
+                    <a href="http://struts.apache.org/">Struts</a>
+                    , servlets, PHP, etc.) are operation-centric. You create servlets (or Actions,
+                    or what have you) that are invoked when a user clicks a link or submits a form.
+                    You are responsible for selecting an appropriate URL, and the name and type of
+                    any query parameters, so that you can pass along the information you need in the
+                    URL.
+                </p>
+
+                <p>
+                    You are also responsible for connecting your output pages (whether they are
+                    JSPs,
+                    <a href="http://jakarta.apache.org/velocity/">Velocity</a>
+                    templates, or some other form of templating technology) to those operations.
+                    This requires you to construct those URLs and get them into the
+                    <code>href</code>
+                    attribute of your &lt;a&gt; tag, or into the
+                    <code>action</code>
+                    attribute of your &lt;form&gt; tag.
+                </p>
+
+                <p>
+                    Everything is different inside Tapestry. Tapestry applications consist of pages;
+                    pages are constructed from smaller components. Components may themselves be
+                    constructed from other components. Every page has a unique name, and every
+                    component within a page has its own unique id ... this is a
+                    <em>component object model</em>
+                    . Effectively, every component has an
+                    <em>address</em>
+                    that can easily be incorporated into a URL.
+                </p>
+
+                <p>
+                    In practical terms, your don't write a servlet for the
+                    <code>add-item-to-shopping-cart</code>
+                    operation. In fact, you don't even write an
+                    <code>add-item-to-shopping-cart</code>
+                    component. What you do is take an existing component, such as
+                    <a href="site:DirectLink">DirectLink</a>
+                    , and configure it. When the component renders, it will create a callback URL.
+                    When you click that link, the callback URL (which includes the name of the page
+                    and the id of the component within the page) will invoke a method on the
+                    component ... and
+                    <em>that</em>
+                    method invokes your application-specific
+                    <em>listener method</em>
+                    .
+                </p>
+
+                <p>
+                    <strong>Note:</strong>
+                    <br />
+                    Listener methods in Tapestry are very similar in intent to
+                    <em>delegates</em>
+                    in C#. In both cases, a method of a particular object instance is represented as
+                    an object. Calling this a "listener" or a "listener method" is a bit of a naming
+                    snafu; it should be called a "delegate" and a "delegate method" but the existing
+                    naming is too deeply entrenched to change any time soon.
+                </p>
+
+                <p>
+                    You supply just the listener method ... not an entire servlet. Tapestry takes
+                    care that your listener method is invoked at the right time, under the right
+                    conditions. You don't have to think about how to build that URL, what data goes
+                    in the URL, or how to hook it up to your application-specific code--that's all
+                    handled by the framework.
+                </p>
+
+                <img alt="Tapestry request dispatch (high level)"
+                    src="../images/UsersGuide/high-level-component-request.png" />
+
+            </subsection><!-- intro.overview -->
+
+            <subsection name="Pages and components">
+
+
+                <p>
+                    Tapestry divides an application into a set of pages. Each page is assembled from
+                    Tapestry components. Components themselves may be assembled from other
+                    components ... there's no artificial depth limit.
+                </p>
+
+
+                <p>
+                    Tapestry pages are themselves components, but are components with some special
+                    responsibilities.
+                </p>
+
+                <p>
+                    All Tapestry components can be containers of other components. Tapestry pages,
+                    and most user-defined components, have a template, a special HTML file that
+                    defines the static and dynamic portions of the component, with markers to
+                    indicate where embedded components are active. Components do not have to have a
+                    template, most of the components provided with Tapestry generate their portion
+                    of response in code, not using a template.
+                </p>
+
+                <p>
+                    Components may have one or more named parameters which may be set (or, more
+                    correctly, "bound") by the page or component which contains them. Unlike Java
+                    method parameters, Tapestry component parameters may be bidirectional; a
+                    component may read a parameter to obtain a value, or write a parameter to set a
+                    value.
+                </p>
+
+                <p>
+                    Most components are concerned only with generating HTML. A certain subset of
+                    components deal with the flip-side of requests; handling of incoming requests.
+                    Link classes, such as
+                    <a href="site:PageLink">PageLink</a>
+                    ,
+                    <a href="site:DirectLink">DirectLink</a>
+                    and
+                    <a href="site:ActionLink">ActionLink</a>
+                    , create clickable links in the rendered page and are involved in dispatching to
+                    user-supplied code when such a link is triggered by clicking it.
+                </p>
+
+                <p>
+                    Other components,
+                    <a href="site:Form">Form</a>
+                    , and the form control components (
+                    <a href="site:TextField">TextField</a>
+                    ,
+                    <a href="site:PropertySelection">PropertySelection</a>
+                    ,
+                    <a href="site:Checkbox">Checkbox</a>
+                    , etc.), facilitate HTML forms. When such components render, they read
+                    properties from application objects so as to provide default values. When the
+                    forms are submitted, the components within the form read HTTP query parameters,
+                    convert the values to appropriate types and then update properties of
+                    application objects.
+                </p>
+
+            </subsection><!-- intro.pages-and-components -->
+
+            <subsection name="Engines, services and friends">
+
+
+                <p>Tapestry has evolved its own jargon over time.</p>
+
+                <p>
+                    The Engine is a central object, it occupies the same semantic space in Tapestry
+                    that the HttpSession does in the Servlet API. The Engine is ultimately
+                    responsible for storing the persistent state of the application (properties that
+                    exist from one request to the next), and this is accomplished by storing the
+                    Engine into the HttpSession. This document will largely discuss the
+                    <em>default</em>
+                    implementation, with notes about how the default implementation may be extended
+                    or overriden, where appropriate.
+                </p>
+
+                <p>
+                    Engine services are the bridge between servlets and URLs and the rest of
+                    Tapestry. Engine services are responsible for encoding URLs, providing query
+                    parameters that identify, to the framework, the exact operation that should
+                    occur when the generated URL is triggered (by the end user clicking a link or
+                    submitting a form). Services are also responsible for dispatching those incoming
+                    requests. This encapsulation of URL encoding and decoding inside a single object
+                    is key to how Tapestry components can flexibily operate without concern for how
+                    they are contained and on which page ... the services take into account page and
+                    location when formulating URLs.
+                </p>
+
+                <p>
+                    The
+                    <a href="state.html#state.visit">Visit object</a>
+                    is an application-defined object that acts as a focal point for all server-side
+                    state (not associated with any single page). Individual applications define for
+                    themselves the class of the Visit object. The Visit is stored as a property of
+                    the Engine, and so is ultimately stored persistently in the HttpSession.
+                </p>
+
+                <p>
+                    The
+                    <a href="state.html#state.global">Global object</a>
+                    is also application-specific. It stores information global to the entire
+                    application, independent of any particular user or session. A common use for the
+                    Global object is to centralize logic that performs JNDI lookups of session EJBs.
+                </p>
+
+            </subsection><!-- intro.engine-service-visit -->
+
+            <subsection name="Object Graph Navigation Language">
+
+
+                <p>
+                    Tapestry is tightly integrated with
+                    <a href="http://www.ognl.org">OGNL</a>
+                    , the Object Graph Navigation Language. OGNL is a Java expression language,
+                    which is used to peek into objects and read or update their properties. OGNL is
+                    similar to, and must more powerful than, the expression language built into the
+                    JSP 2.0 standard tag library. OGNL not only support property access, it can
+                    include mathematical expressions and method invocations. It can reference static
+                    fields of public classes. It can create new objects, including lists and maps.
+                </p>
+
+                <p>
+                    The simplest OGNL expressions are property names, such as
+                    <code>foo</code>
+                    , which is equivalent to method
+                    <code>getFoo()</code>
+                    (or
+                    <code>setFoo()</code>
+                    if the expression is being used to update a property). The "Navigation" part
+                    comes into play when the expression is a series of property names, such as
+                    <code>foo.bar.baz</code>
+                    , which is equivalent to
+                    <code>getFoo().getBar().getBaz()</code>
+                    ... though care must always be taken that the intermediate properties (
+                    <code>foo</code>
+                    and
+                    <code>bar</code>
+                    in this example) are not null.
+                </p>
+
+                <p>
+                    OGNL is primarily used to allow two different objects (such as a page and a
+                    component contained by that page) to share information.
+                </p>
+
+            </subsection><!-- intro.ognl -->
+
+            <subsection name="Tapestry Past, Tapestry Future">
+
+
+                <p>
+                    Since its initial introduction in early 2000, Tapestry has been in a constant
+                    state of evolution, driven by feedback from its community. Tapestry took a big
+                    leap forward in 2003. During that period, the Tapestry project moved from
+                    <a href="http://sf.net">SourceForge</a>
+                    to
+                    <a href="http://jakarta.apache.org">Jakarta</a>
+                    . This was also the transition from release 2.3 to release 3.0 (the final 3.0
+                    release occuring in April 2004).
+                </p>
+
+                <p>
+                    Tapestry 3.0 was designed to radically change how Tapestry applications were
+                    created. It introduced a kind of RAD (Rapid Application Development) support in
+                    the form of
+                    <a href="template.html#template.components">implicit components</a>
+                    ... a way of specifying a component's type and parameters in place in the HTML
+                    template, which is much more familiar to JSP and PHP developers.
+                </p>
+
+                <p>
+                    Tapestry 3.0 also saw the introduction of
+                    <em>line precise error reporting</em>
+                    , in which runtime errors are related back to relevant lines in the HTML
+                    template or specification file. Further, 3.0 introduced the
+                    <a href="spec.html#spec.property">&lt;property&gt;</a>
+                    element, and the
+                    <em>bytecode enhancement</em>
+                    technology behind it.
+                </p>
+
+                <p>
+                    Tapestry 4.0 represents an even more radical leap beyond 3.0 by introducing a
+                    new, sophisticated infrastructure on top of the
+                    <a href="http://jakarta.apache.org/hivemind/">HiveMind</a>
+                    microkernel. This new backbone provides the support necessary to meet the needs
+                    of Tapestry's much larger community ... including support for
+                    <em>prettier</em>
+                    URLs, integration of Tapestry and the Java Portlet API, and modularization of
+                    applications (allowing the use of folders, and thus, J2EE declarative security).
+                    In addition, a more sophisticated approach to implementing connected parameter
+                    properties has been introduced in release 4.0, and more flexibility for storing
+                    session-specific state as HTTP query parameters has been provided. For JDK 1.5
+                    users, the XML page and component specifications can now be sidelined in favor
+                    of Java annotations.
+                </p>
+
+                <p>
+                    A further future direction, in the Tapestry 5.0 timeframe (the far future), is
+                    to rethink the component object model such that the classes
+                    <em>you</em>
+                    write do not sub-class Tapestry base classes. Page and component Java classes
+                    will be simple POJOs (Plain Old Java Objects) and will have any Tapestry
+                    dependencies
+                    <em>injected</em>
+                    into them.
+                </p>
+
+            </subsection>
+        
+        </section>
+    </body>
+</document>

Propchange: tapestry/tapestry4/trunk/src/site/xdoc/UsersGuide/index.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tapestry/tapestry4/trunk/src/site/xdoc/UsersGuide/injection.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/src/site/xdoc/UsersGuide/injection.xml?rev=418665&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/src/site/xdoc/UsersGuide/injection.xml (added)
+++ tapestry/tapestry4/trunk/src/site/xdoc/UsersGuide/injection.xml Sun Jul  2 17:17:29 2006
@@ -0,0 +1,250 @@
+<?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>
+    
+<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">&lt;inject&gt;</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">&lt;inject&gt;</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">&lt;inject&gt;</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/hivedocs/config/tapestry.enhance.InjectWorkers.html">tapestry.enhance.InjectWorkers</a> configuration point
+defines the available types of injection.
+The <a href="../tapestry/hivedocs/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">&lt;bean&gt;</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>
+
+
+<section 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">&lt;meta&gt;</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">
+
+  &lt;meta key="page.size" value="15"/&gt;
+  
+  &lt;inject property="pageSize" type="meta" object="page.size"/&gt;
+
+</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>
+  
+</section> <!-- injection.meta -->
+
+<section 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>
+
+</section> <!-- injection.object -->
+
+<section 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="../tapestry/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="../tapestry/apidocs/org/apache/tapestry/IPage.html">IPage</a>, or any type assignable to <a href="../tapestry/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">
+  &lt;inject property="detailsPage" type="page" object="Details"/&gt;
+</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>
+  
+</section> <!-- injection.page -->
+
+<section 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="../tapestry/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">
+  &lt;inject property="script" type="script" object="Palette.script"/&gt;
+</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>
+
+</section> <!-- injection.script -->
+
+<section 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>  
+  
+</section>
+
+<section 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">
+// &lt;inject&gt; type state-flag in the XML
+public abstract boolean getUserIdentityExists();
+
+// &lt;inject&gt; type state in the XML
+public abstract WizardState  getUserIdentity();
+  
+public void doOperation()
+{
+  if (getUserIdentityExists() &amp;&amp; getUserIdentity().isLoggedIn())
+  {
+    . . .
+  }
+  else
+  {
+    . . .
+  }
+}
+</source>
+</section> <!-- injection.state-flag -->
+    
+  </body>
+</document>

Propchange: tapestry/tapestry4/trunk/src/site/xdoc/UsersGuide/injection.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tapestry/tapestry4/trunk/src/site/xdoc/UsersGuide/listenermethods.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/src/site/xdoc/UsersGuide/listenermethods.xml?rev=418665&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/src/site/xdoc/UsersGuide/listenermethods.xml (added)
+++ tapestry/tapestry4/trunk/src/site/xdoc/UsersGuide/listenermethods.xml Sun Jul  2 17:17:29 2006
@@ -0,0 +1,223 @@
+<?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>Listener Methods</title>
+</properties>
+<body>
+
+<p>
+Listener methods are the main approach by which you add application-specific behavior to your application.
+</p>  
+
+<p>
+Listener methods are a kind of call back; they are triggered when a form is submitted or a link is clicked.  The listener methods
+exist within your page and component classes.  Components such as <a href="site:DirectLink">DirectLink</a> and <a href="site:Form">Form</a> take a listener parameter,
+and you can use a listener: <a href="bindings.html">binding reference</a> to use a listener method in your class as the listener.
+</p>
+
+<p>
+<strong>Note:</strong>
+<br/>
+The parameter type for listeners is <a href="../tapestry/apidocs/org/apache/tapestry/IActionListener.html">IActionListener</a>.  Internally, Tapestry creates an object that implements
+that interface and uses reflection to invoke the corrsponding method  on your page or component instance. On rare
+occasions, it is useful to create objects that implement the interface directly.  For pages, components and the
+engine, there is a listeners property whose keys are the names of listener methods, but the listener: binding reference
+is easier to use.
+</p>
+
+<p>
+A listener method is always a public  instance method.   It may take parameters, or not, and may
+return void or certain other types.
+</p>
+
+<section name="Return Type">
+  
+  
+<p>
+A listener method may return void, may return a string, or may return an object that implements <a href="../tapestry/apidocs/org/apache/tapestry/IPage.html">IPage</a>.
+The last two options are used to change the <em>active page</em>, the page which will render
+the response. Returning null will not change the active page (it defaults to the page containing the
+link or form components which invoked the listener method).
+</p>
+
+<dl>
+ <dt>void</dt>
+ <dd>The listener method does not change the active page.</dd>
+
+<dt>java.lang.String</dt>
+<dd>The listener method may return the name of a page to activate (and render the response). Returning
+null does not change the active page.</dd>
+
+<dt>
+<a href="../tapestry/apidocs/org/apache/tapestry/IPage.html">IPage</a>
+</dt>
+<dd>A non-null <a href="../tapestry/apidocs/org/apache/tapestry/IPage.html">IPage</a> will activate that page instance. The page object may be obtained
+from the request cycle, or via <a href="injection.html#injection.page">page injection</a>.
+</dd>
+
+<dt>
+<a href="../tapestry/apidocs/org/apache/tapestry/engine/ILink.html">ILink</a>
+</dt>
+<dd>
+Returning a non-null <a href="../tapestry/apidocs/org/apache/tapestry/engine/ILink.html">ILink</a> will send a redirect to the client for the URL associated with the link.
+This is commonly used to perform a <em>redirect-after-post</em>.
+</dd>
+</dl>
+
+</section> <!-- listenermethods.return -->
+
+
+
+<section name="Listener Method Parameters">
+  
+
+<p>
+When using the <a href="site:DirectLink">DirectLink</a> component, you may specify additional <em>listener parameters</em>.  The listener parameters
+are encoded into the URL and will be available in a later request, when the listener is triggered.
+</p>
+
+<p>
+<strong>Note:</strong>
+<br/>
+In Tapestry 3.0 and earlier, <em>listener parameters</em> were known as <em>service parameters</em>.  In addition,
+listener methods had to be in a very fixed form, taking exactly one parameter of type <a href="../tapestry/apidocs/org/apache/tapestry/IRequestCycle.html">IRequestCycle</a> and returning void.
+</p>
+
+<p>
+The listener can gain access these parameters in one of two ways:</p>
+
+<ul>
+  <li>By invoking the <code>getListenerParameters()</code> method of <a href="../tapestry/apidocs/org/apache/tapestry/IRequestCycle.html">IRequestCycle</a>
+</li>
+  <li>By declaring a method parameter for <em>each</em> listener parameter (in order)</li>  
+</ul>
+
+<p>
+Using the second method is usually the best way.  The link parameter values are <em>not</em> simply
+converted into strings, they are encoded as strings but maintain their type; therefore, the listener method
+parameters must be of the correct type.
+</p>
+
+<p>
+For example, suppose that the link encoded a String objectId and an integer index.  The component
+in the template names the listener method, and the two parameters are passed into the DirectLink as an OGNL
+list expression:
+</p>
+
+<source xml:space="preserve">
+&lt;a jwcid="@DirectLink" listener="listener:doClick" parameters="ognl:{ objectId, index }"&gt; . . . &lt;/a&gt;
+</source>
+
+<p>
+In the Java class, the listener method might look like:
+</p>
+
+<source xml:space="preserve">
+public void doClick(String objectId, int index)
+{
+  . . .
+}
+</source>
+
+<p>
+Alternately, the listener method could look like:
+</p>
+
+<source xml:space="preserve">
+public void doClick(IRequestCycle cycle)
+{
+  Object[] parameters = cycle.getListenerParameters();
+  String objectId = (String)parameters[0];
+  int index = ((Integer)parameters[1]).intValue();
+  
+  . . .
+}
+</source>
+
+<p>
+This second case is maintained in Tapestry 4.0 mostly for backwards compatibility, or to handle the case
+where a single listener method must handle an indeterminate number of listener parameters.
+</p>
+
+<p>
+In fact, Tapestry does a search for the most appropriate method, given the number of listener parameters:
+</p>
+
+<ul>
+  <li>public <em>type</em> <em>method</em>(<em>parameters</em>)</li>
+  <li>public <em>type</em> <em>method</em>(IRequestCycle cycle, <em>parameters</em>)</li>
+  <li>public <em>type</em> <em>method</em>()</li>
+  <li>public <em>type</em> <em>method</em>(IRequestCycle cycle)</li>
+</ul>
+
+<p>
+Tapestry 3.0 and earlier only accepted the final variation (and it had to return void).  Don't get too tricky with multiple overloadings
+of the method; Tapestry doesn't attempt to match the listener parameter types to the method parameter types (it
+works just by comparing the <em>number</em> of parameters).  However, you can count on Java boxing and autoboxing
+the parameter values (so you can use <code>int</code> and <code>java.lang.Integer</code> interchangeably).
+</p>
+
+</section> <!-- listenermethods.parameters -->
+
+<section name="Invoking Listener Methods">
+  
+
+
+<p>
+When creating components that accept a listener as a parameter, you should not invoke the
+<a href="../tapestry/apidocs/org/apache/tapestry/IActionListener.html">IActionListener</a> directly, instead, you should inject the infrastructure:ListenerInvoker service 
+into your component, and have it invoke the listener.  The ListenerInvoker is extensible, and 
+application logic may depend on ListenerInvoker's behavior (commonly, it is used to mark
+transactions boundaries).
+</p>
+
+<p>
+In your component specification:
+</p>
+
+<source xml:space="preserve">
+  &lt;parameter name="listener" required="yes"/&gt;
+
+  &lt;inject property="listenerInvoker" object="infrastructure:listenerInvoker"/&gt;
+</source>
+
+<p>
+In your source code:
+</p>
+
+<source xml:space="preserve">
+  public abstract IActionListener getListener();
+  
+  public abstract ListenerInvoker getListenerInvoker();
+  
+  . . .
+  
+  IActionListener listener = getListener();
+  ListenerInvoker invoker = getListenerInvoker();
+  
+  invoker.invokeListener(listener, this, cycle);
+</source>
+
+<p>
+It is acceptible to pass null as the listener; this saves you the necessity of checking for null
+when the listener is an optional parameter.
+</p>
+
+</section> <!-- listenermethods.invoking -->
+</body>
+</document>

Propchange: tapestry/tapestry4/trunk/src/site/xdoc/UsersGuide/listenermethods.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tapestry/tapestry4/trunk/src/site/xdoc/UsersGuide/localization.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/src/site/xdoc/UsersGuide/localization.xml?rev=418665&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/src/site/xdoc/UsersGuide/localization.xml (added)
+++ tapestry/tapestry4/trunk/src/site/xdoc/UsersGuide/localization.xml Sun Jul  2 17:17:29 2006
@@ -0,0 +1,330 @@
+<?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>Localization</title>
+</properties>
+<body>
+    <p> Proper localization is a pervasive aspect of web application development. Supporting users from different countries, with different languages, can be a tricky proposition ... it is more than just text that must be localized, but more subtle aspects of the application such as date and currency formats. It is also more than text ... in some cases, a localized application will want to change images or even color schemes. </p>
+    <p> Localization support in Tapestry is likewise pervasive. </p>
+    <section name="Component Message Catalogs">
+      
+      <p> The most fundamental aspect of localization in Tapestry are component message catalogs (remember that pages are components too). A message catalog is a mapping from a logical key (that may appear in Java code or in OGNL expressions) to a literal string. Tapestry message catalogs are similar to Java's ResourceBundle class, except there is more flexibility in the character set of the files, and the location of the files. </p>
+      <p> Each component <em>may</em> have a message catalog, consisting of a set of localized message properties files. </p>
+      <p> These files are stored with the page or component specification file. They are named the same as the specification file, but with a different extension (".properties" instead of ".jwc" or ".page"). </p>
+      <p> In addition, this is a <em>set</em> of files; a locale string may be inserted just before the extension. For example, <code>WEB-INF/Home_fr.properties</code> to contain the French language localization of the keys. </p>
+      <p> As with Java's ResourceBundle, resolution of a key to a message starts with the most 
+        <em>specific</em> properties file. Any key not found there will be searched for in less specific files.  For example,
+        the search path could be <code>Home_fr_BE.properties</code>, <code>Home_fr.properties</code>, <code>Home.properties</code>.</p>
+        <p>If a properties file does not exist, that's perfectly ok, the search will continue.</p>
+      <p>
+        When a key can not be found even in the most general properties file, a search occurs in the
+        <a href="#localization.namespace">namespace</a>. In this way, very common strings can be
+        stored and localized once, and used throughout a library or application.
+      </p>
+      <p> We'll describe how to use the message catalog shortly, but first some notes on how the message catalogs are read. </p>
+      <subsection name="Properties file encoding">
+        
+        <p> For Java's ResourceBundle, the properties files must be in UTF-8 character set. This can be problematic, as in non-western languages it is necessary to use Java's native2ascii tool to convert from non-native files into an ASCII encoding of UTF-8. </p>
+        <p> Tapestry can read properties files in alternate character sets, but must be told what character set the file is encoded in (internally, the contents must be converted into standard multi-byte Unicode). </p>
+        <p> This is accomplished by providing some metadata inside the component (or page) specification. Metadata is specified using the <a href="spec.html#spec.meta">&lt;meta&gt;</a> element. </p>
+        <p> The resolution of the character set is somewhat complicated; it is  possible that each properties file will use a different 
+          character set. At the same time, repetition is bad ... therefore it is possible to specify some of this information
+          in the namespace meta data (in the containing application or library specification) so that it can apply to all pages
+          and components within the namespace.</p>
+          
+        <p>
+          The basic meta-data  property name searched for is <code>org.apache.tapestry.messages-encoding</code>.  The value for this name
+          is the name of the charset for the properties file.
+        </p>
+        
+        <p>
+          However, the base name is modified to reflect the locale for the file being read; the locale string is appended
+          to the key, thus <code>org.apache.tapestry.messages-encoding_fr</code> will define the character set for
+          the file <code>WEB-INF/Home_fr.properties</code>
+        </p>
+        
+        <p>
+          For each localization of the base property name, a search of the following locations takes place.
+        </p>
+        <ul>
+          <li>The page or component specification.</li>
+          <li>The namespace (library or application) specification for the namespace containing the page or component.</li>
+          <li>The <a href="configuration.html#configuration.global-property-source">global property source</a>.</li>
+        </ul>
+        
+        <p>
+          Because localization of templates is similar to
+          localization of message properties files,
+          a second search occurs if the search for (variations of)
+          <code>org.apache.tapestry.messages-encoding</code> fails; this time for
+          <code>org.apache.tapestry.template-encoding</code> occurs (again, with variations
+          for each locale).
+        </p>
+        
+        <p>
+          The ultimate default for encoding character set is
+          ISO-8859-1; in other words, the same behavior as reading an ordinary
+          Java ResourceBundle.
+        </p>
+          
+      </subsection>
+    </section>
+    <section name="Missing keys">
+      
+      
+      <p>
+        While developing, you may occasionally reference a key that does not exist. Rather than fail  with an exception,
+        Tapestry will fabricate a missing key value.  This is the key, converted to upper-case, and surrounded with brackets.  For example,
+        <code>[A-MISSING-KEY]</code>.  This allows missing key values to stand out an demand to be fixed, without
+        completely subverting your application.
+      </p>
+      
+    </section> <!-- localization.missing-keys -->
+    <section name="Namespace message catalogs">
+      
+      
+      <p>
+      It is very likely that you'll have a number of strings that are used, and re-used, throughout
+      your application. Rather than duplicate the same message keys and localized values in all your page
+      and component message catalogs, you can put these into your <em>namespace</em> catalog.
+      </p>
+      
+      <p>
+        Each page and component is part of a <code>namespace</code>, identified by
+        a library specification or component specification.
+      </p>
+      
+      <p>
+        The specification may also have a message catalog; for instance, for <code>WEB-INF/myapp.application</code>,
+        the files would be named <code>WEB-INF/myapp.properties</code>, etc. Again, the 
+        name of the file  is based on the servlet name ("myapp").
+      </p>
+      
+      <p>
+        Very simple applications may not have an application specification, but may still have
+        properties, just as if the application specification existed.
+      </p>
+      
+    </section> <!-- localization.namespace -->
+    <!-- localization.component-catalog -->
+    <section name="Template text localization">
+      
+      <p>As described in <a href="template.html#template.directives.l10n">the discussion of Tapestry templates</a>, 
+        static text in an HTML template can be enclosed in a specialized &lt;span&gt; tag. </p>
+      
+    </section>
+    
+    <section name="Localized templates">
+      
+      
+      <p>
+        In some cases, the entire layout of a page (or component) must change due to locale. For example,
+        because of differences between western languages (which read left to right) and many eastern
+        languages (which read right to left).
+      </p>
+      
+      <p>
+        In this case, it is possible to have multiple HTML templates. If a localized template (e.g.,
+        <code>Home_jp.html</code> for a Japanese locale) exists, it will be used as appropriate.
+      </p>
+      
+      <p>
+        Page and component <em>specifications</em> are never localized, just <em>templates</em>.
+      </p>
+      
+      <p>
+        It is a good idea to make use of declared components, rather than implicit components, when
+        using localized templates ... it reduces duplication in the templates.
+      </p>
+    </section>
+    
+    <section name="Template encoding">
+      
+      
+      <p>
+        Like <a href="#localization.component-catalog.encoding">message catalogs</a>,
+        each template may be written in a different character set.  
+      </p>
+      
+        <p>
+          For each localization of the base key (<code>org.apache.tapestry.template-encoding</code>, a search of the following locations takes place.
+        </p>
+        <ul>
+          <li>The page or component specification.</li>
+          <li>The namespace specification for the namespace containing the page or component.</li>
+          <li>The <a href="configuration.html#configuration.search-path">application property search path</a>
+</li>
+        </ul>
+    </section>
+    
+    <section name="Using the message: binding prefix">
+      
+      
+      <p>
+        When specifying a parameter binding, the <code>message:</code> prefix
+        is used to reference a localized message key.  For example:
+      </p>
+      
+<source xml:space="preserve">
+&lt;html jwcid="@<a href="site:Shell">Shell</a>" title="message:page-title"&gt;
+ . . .
+&lt;/html&gt;
+</source>      
+      
+    </section>
+    
+    <section name="Localization of Assets">
+      
+      
+      <p>
+Assets may also be localized.  Classpath and context assets will  automatically search for a
+locale-specific match (this is very similar to how localized templates work).
+      </p>
+    </section>  <!-- localization.assets -->
+    
+    <section name="Formatting messages">
+      
+      
+<p>
+Messages may contain <em>arguments</em>, strings of the form <code>{0}</code> (or
+some other number). The argument are handled exactly the same as with Java's MessageFormat
+class (in fact, under the covers, MessageFormat does the work).
+</p>      
+
+<p>
+Components include a <code>messages</code> property for accessing localized messages.
+This property is of type Messages, and includes two methods:
+</p>
+
+<ul>
+  <li>
+<code>getMessage()</code> takes a string parameter and returns a localized message</li>
+  <li>
+<code>format()</code> takes a string parameter (the key) and then takes a number of
+    additional parameters as arguments.  The arguments are just objects.  If you have more
+    than three arguments, then specify them as an object array.</li>
+</ul>
+
+<p>
+It is common to format messages using OGNL expessions, i.e.:
+</p>
+
+<source xml:space="preserve">
+&lt;span jwcid="@<a href="site:Insert">Insert</a>" value="ognl:messages.format('billing-info', amountDue)"/&gt;
+</source>
+
+<p>
+The above example would get the amountDue property and pass it in as argument 0 to the message
+format retrieved from the message catalog as key 'billing-info'.
+</p>
+      
+    </section>
+    
+<section name="Changing the locale">
+   
+  
+<p>
+In order to change the locale, you must obtain the <a href="../tapestry/apidocs/org/apache/tapestry/IEngine.html">IEngine</a> and invoke <code>setLocale()</code> on it.
+This will change the value stored in the engine (which is used when loading new pages), and:
+</p>
+
+<ul>
+  <li>Update the hivemind.ThreadLocale service, allowing localized messages from services to be generated
+    in the correct locale</li>
+  <li>Cause an HTTP Cookie to be added to the request so that future requests from the same client
+    will be in the same locale</li>
+</ul>
+
+<p>
+  Changing the locale <a href="#localization.engine-locale">does not affect any pages loaded
+    in the current request.</a>
+</p>
+ 
+  
+</section>    
+    
+    <section name="Engine locale vs. page locale">
+      
+      
+<p>
+When pages are created, or obtained from the page pool, the engine's locale is
+taken into account.  Pages are obtained when they are used by a service,
+or when accessed via <a href="../tapestry/apidocs/org/apache/tapestry/IRequestCycle.html">IRequestCycle</a>.getPage().
+</p>      
+      
+<p>
+A page is loaded for a particular locale, and the page's locale never changes.
+This is because of the degree to which localization creeps into the properties
+of the page and the components within the page.
+</p>      
+
+<p>
+Additionally, once a page  is loaded during a request cycle, it is kept
+for the duration of the cycle ... even if the engine locale changes.
+</p>
+
+<p>
+If you have a listener method on a page that changes the engine's locale, it is necessary to activate a <em>different</em>
+page to render the response.  This new page will be loaded in the new locale.
+</p>
+
+<p>
+<strong>Note:</strong>
+<br/>
+This may be addressed somewhat in Tapestry 4.0.  Two options are possible: a service for
+changing the locale before rendering a page, and a way to force Tapestry to re-load a page, in a new
+locale.
+</p>
+      
+    </section>
+    
+<section name="Limiting accepted locales">
+  
+  
+<p>
+By default, Tapestry accepts incoming locales (as specified in the request HTTP header) as-is. The requested
+locale is used as-is.  This has some implications, primarily in terms of resource usage.  
+</p>  
+
+<p>
+Imagine an application that is being accessed by users in the US, the UK and in Canada. The incoming request
+locales will be "en_US", "en_UK" and "en_CA" (respectively). However, it is likely that you will only have
+created a single localization, for English in general (locale "en").  Despite this, there will be several different
+versions of each page in the page pool: one for each of the above locales, even though they will be functionally identical.
+</p>
+
+<p>
+Ideally, what we want is to limit incoming requests so that all of the listed locales ("en_US", "en_UK" and "en_CA") will
+be 'filtered down' to just "en".
+</p>
+
+<p>
+That functionality is controlled by the org.apache.tapestry.accepted-locales <a href="configuration.html#configuration.properties">configuration property</a>. By setting
+this property to a comma-seperated list of local names, incoming requests will be converted
+to the closest match.  For example, the the property could be configured to "en,fr,de" to support English, French and German.
+</p>
+
+<p>
+Matching takes place by stripping off "terms" (the locale variant, then the locale country code) from the locale name.  So "en_US" would be stripped to "en" (which would match).
+When no match can be found, the <em>first</em> locale in the list is treated as the default.  In the prior example, Russian users
+would be matched to the "en" locale.
+</p>
+
+</section>    
+  </body>
+</document>

Propchange: tapestry/tapestry4/trunk/src/site/xdoc/UsersGuide/localization.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tapestry/tapestry4/trunk/src/site/xdoc/UsersGuide/page-class.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/src/site/xdoc/UsersGuide/page-class.xml?rev=418665&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/src/site/xdoc/UsersGuide/page-class.xml (added)
+++ tapestry/tapestry4/trunk/src/site/xdoc/UsersGuide/page-class.xml Sun Jul  2 17:17:29 2006
@@ -0,0 +1,116 @@
+<?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>Determining the Page Class</title>
+</properties>
+<body>
+<p>
+  When it comes time for Tapestry to instantiate a page, it must identify the Java class
+  to instantiate.
+</p>
+
+<p>
+Tapestry pages implement the <a href="../tapestry/apidocs/org/apache/tapestry/IPage.html">IPage</a> interface.  Because this is a large interface,
+you will typically extends the <a href="../tapestry/apidocs/org/apache/tapestry/html/BasePage.html">BasePage</a> base class (for HTML pages).
+</p>
+
+<p>
+Typically, you will identify the page class within the page's specification, using
+the <a href="spec.html#spec.page-specification">&lt;page-specification&gt;</a> element's class attribute.
+</p>
+
+<p>
+In many cases, however, the page specification is optional.  Alternately, the class
+attribute may be omitted from the page specification.  Tapestry takes the following steps
+to find the class for a page:
+</p>
+
+<ul>
+  <li>As indicated in the page specification</li>
+  <li>By searching the packages listed in the application specification (more below)</li>
+  <li>The application specification's org.apache.tapestry.default-page-class property</li>
+  <li>The global property org.apache.tapestry.default-page-class</li>
+</ul>
+
+<p>
+The most useful of these is the second option, to search.  For this step,
+Tapestry looks in the application specification
+for the org.apache.tapestry.page-class-packages <a href="spec.html#spec.meta">&lt;meta&gt;</a> property. This
+is a comma-seperated list of package names to search.  The list of packages is
+optional, and the default Java package is searched last.
+</p>
+
+<p>
+Also, for this search, the page name is converted into a partial class name. For pages
+inside folders, the folder names are part of the package name, so page name
+<code>admin/EditUser</code> will be become <code>admin.EditUser</code>.
+</p>
+
+<p>
+So, if the prefix list is <code>org.example.pages</code>, then Tapestry will search
+for <code>org.example.pages.admin.EditUser</code>, then
+<code>admin.EditUser</code> (that is, in the default package).
+</p>
+
+<p>
+Only if those searches fail to locate a class  does Tapestry continue to the next steps, using
+default page class names in the application specification and beyond.
+</p>
+
+<p>
+<strong>Note:</strong>
+<br/>
+These steps are specified in the
+<a href="../tapestry/hivedocs/config/tapestry.page.PageClassProviderChain.html">tapestry.page.PageClassProviderChain</a>
+configuration point.
+</p>
+
+<p>
+For simplicity, we described the search for application pages. For pages within a library, the process
+is the same, but it is the library's specification which is searched for the list of packages,
+and later, for the default page class name.
+</p>
+
+<section name="Component Classes">
+  
+  
+<p>
+A similar search occurs for components (again, with the express desire that the class attribute of the
+<a href="spec.html#spec.component-specification">&lt;component-specification&gt;</a> <em>not</em> be used).  
+</p>
+
+<ul>
+  <li>As defined by the component specification</li>
+  <li>In any package defined by the containing namespace's org.apache.tapestry.component-class-packages
+    meta data property (if any)</li>
+  <li>In the default package</li>
+  <li>
+<a href="../tapestry/apidocs/org/apache/tapestry/BaseComponent.html">BaseComponent</a> is the final default</li>
+</ul>
+
+<p>
+<strong>Note:</strong>
+<br/>
+These steps are specified in the
+<a href="../tapestry/hivedocs/config/tapestry.page.ComponentClassProviderChain.html">tapestry.page.ComponentClassProviderChain</a>
+configuration point.
+</p>
+</section>
+
+</body>
+</document>

Propchange: tapestry/tapestry4/trunk/src/site/xdoc/UsersGuide/page-class.xml
------------------------------------------------------------------------------
    svn:eol-style = native