blob: 8f4dc4481da66fa51e25d8685ad47ed6493b5859 [file] [log] [blame]
<!-- $Id$ -->
<!--
Copyright 2004 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.
-->
<chapter id="configuration">
<title>Configuring Tapestry</title>
<section id="configuration.requirements">
<title>Requirements</title>
<para>
Tapestry is designed to operate on a variety of different JVMs and versions of
the Java Servlet API. Below you can find the list of supported and
tested configurations:
</para>
<variablelist>
<title>Supported Java Versions</title>
<varlistentry>
<term>Java 1.2.2</term>
<listitem>
<para>
Operates correctly. Requires the Xerces parser to be in the classpath
(usually provided by the servlet container).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Java 1.3.x</term>
<listitem>
<para>
Operates correctly. Requires the Xerces parser to be in the classpath
(usually provided by the servlet container).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Java 1.4.x (recommended)</term>
<listitem>
<para>
Operates correctly.
</para>
</listitem>
</varlistentry>
</variablelist>
<variablelist>
<title>Supported Java Servlet API Versions</title>
<varlistentry>
<term>Java Servlet API 2.2</term>
<listitem>
<para>
Operates correctly with minor exceptions related to character encoding
of the requests due to the limitations of the Servlet API version.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Java Servlet API 2.3 (recommended)</term>
<listitem>
<para>
Operates correctly.
</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section id="configuration.deployment-descriptor">
<title>Web deployment descriptor</title>
<para>
All Tapestry applications make use of the &ApplicationServlet; class as their
servlet; it is rarely necessary to create a subclass.
</para>
<example>
<title>Web Deployment Descriptor</title>
<programlisting>
&lt;?xml version="1.0"?&gt;
&lt;!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd"&gt;
&lt;web-app&gt;
&lt;distributable/&gt; <co id="configuration.web.distributable"/>
&lt;display-name&gt;My Application&lt;/display-name&gt;
&lt;servlet&gt;
&lt;servlet-name&gt;myapp&lt;/servlet-name&gt; <co id="configuration.web.servlet-name"/>
&lt;servlet-class&gt;org.apache.tapestry.&ApplicationServlet;&lt;/servlet-class&gt; <co id="configuration.web.servlet-class"/>
&lt;load-on-startup&gt;0&lt;/load-on-startup&gt; <co id="configuration.load-on-startup"/>
&lt;/servlet&gt;
&lt;servlet-mapping&gt;
&lt;servlet-name&gt;myapp&lt;/servlet-name&gt;
&lt;url-pattern&gt;/app&lt;/url-pattern&gt; <co id="configuration.web.url"/>
&lt;/servlet-mapping&gt;
&lt;filter&gt; <co id="configuration.web.filter"/>
&lt;filter-name&gt;redirect&lt;/filter-name&gt;
&lt;filter-class&gt;org.apache.tapestry.&RedirectFilter;&lt;/filter-class&gt;
&lt;/filter&gt;
&lt;filter-mapping&gt;
&lt;filter-name&gt;redirect&lt;/filter-name&gt;
&lt;url-pattern&gt;/&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;
&lt;session-config&gt;
&lt;session-timeout&gt;15&lt;/session-timeout&gt;
&lt;/session-config&gt;
&lt;welcome-file-list&gt;
&lt;welcome-file&gt;index.html&lt;/welcome-file&gt;
&lt;/welcome-file-list&gt;
&lt;/web-app&gt;
</programlisting>
</example>
<calloutlist>
<callout arearefs="configuration.web.distributable">
<para>
This indicates to the application server that the Tapestry application may be clustered. Most
application servers ignore this element, but future servers may only distribute
applications within a cluster if this element is present.
</para>
<warning>
<title>JBoss is very literal!</title>
JBoss 3.0.x appears to be very literal about the <sgmltag class="starttag">distributable</sgmltag>
element. If it appears, you had better be deploying into a clustered environment, otherwise
HttpSession state management simply doesn't work.
</warning>
</callout>
<callout arearefs="configuration.web.servlet-name">
<para>
The servlet name may be used when locating the application specification (though
not in this example).
</para>
</callout>
<callout arearefs="configuration.web.servlet-class">
<para>
The servlet class is nearly always &ApplicationServlet;. There's rarely
a need to create a subclass; Tapestry has many other hooks for extending the
application.
</para>
</callout>
<callout arearefs="configuration.load-on-startup">
<para>
It is generally a good idea to specify
<sgmltag class="starttag">load-on-startup</sgmltag>, this causes
the servlet container to instantitate and initialize the the application servlet, which in turn,
reads the Tapestry application specification. Many common development errors will be spotted immediately,
rather than when the first application request arrives.
</para>
</callout>
<callout arearefs="configuration.web.url">
<para>
The servlet is mapped to <filename>/app</filename> within the context. The context
itself has a path, determined by the application server and based on the name of the WAR file.
The client web browser will see the Tapestry application
as <filename>http://<replaceable>host</replaceable>/<replaceable>war-name</replaceable>/app</filename>.
</para>
<para>
Using <filename>/app</filename> as the URL is a common convention when creating
Tapestry applications, but is not a requirement. The framework will adapt to whatever mapping
you select.
</para>
</callout>
<callout arearefs="configuration.web.filter">
<para>
This filter sends a client redirect to the user when they access the web application context. The filter
sends a client redirect to the user's browser, directing them to the application servlet. In this way,
the "public" URL for an application can be <literal>http://myserver/mycontext/</literal> when, in fact,
the real address is <literal>http://myserver/mycontext/app</literal>.
</para>
</callout>
</calloutlist>
<para>
On initialization, the Tapestry servlet will locate its
application specification; a file that identifies details about the
application, the pages and components within it, and any
component libraries it uses. Tapestry provides a great deal of
flexibility on where the specification is stored; trivial Tapestry
applications can operate without an application specification.
</para>
<para>
The specification is normally
stored under &WEB-INF;. In fact, Tapestry performs a search to find the specification:
</para>
<orderedlist>
<listitem>
<para>
On the classpath, as defined by the <literal>org.apache.tapestry.application-specification</literal>
configuration parameter.
</para>
</listitem>
<listitem>
<para>
As <filename>/WEB-INF/<replaceable>name</replaceable>/<replaceable>name</replaceable>.application</filename>.
The <replaceable>name</replaceable> is the servlet name. This location
is only used in the rare case of a single WAR containing multiple Tapestry
applications.
</para>
</listitem>
<listitem>
<para>
As <filename>/WEB-INF/<replaceable>name</replaceable>.application</filename>.
Again, <replaceable>name</replaceable> is the
servlet name. This is the standard location.
</para>
</listitem>
</orderedlist>
<para>
If the application specification still can not be found, then an empty, "stand in"
application specification is used. This is perfectly acceptible ... an application specification is typically
needed only when an application makes use of component libraries, or requires some other kind of customization
only possible with an application specification.
</para>
</section> <!-- configuration.deployment-descriptor -->
<section id="configuration.search-path">
<title>Configuration Search Path</title>
<para>
Tapestry occasionally must obtain a value for a configuration property. These configuration
properties are items that are frequently optional, and don't fit into any particular
specification. Many are related to the runtime environment, such as which class to instantiate as the
Visit object.
</para>
<para>
Tapestry
is very flexible about where values for such properties may be obtained. In general,
the search path for configuration properties is:
</para>
<itemizedlist>
<listitem>
<para>
As a &spec.property; of the &spec.application; (in the application specification,
if the application uses one).
</para>
</listitem>
<listitem>
<para>
As an <sgmltag class="starttag">init-parameter</sgmltag>
for the servlet, in the web application deployment descriptor.
</para>
</listitem>
<listitem>
<para>
As an <sgmltag class="starttag">init-parameter</sgmltag>
for the servlet context, also in the web application deployment descriptor.
</para>
</listitem>
<listitem>
<para>
As a JVM system property.
</para>
</listitem>
<listitem>
<para>
Hard-coded "factory" defaults (for some properties).
</para>
</listitem>
</itemizedlist>
<para>
It is expected that some configurations are not defined at any level; those will
return null.
</para>
<para>
Applications are free to leverage this lookup mechanism as well. &IEngine; defines
a <varname>propertySource</varname> property (of type &IPropertySource;)
that can be used to perform such lookups.
</para>
<para>
Applications may also want to change or augment
the default search path; this is accomplished by overriding
&AbstractEngine; method <function>createPropertySource()</function>. For example,
some configuration data could be drawn from a database.
</para>
<para>
The following are all the configuration values
currently used in Tapestry:
<variablelist>
<title>Configuration Values</title>
<varlistentry>
<term><literal>org.apache.tapestry.template-extension</literal></term>
<listitem>
<para>
Overrides the default extension used to locate templates for pages or components.
The default extension is "html", this configuration property
allows overrides where appropriate. For example,
an application that produces WML may want to override this to "wml".
</para>
<para>
This configuration property does not follow the normal search path rules. The
&spec.property; must be provided in the &spec.page-specification; or &spec.component-specification;.
If no value is found there, the immediate containing &spec.application; or
&spec.library-specification; is checked. If still not found, the default is used.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>org.apache.tapestry.asset.dir</literal></term>
<term><literal>org.apache.tapestry.asset.URL</literal></term>
<listitem>
<para>
These two values are used to handle private assets. Private assets are assets
that are stored on the classpath, and not normally visible to client web browsers.
</para>
<para>
By specifying these two configuration values, Tapestry can export private assets
to a directory that is visible to the client web browser. The <literal>URL</literal>
value should map to the directory specified by the <literal>dir</literal> value.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>org.apache.tapestry.visit-class</literal></term>
<listitem>
<para>
The fully qualified class name to instantiate as the
<link linkend="intro.engine-service-visit">Visit object</link>.
</para>
<para>
If not specified, an instance of &HashMap; will be created.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>org.apache.tapestry.default-page-class</literal></term>
<listitem>
<para>
By default, any page that omits the
<varname>class</varname> attribute (in its &spec.page-specification;)
will be instantiated as &BasePage;. If this is not desired,
the default may be overridden by specifying a fully
qualified class name.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>org.apache.tapestry.engine-class</literal></term>
<listitem>
<para>
The fully qualified class name to instantiate as the application engine.
This configuration value is only used when the
application specification does not exist, or fails to
specify a class. By default, &BaseEngine; is used if this configuration
value is also left unspecified.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>org.apache.tapestry.enhance.disable-abstract-method-validation</literal></term>
<listitem>
<para>
Used to work around a bug in IBM's JDK 1.3.1. This JDK reports <emphasis>all</emphasis> methods
of an abstract class as abstract, even if they are concrete. This causes spurious errors
about unimplemented abstract methods. Specifying <literal>true</literal> for this property
disables checks for unimplemented abstract methods.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>org.apache.tapestry.global-class</literal></term>
<listitem>
<para>
The fully qualified class name to instantiate as the engine <literal>global</literal>
property. The Global object is much like Visit object,
except that it is shared by all instances
of the application engine rather than being private to any particular session.
If not specified, a synchronized instance of &HashMap; is used.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>org.apache.tapestry.default-script-language</literal></term>
<listitem>
<para>
The name of a &BSF;-supported language, used when a
&spec.listener-binding; element does not specify
a language. If not overridden, the default is "jython".
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>org.apache.tapestry.enable-reset-service</literal></term>
<listitem>
<para>
If not specified as "true", then the <literal>reset</literal> service
will be non-functional. The reset service is used to force
the running Tapestry application to discard all cached data (including
templates, specifications, pooled objects and more). This must
be explicitly enabled, and should only be used in development (in production,
it is too easily exploited as a denial of service attack).
</para>
<para>
Unlike most other configuration values, this must be specified
as a JVM system property.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>org.apache.tapestry.disable-caching</literal></term>
<listitem>
<para>
If specified (as "true"), then the framework will discard all cached data
(specifications, templates, pooled objects, etc.) at the end of each request cycle.
</para>
<para>
This slows down request handling by a noticable amount, but is very
useful in development; it means that changes to templates and specifications
are immediately visible to the application. It also helps identify
any errors in managing persistent page state.
</para>
<para>
This should never be enabled in production; the performance hit is too large.
Unlike most other configuration values, this must be specified
as a JVM system property.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>org.apache.tapestry.output-encoding</literal></term>
<listitem>
<para>
Defines the character set used by the application to encode its HTTP responses.
This is also the character set that the application assumes that the browser uses
when submitting data unless it is not specified differently in the HTTP request.
</para>
<para>
The default for this configuration property is UTF-8.
Normally there is no need to modify this value since UTF-8 allows almost all
characters to be correctly encoded and displayed.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>org.apache.tapestry.template-encoding</literal></term>
<listitem>
<para>
Defines the character set used by the application templates.
The default value is ISO-8859-1.
</para>
<para>
Please see the &configuration.character-sets; section for more information.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</section> <!-- configuration.search-path -->
<section id="configuration.extensions">
<title>Application extensions</title>
<para>Tapestry is designed for flexibility; this extends beyond simply
configuring the framework, and encompasses actually replacing or augmenting the implementation
of the framework. If Tapestry doesn't do what you want it to, there are multiple paths
for extending, changing and overriding its normal behavior.
In some cases,
it is necessary to subclass framework classes in order to alter behavior, but in
many cases, it is possible to use an application extension.
</para>
<para>
Application extensions are JavaBeans declared in the application specification using
the &spec.extension; element. Each extension consists of a name, a Java class
to instantiate, and an optional configuration (that is, properties of the
bean may be set). The framework has a finite number of extension points. If an extension
bean with the correct name exists, it will be used at that extension point.
</para>
<para>
Your application may have its own set of extensions not related to Tapestry framework extension points.
For example, you might have an application extension referenced from multiple pages to perform common
operations such as JNDI lookups.
</para>
<para>
You may access application extensions via the engine's specification property. For example:
<informalexample><programlisting>
&IEngine; engine = getEngine();
&IApplicationSpecification; specification = engine.getSpecification();
myExtension myExtension = (MyExtension) specification.getExtension("myExtension");
</programlisting>
</informalexample>
</para>
<para>
Each application extension used with an framework extension point must implement an interface particular
to the extension point.
</para>
<variablelist>
<title>Application Extension Points</title>
<varlistentry>
<term><literal>org.apache.tapestry.property-source</literal> (&IPropertySource;)</term>
<listitem>
<para>
This extension
is fit into the configuration property search path, after the servlet context, but
before JVM system properties. A typical use would be to access some set of configuration
properties stored in a database.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>org.apache.tapestry.request-decoder</literal> (&IRequestDecoder;)</term>
<listitem>
<para>
A request decoder is used
to identify the actual server name, server port, scheme and request URI for the
request. In some configurations, a firewall may invalidate the values provided by
the actual &HttpServletRequest; (the values reflect the internal server forwarded
to by the firewall, not the actual values used by the external client). A
request decoder knows how to determine the actual values.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>org.apache.tapestry.monitor-factory</literal> (&IMonitorFactory;)</term>
<listitem>
<para>An object that is used to create &IMonitor; instances. Monitors
are informed about key application events (such as loading a page)
during the processing of a request.
</para>
<para>
The factory may create a new instance for the request, or may simply
provide access to a shared instance.
</para>
<para>
If not specified, a default implementation is used (&DefaultMonitorFactory;).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>org.apache.tapestry.specification-resolver-delegate</literal> (&ISpecificationResolverDelegate;)</term>
<listitem>
<para>
An object which is used to find page and component specifications that are not located
using the default search rules. The use of this is open-ended, but is generally
useful in very advanced scenarios where specifications are stored externally
(perhaps in a database), or constructed on the fly.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>org.apache.tapestry.template-source-delegate</literal> (&ITemplateSourceDelegate;)</term>
<listitem>
<para>
An object which is used to find page or component templates that are not located
using the default search rules. The use of this is open-ended, but is generally
useful in very advanced scenarios where templates are stored externally
(perhaps in a database), or constructed on the fly.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>org.apache.tapestry.multipart-decoder</literal> (&IMultipartDecoder;)</term>
<listitem>
<para>
Allows an alternate object to be responsible for decoding multipart requests (context
type multipart/form-data, used for file uploads). Generally, this is used to
configure an instance of &DefaultMultipartDecoder; with non-default values for
the maximum upload size, threshold size (number of bytes before a temporary file is created
to store the) and repository directory (where temporary files are stored).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>org.apache.tapestry.ognl-type-converter</literal></term>
<listitem>
<para>
Specifies an implementation of ognl.TypeConverter to be used for expression bindings.
See OGNL's <ulink url="http://www.ognl.org/2.6.3/Documentation/html/typeConversion.html">Type
Converter documentation</ulink>
for further information on implementing a custom type converter.
</para>
</listitem>
</varlistentry>
</variablelist>
</section> <!-- configuration.extensions -->
<section id="configuration.character-sets">
<title>Character Sets</title>
<para>
Tapestry is designed to make the web application localization easy and
offers the ability to define different localized templates for the same component.
For example, <filename>Home.html</filename> would be the default template of the Home page, however
<filename>Home_fr.html</filename> would be used in all French locales, while <filename>Home_zh_CN.html</filename> would be used in
China and <filename>Home_zh_TW.html</filename> would be used in Taiwan.
</para>
<para>
Web developers and designers in different countries tend to use different character sets
for the templates they produce. English, German, French templates are typically produced in
ISO-8859-1, Russian templates often use KOI8-R, and Chinese texts are normally written in Big5.
Tapestry allows the application to configure the character set used in its templates
and makes it possible to use different character sets for templates associated with
different components and different locales.
</para>
<para>
The character set of a template is defined using the
<literal>org.apache.tapestry.template-encoding</literal>
&configuration-property;. The search path of this property is slightly different then the
standard one and allows specific components to use other character sets:
</para>
<itemizedlist>
<listitem>
<para>
As a &spec.property; of the &spec.page-specification; or the &spec.component-specification;
(in the page or component specification).
</para>
<para>
This configuration will apply only to the page or component where it is defined.
</para>
</listitem>
<listitem>
<para>
As a &spec.property; of the &spec.library-specification;
(in the library specification, if the components are included in a library).
</para>
<para>
This configuration will apply to all pages and components in the library.
</para>
</listitem>
<listitem>
<para>
As a &spec.property; of the &spec.application; (in the application specification,
if the application uses one).
</para>
</listitem>
<listitem>
<para>
As an <sgmltag class="starttag">init-parameter</sgmltag>
for the servlet, in the web application deployment descriptor.
</para>
</listitem>
<listitem>
<para>
As an <sgmltag class="starttag">init-parameter</sgmltag>
for the servlet context, also in the web application deployment descriptor.
</para>
</listitem>
<listitem>
<para>
As a JVM system property.
</para>
</listitem>
<listitem>
<para>
The hard-coded default "ISO-8859-1".
</para>
</listitem>
</itemizedlist>
<para>
Tapestry also makes it possible to define the character set used by the templates specific
to a particular locale by appending the locale to the property name above.
As an example, the
<literal>org.apache.tapestry.template-encoding_ru</literal> configuration property would define
the character set used by the Russian templates, such as <filename>Home_ru.html</filename>.
This allows templates for different locales to use different character sets,
even though they are in the same application.
For example, it is possible for all Russian templates in the application to use the KOI8-R
character set and all Chinese templates to use Big5 at the same time.
</para>
<para>
The character sets used by the templates do not reflect in any way on the character set
Tapestry uses to encode its response to the browser. The character sets are used when reading
the template to translate it appropriately into Unicode.
The output character set is defined by the
<literal>org.apache.tapestry.output-encoding</literal> configuration property.
</para>
</section> <!-- configuration.character-sets -->
</chapter>