You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@click.apache.org by sa...@apache.org on 2009/03/11 19:55:50 UTC
svn commit: r752572 [2/3] - in /incubator/click/trunk/click/documentation:
./ docs/ xdocs/ xdocs/src/ xdocs/src/css/ xdocs/src/css/html/
xdocs/src/docbook/ xdocs/src/docbook/click/ xdocs/src/images/
xdocs/src/images/best-practices/ xdocs/src/images/con...
Added: incubator/click/trunk/click/documentation/xdocs/src/docbook/click/chapter-configuration.xml
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/documentation/xdocs/src/docbook/click/chapter-configuration.xml?rev=752572&view=auto
==============================================================================
--- incubator/click/trunk/click/documentation/xdocs/src/docbook/click/chapter-configuration.xml (added)
+++ incubator/click/trunk/click/documentation/xdocs/src/docbook/click/chapter-configuration.xml Wed Mar 11 18:55:49 2009
@@ -0,0 +1,1053 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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="chapter-configuration" remap="h1">
+ <title>Configuration</title>
+
+ <para>This section discusses how to setup and configure a Click web application
+ and covers the following topics:
+ </para>
+
+ <orderedlist>
+ <listitem>
+ <para>
+ <link linkend="servlet-configuration">Servlet Configuration</link>
+ - how to setup the ClickServlet
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <link linkend="application-configuration">Application Configuration</link>
+ - how to configure the Click application descriptor
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <link linkend="auto-deployed-files">Auto Deployed Files</link>
+ - automatically deployed Click files
+ </para>
+ </listitem>
+ </orderedlist>
+
+ <para>The Click configuration files include:
+ </para>
+
+ <informaltable frame="none">
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="30*"/>
+ <colspec colname="c2" colwidth="70*"/>
+ <tbody>
+ <row>
+ <entry>
+ <inlinemediaobject>
+ <imageobject>
+ <imagedata fileref="images/configuration/config-files.png" format="PNG" scale="85"/>
+ </imageobject>
+ </inlinemediaobject>
+ </entry>
+ <entry>
+ <itemizedlist>
+ <listitem>
+ <para> WEB-INF/
+ <link linkend="application-configuration">click.xml</link>
+ - Application Configuration (
+ <emphasis role="bold">required</emphasis>)
+ </para>
+ </listitem>
+ <listitem>
+ <para> WEB-INF/
+ <link linkend="servlet-configuration">web.xml</link>
+ - Servlet Configuration (
+ <emphasis role="bold">required</emphasis>)
+ </para>
+ </listitem>
+ </itemizedlist>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <sect1 id="servlet-configuration" remap="h2">
+ <title>Servlet Configuration</title>
+
+ <para>For a Click web application to function the
+ <ulink url="../../click-api/org/apache/click/ClickServlet.html">ClickServlet</ulink>
+ must be configured in the web application's <filename>/WEB-INF/web.xml</filename>
+ file. A basic web application which maps all <literal>*.htm</literal> requests
+ to a ClickServlet is provided below.
+ </para>
+
+ <programlisting language="xml"><web-app>
+
+ <servlet>
+ <servlet-name>ClickServlet</servlet-name>
+ <servlet-class>org.apache.click.ClickServlet</servlet-class>
+ <load-on-startup>0</load-on-startup>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>ClickServlet</servlet-name>
+ <url-pattern>*.htm</url-pattern>
+ </servlet-mapping>
+
+</web-app></programlisting>
+
+ <sect2 id="servlet-mapping" remap="h3">
+ <title>Servlet Mapping</title>
+
+ <para>By convention all Click page templates should have a .htm extension,
+ and the ClickServlet should be mapped to process all *.htm URL requests.
+ With this convention you have all the static HTML pages use a .html extension
+ and they will not be processed as Click pages.
+ </para>
+
+ </sect2>
+
+ <sect2 id="load-on-startup" remap="h3">
+ <title>Load On Startup</title>
+
+ <para>Note you should always set <literal>load-on-startup</literal> element
+ to be 0 so the servlet is initialized when the server is started. This will
+ prevent any delay for the first client which uses the application.
+ </para>
+
+ <para>The <classname>ClickServlet</classname> performs as much work as possible
+ at startup to improve performance later on. The Click start up and caching
+ strategy is configured with the Click application mode element in the
+ "<filename>click.xml</filename>" config file, covered next.
+ </para>
+
+ </sect2>
+ </sect1>
+
+ <sect1 id="application-configuration" remap="h2">
+ <title>Application Configuration</title>
+
+ <para> The heart of a Click application is the <filename>click.xml</filename>
+ configuration file. This file specifies the application pages, headers, the
+ format object and the applications mode.
+ </para>
+
+ <para>By default the ClickServlet will attempt to load the application
+ configuration file using the path: <filename>/WEB-INF/click.xml</filename>
+ </para>
+
+ <para>If this file is not found under the <literal>WEB-INF</literal> directory,
+ then ClickServlet will attempt to load it from the classpath as
+ <filename>/click.xml</filename>.
+ </para>
+
+ <para>See <ulink url="../../click-dtd.html">Click DTD</ulink> for the click-app
+ XML definition.
+ </para>
+
+ <para>A complete Click configuration example is available
+ <ulink url="../../click-dtd-example.html">here</ulink> which can be used as a quick
+ reference when configuring Click.
+ </para>
+
+ <para>A basic Click app config file is provided below:
+ </para>
+
+ <programlisting language="xml"><click-app>
+
+ <pages package="com.mycorp.page"/>
+
+ <mode value="profile"/>
+
+</click-app></programlisting>
+
+ <para>An advanced config file would look like this:
+ </para>
+
+ <programlisting language="xml"><click-app charset="UTF-8" locale="de">
+
+ <pages package="com.mycorp.banking.page">
+ <page path="index.htm" classname="com.mycorp.page.Home"/>
+ </pages>
+
+ <pages package="com.mycorp.common.page"/>
+
+ <format classname="com.mycorp.util.Format"/>
+
+ <mode value="profile"/>
+
+ <log-service classname="org.apache.click.extras.service.Log4JLogService"/>
+
+</click-app></programlisting>
+
+ <para>The take away point is that there is not much to configure, even for
+ advanced uses.
+ </para>
+
+ <sect2 id="click-app" remap="h3">
+ <title>Click App</title>
+
+ <para>The root <symbol>click-app</symbol> element defines two application
+ localization attributes <varname>charset</varname> and <varname>locale</varname>.
+ </para>
+
+ <literallayout><!ELEMENT <symbol>click-app</symbol> (pages*, headers?, format?, mode?, controls?,
+ file-upload-service?, log-service?, template-service?)>
+ <!ATTLIST click-app <varname>charset</varname> CDATA #IMPLIED>
+ <!ATTLIST click-app <varname>locale</varname> CDATA #IMPLIED></literallayout>
+
+ <para>The <varname>charset</varname> attribute defines the character encoding
+ set for:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Velocity templates</para>
+ </listitem>
+ <listitem>
+ <para>HttpServletRequest character encoding</para>
+ </listitem>
+ <listitem>
+ <para>Page Content-Type charset, see Page
+ <ulink url="../../click-api/org/apache/click/Page.html#getContentType()">getContentType()</ulink>
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>The <varname>locale</varname> attribute defines the default application
+ Locale. If this value is defined it will override Locale returned by the request.
+ Please see the Context
+ <ulink url="../../click-api/org/apache/click/Context.html#getLocale()">getLocale()</ulink>
+ for details. For example the folliwing configuration sets the application
+ character set to UTF-8 and the default Locale as German (de):
+ </para>
+
+ <programlisting language="xml"><click-app charset=" UTF-8" locale="de">
+ ..
+</click-app></programlisting>
+ </sect2>
+
+ <sect2 id="application-pages" remap="h3">
+ <title>Pages</title>
+
+ <para>The first child element of the click-app is the mandatory
+ <literal>pages</literal> element which defines the list of Click pages.
+ </para>
+
+ <literallayout><!ELEMENT <varname>pages</varname> (<symbol>page</symbol>*)>
+ <!ATTLIST pages <varname>package</varname> CDATA #IMPLIED>
+ <!ATTLIST pages <varname>automapping</varname> (true|false) "true">
+ <!ATTLIST pages <varname>autobinding</varname> (true|false) "true"></literallayout>
+
+ <para>The pages element can specify a default <varname>package</varname> name
+ which is prepended to the classname of any pages defined.
+ </para>
+
+ <para>The pages element also defines the <varname>automapping</varname> and
+ <varname>automapping</varname> attributes which is discussed in the
+ <link linkend="application-automapping">Page Automapping</link> and
+ <link linkend="application-autobinding">Page Autobinding</link> sections
+ respectively.
+ </para>
+
+ <sect3 id="application-multiple-packages" remap="h4">
+ <title>Multiple Pages Packages</title>
+
+ <para>Click can support multiple pages elements to enable the automapping
+ of multiple packages.
+ </para>
+
+ <programlisting language="xml"><click-app>
+
+ <pages package="com.mycorp.banking.page"/>
+
+ <pages package="com.mycorp.common.page"/>
+
+</click-app></programlisting>
+
+ <para>With multiple pages elements, pages are loaded in the order of the page
+ elements, with manual page elements being loaded before automapped pages.
+ Once a page template has been mapped to a Page class it will not be replaced
+ by a subsequent potential match. So pages elements at the top take priority
+ over lower pages elements.
+ </para>
+
+ </sect3>
+ </sect2>
+
+ <sect2 id="application-page" remap="h3">
+ <title>Page</title>
+
+ <para>The page element defines the Click application pages.
+ </para>
+
+ <literallayout><!ELEMENT <symbol>page</symbol>(<varname>header</varname>*)>
+ <!ATTLIST page <varname>path</varname> CDATA #REQUIRED>
+ <!ATTLIST page <varname>classname</varname> CDATA #REQUIRED></literallayout>
+
+ <para>Each page <varname>path</varname> must be unique, as the Click
+ application maps HTTP requests to the page paths.
+ </para>
+
+ <para>The Click application will create a new Page instance for
+ the given request using the configured page <varname>classname</varname>.
+ All pages must subclass
+ <ulink url="../../click-api/org/apache/click/Page.html">Page</ulink> and provide
+ a public no arguments constructor, so they can be instantiated.
+ </para>
+
+ <para>Pages can also define <varname>header</varname> values which are
+ discussed in the next topic.
+ </para>
+
+ <para>When the Click application starts up it will check all the page
+ definitions. If there is a critical configuration error the ClickSerlvet
+ will log an <literal>ERROR</literal> message and throw an
+ <ulink url="http://java.sun.com/products/servlet/2.3/javadoc/javax/servlet/UnavailableException.html">UnavailableException</ulink>.
+ If this occurs the click application will be permanently unavailable until
+ the error is fixed and the web app is restarted.
+ </para>
+
+ <sect3 id="application-automapping" remap="h4">
+ <title>Page Automapping</title>
+
+ <para> Page automapping will automatically configure application pages
+ using a simple set of rules. This enables you to greatly streamline your
+ configuration file as you only need to define pages which don't fit
+ the automapping rules.
+ </para>
+
+ <para>Automapping will attempt to associate each page template (*.htm)
+ and JSP file in the web application (excluding those under the WEB-INF
+ and click directories) to a Page class. Automapped pages are loaded after
+ the manually defined pages are loaded, and manually defined pages takes
+ preference. When automapping is enabled the Click application will log
+ the page mappings when in debug or trace mode.
+ </para>
+
+ <para>For example, given the following page path to class mapping:
+ </para>
+
+ <literallayout>index.htm => <token>com.mycorp.page.Home</token>
+search.htm => <token>com.mycorp.page.Search</token>
+contacts/contacts.htm => <token>com.mycorp.page.contacts.Contacts</token>
+security/login.htm => <token>com.mycorp.page.security.Login</token>
+security/logout.htm => <token>com.mycorp.page.security.Logout</token>
+security/change-password.htm => <token>com.mycorp.page.security.ChangePassword</token></literallayout>
+
+ <para>The above mapping could be configured manually by setting the
+ <symbol>automapping</symbol> attribute to "false" and using the package
+ prefix, for example:
+ </para>
+
+ <programlisting language="xml"><click-app>
+ <pages package="<token>com.mycorp.page</token>" <symbol>automapping</symbol>="false">
+ <page path="index.htm" classname="<token>Home</token>"/>
+ <page path="search.htm" classname="<token>Search</token>"/>
+ <page path="contacts/contacts.htm" classname="<token>contacts.Contacts</token>"/>
+ <page path="security/login.htm" classname="<token>security.Login</token>"/>
+ <page path="security/logout.htm" classname="<token>security.Logout</token>"/>
+ <page path="security/change-password.htm" classname="<token>security.ChangePassword</token>"/>
+ </pages>
+</click-app></programlisting>
+
+ <para>By using <symbol>automapping</symbol> the page paths will automatically
+ map to page classes: (except for Home page which doesn't automatically map
+ to index.html)
+ </para>
+
+ <programlisting language="xml"><click-app>
+ <pages package="<token>com.mycorp.page</token>" <symbol>automapping</symbol>="true">
+ <page path="index.htm" classname="Home"/>
+ </pages>
+</click-app></programlisting>
+
+ <para>Note <symbol>automapping</symbol> is true by default, so it could be
+ omitted from the configuration file.
+ </para>
+
+ <para>The page template name to classname convention is:
+ </para>
+
+ <literallayout>change-password.htm => <token>ChangePassword</token>
+change_password.htm => <token>ChangePassword</token>
+changePassword.htm => <token>ChangePassword</token>
+ChangePassword.htm => <token>ChangePassword</token></literallayout>
+
+ <para>When automapping pages, if a class cannot be found Click will attempt
+ to add the 'Page' suffix to the classname if not already present and map
+ this. For example:
+ </para>
+
+ <literallayout>customer.htm => <token>CustomerPage</token>
+change-password.htm => <token>ChangePasswordPage</token></literallayout>
+ </sect3>
+
+ <sect3 id="application-excludes" remap="h4">
+ <title>Automapping Excludes</title>
+
+ <para>With Page automapping there can be resources where you don't want
+ automapping applied. For example when using a JavaScript library with lots
+ of <literal>.htm</literal> files, you don't want automapping to try and
+ find Page class for each of these files. In these situations you can use
+ the pages <symbol>excludes</symbol> element.
+ </para>
+
+ <literallayout><!ELEMENT <symbol>excludes</symbol> (#PCDATA)>
+ <!ATTLIST excludes <varname>pattern</varname> CDATA #REQUIRED></literallayout>
+
+ <para>For example if our application uses the TinyMCE JavaScript library
+ we could configure our pages automapping to exclude all <literal>.htm</literal>
+ files under the <literal>/tiny_mce</literal> directory.
+ </para>
+
+ <programlisting language="xml"><click-app>
+ <pages package="com.mycorp.page">
+ <symbol><excludes</symbol> pattern="<varname>/tiny_mce/*</varname>"/>
+ </pages>
+</click-app></programlisting>
+
+ <para>The excludes pattern can specify multiple directories or files using a
+ comma separated notation. For example:
+ </para>
+
+ <programlisting language="xml"><click-app>
+ <pages package="com.mycorp.page">
+ <symbol><excludes</symbol> pattern="<varname>/dhtml/*, /tiny_mce/*, banner.htm, about.htm</varname>"/>
+ </pages>
+</click-app></programlisting>
+
+ <para>HTM files excluded from Page automapping are handled by an internal
+ Page class with caching headers enabled.
+ </para>
+
+ </sect3>
+
+ <sect3 id="application-autobinding" remap="h4">
+ <title>Page Autobinding</title>
+
+ <para>By default all pages have autobinding enabled. With autobinding
+ enabled the ClickServlet will automatically:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para> add any public controls to the page, after the page constructor
+ has been invoked
+ </para>
+ </listitem>
+ <listitem>
+ <para> if the public control's name is not defined, its name will be
+ set to the the value its field name
+ </para>
+ </listitem>
+ <listitem>
+ <para> bind any request parameters to public page fields, after page
+ constructor has been invoked. See
+ <ulink url="../../click-api/org/apache/click/ClickServlet.html#processPageRequestParams(org.apache.click.Page)">ClickServlet.processPageRequestParams(Page)</ulink>
+ for more details
+ </para>
+ </listitem>
+ <listitem>
+ <para> add any public page fields to the page model, before rendering</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>For example:
+ </para>
+
+ <programlisting language="java">public class EmployeePage extends Page {
+
+ public Form employeeForm = new Form();
+
+ public Table myTable = new Table();
+
+}</programlisting>
+
+ <para>In the example above the <varname>employeeForm</varname> and
+ <varname>myTable</varname> controls were not added to the page. Also note
+ that Form and Table do not have their names defined.
+ </para>
+
+ <para>When autobinding is enabled, ClickServlet will create a new Page and
+ add the public controls to the page. In the example above the
+ <varname>employeeForm</varname> and <varname>myTable</varname> will be
+ added to the page, as if you had invoked,
+ <methodname>addControl(employeeForm)</methodname> and
+ <methodname>addControl(myTable)</methodname>.
+ </para>
+
+ <para>The control's names were not defined so ClickServlet will set their
+ names to the value of their field/variable name. In this case the Form
+ name will be set to <varname>employeeForm</varname> while the Table name
+ will set to <varname>myTable</varname>.
+ </para>
+
+ <para>The above example is thus a shorthand way of writing the following:
+ </para>
+
+ <programlisting language="java">public class EmployeePage extends Page {
+
+ private Form employeeForm = new Form();
+
+ private Table myTable = new Table();
+
+ public void onInit() {
+ employeeForm.setName("employeeForm");
+ addControl(employeeForm);
+
+ myTable.setName("myTable");
+ addControl(myTable);
+ }
+}</programlisting>
+
+ <para>You can turn this behaviour off by setting the <symbol>autobinding</symbol>
+ attribute to false, for example:
+ </para>
+
+ <programlisting language="xml"><click-app>
+ <pages package="com.mycorp.page" <symbol>autobinding</symbol>="<varname>false</varname>"/>
+</click-app></programlisting>
+
+ </sect3>
+ </sect2>
+
+ <sect2 id="application-headers" remap="h3">
+ <title>Headers</title>
+
+ <para>The optional <literal>headers</literal> element defines a list of
+ <literal>header</literal> elements which are applied to all pages.
+ </para>
+
+ <literallayout><!ELEMENT <varname>headers</varname> (<symbol>header</symbol>*)></literallayout>
+
+ <para>The <symbol>header</symbol> element defines header name and value
+ pairs which are applied to the
+ <ulink url="http://java.sun.com/products/servlet/2.3/javadoc/javax/servlet/http/HttpServletResponse.html">HttpServletResponse</ulink>.
+ </para>
+
+ <literallayout><!ELEMENT <symbol>header</symbol> (#PCDATA)>
+ <!ATTLIST header <varname>name</varname> CDATA #REQUIRED>
+ <!ATTLIST header <varname>value</varname> CDATA #REQUIRED>
+ <!ATTLIST header <varname>type</varname> (String|Integer|Date) "String"></literallayout>
+
+ <para>Page headers are set after the Page has been constructed and before
+ <methodname>onInit()</methodname> is called. Pages can then modify their
+ <ulink url="../../click-api/org/apache/click/Page.html#headers">headers</ulink>
+ property using the
+ <ulink url="../../click-api/org/apache/click/Page.html#setHeader(java.lang.String,%20java.lang.Object)">setHeader()</ulink>
+ method.
+ </para>
+
+ <sect3 id="browser-caching" remap="h4">
+ <title>Browser Caching</title>
+
+ <para>Headers are typically used to switch off browser caching. By
+ default Click will use the following no caching header values if you don't
+ define a <literal>headers</literal> element in your application:
+ </para>
+
+ <programlisting language="xml"><click-app>
+ <pages>
+ ..
+ </pages>
+ <headers>
+ <header name="Pragma" value="no-cache"/>
+ <header name="Cache-Control"
+ value="no-store, no-cache, must-revalidate, post-check=0, pre-check=0"/>
+ <header name="Expires" value="1" type="Date"/>
+ </headers>
+</click-app></programlisting>
+
+ <para>Alternatively you can define your headers individually in pages or
+ for all application pages by setting header values. For example to switch
+ off caching in the login page, note the value for a Date type should
+ be a long number value:
+ </para>
+
+ <programlisting language="xml"><page path="login.htm" classname="com.mycorp.page.Login">
+ <header name="Pragma" value="no-cache"/>
+ <header name="Expires" value="1" type="Date"/>
+</page></programlisting>
+
+ <para>If you wanted to enable caching for a particular page you could set
+ the following page cache control header. This will mark the page as cachable
+ for a period of 1 hour after which it should be reloaded.
+ </para>
+
+ <programlisting language="xml"><page path="home.htm" classname="com.mycorp.page.Home">
+ <header name="Cache-Control" value="max-age=3600, public, must-revalidate"/>
+</page></programlisting>
+
+ <para>To apply header values globally define header values in the headers
+ element. For example:
+ </para>
+
+ <programlisting language="xml"><click-app>
+ <pages>
+ ..
+ </pages>
+ <headers>
+ <header name="Pragma" value="no-cache"/>
+ <header name="Cache-Control"
+ value="no-store, no-cache, must-revalidate, post-check=0, pre-check=0"/>
+ <header name="Expires" value="1" type="Date"/>
+ </headers>
+</click-app></programlisting>
+
+ </sect3>
+ </sect2>
+
+ <sect2 id="application-format" remap="h3">
+ <title>Format</title>
+
+ <para>The optional <literal>format</literal> element defines the Format
+ object classname which is applied to all pages.
+ </para>
+
+ <literallayout><!ELEMENT <symbol>format</symbol> (#PCDATA)>
+ <ATTLIST format <varname>classname</varname> CDATA #FIXED "org.apache.click.util.Format"></literallayout>
+
+ <para>By default all Click pages are configured with a
+ <ulink url="../../click-api/org/apache/click/util/Format.html">org.apache.click.util.Format</ulink>
+ object. The format object is made available in the Velocity page templates
+ using the name <varname>$format</varname>.
+ </para>
+
+ <para>To specify a custom format class configure a <literal>format</literal>
+ element in the click-app descriptor. For example:
+ </para>
+
+ <programlisting language="xml"><click-app>
+ ..
+ <symbol><format</symbol> classname="<varname>com.mycorp.util.CustomFormat</varname>"/>
+</click-app></programlisting>
+
+ </sect2>
+
+ <sect2 id="application-mode" remap="h3">
+ <title>Mode</title>
+
+ <para>The optional <literal>mode</literal> element defines the application
+ logging and caching mode.
+ </para>
+
+ <literallayout><!ELEMENT <symbol>mode</symbol> (#PCDATA)>
+ <ATTLIST mode value (<varname>production|profile|development|debug|trace</varname>) "development"></literallayout>
+
+ <para>By default Click applications run in <literal>development</literal> mode,
+ which switches off page template caching, and the logging level is set to
+ <literal>INFO</literal>.
+ </para>
+
+ <para>To change the default application mode configure a mode element in the
+ click-app descriptor. For example to specify <literal>production</literal>
+ mode you would add the following mode element:
+ </para>
+
+ <programlisting language="xml"><click-app>
+ ..
+ <symbol><mode</symbol> value="<varname>production</varname>">
+</click-app></programlisting>
+
+ <para>The application mode configuration can be overridden by setting the
+ system property <literal>"click.mode"</literal>. This can be use in the scenario
+ of debugging a problem on a production system, where you change the mode to
+ <literal>trace</literal> by setting the following system property and
+ restarting the application.
+ </para>
+
+ <literallayout>-Dclick.mode=trace</literallayout>
+
+ <para>The Click Application modes and their settings for Page auto loading,
+ template caching and logging levels are:
+ </para>
+
+ <informaltable frame="all">
+ <tgroup cols="5">
+ <colspec colname="c1" colwidth="20*"/>
+ <colspec colname="c2" colwidth="20*"/>
+ <colspec colname="c3" colwidth="20*"/>
+ <colspec colname="c4" colwidth="20*"/>
+ <colspec colname="c5" colwidth="20*"/>
+ <thead>
+ <row>
+ <?dbfo bgcolor="navy"?>
+ <entry>
+ <para>
+ Application mode
+ </para>
+ </entry>
+ <entry>
+ <para>
+ Page auto loading
+ </para>
+ </entry>
+ <entry>
+ <para>
+ Template caching
+ </para>
+ </entry>
+ <entry>
+ <para>
+ Click log level
+ </para>
+ </entry>
+ <entry>
+ <para>
+ Velocity log level
+ </para>
+ </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry align="center" valign="middle">
+ <para>
+ <emphasis role="bold">production</emphasis>
+ </para>
+ </entry>
+ <entry align="center" valign="middle">
+ <para>No</para>
+ </entry>
+ <entry align="center" valign="middle">
+ <para>Yes</para>
+ </entry>
+ <entry align="center" valign="middle">
+ <para>WARN</para>
+ </entry>
+ <entry align="center" valign="middle">
+ <para>ERROR</para>
+ </entry>
+ </row>
+ <row>
+ <entry align="center" valign="middle">
+ <para>
+ <emphasis role="bold">profile</emphasis>
+ </para>
+ </entry>
+ <entry align="center" valign="middle">
+ <para>No</para>
+ </entry>
+ <entry align="center" valign="middle">
+ <para>Yes</para>
+ </entry>
+ <entry align="center" valign="middle">
+ <para>INFO</para>
+ </entry>
+ <entry align="center" valign="middle">
+ <para>ERROR</para>
+ </entry>
+ </row>
+ <row>
+ <entry align="center" valign="middle">
+ <para>
+ <emphasis role="bold">development</emphasis>
+ </para>
+ </entry>
+ <entry align="center" valign="middle">
+ <para>Yes</para>
+ </entry>
+ <entry align="center" valign="middle">
+ <para>No</para>
+ </entry>
+ <entry align="center" valign="middle">
+ <para>INFO</para>
+ </entry>
+ <entry align="center" valign="middle">
+ <para>ERROR</para>
+ </entry>
+ </row>
+ <row>
+ <entry align="center" valign="middle">
+ <para>
+ <emphasis role="bold">debug</emphasis>
+ </para>
+ </entry>
+ <entry align="center" valign="middle">
+ <para>Yes</para>
+ </entry>
+ <entry align="center" valign="middle">
+ <para>No</para>
+ </entry>
+ <entry align="center" valign="middle">
+ <para>DEBUG</para>
+ </entry>
+ <entry align="center" valign="middle">
+ <para>ERROR</para>
+ </entry>
+ </row>
+ <row>
+ <entry align="center" valign="middle">
+ <para>
+ <emphasis role="bold">trace</emphasis>
+ </para>
+ </entry>
+ <entry align="center" valign="middle">
+ <para>Yes</para>
+ </entry>
+ <entry align="center" valign="middle">
+ <para>No</para>
+ </entry>
+ <entry align="center" valign="middle">
+ <para>TRACE</para>
+ </entry>
+ <entry align="center" valign="middle">
+ <para>WARN</para>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <sect3 id="page-auto-loading" remap="h4">
+ <title>Page Auto Loading</title>
+
+ <para>When Page Auto Loading is enabled any new page templates and classes
+ will be automatically loaded at runtime. These pages are loaded using the
+ <link linkend="application-automapping">Page Automapping</link> rules.
+ </para>
+
+ <para>Page auto loading is a very handy feature for rapid development as
+ you do not have to restart you application server to pick up new pages.
+ </para>
+
+ </sect3>
+
+ <sect3 id="click-logging" remap="h4">
+ <title>Click and Velocity Logging</title>
+
+ <para>The Click and Velocity runtimes use
+ <ulink url="../../click-api/org/apache/click/service/LogService.html">LogService</ulink>
+ for logging messages. The default LogService implementation is
+ <ulink url="../../click-api/org/apache/click/service/ConsoleLogService.html">ConsoleLogService</ulink>
+ which will send messages to the console [System.out]. For example the
+ following logging output is for a HomePage request when the application
+ mode is <literal>trace</literal>:
+ </para>
+
+ <literallayout>[Click] [debug] GET http://localhost:8080/quickstart/home.htm
+[Click] [trace] invoked: HomePage.<<init>>
+[Click] [trace] invoked: HomePage.onSecurityCheck() : true
+[Click] [trace] invoked: HomePage.onInit()
+[Click] [trace] invoked: HomePage.onGet()
+[Click] [trace] invoked: HomePage.onRender()
+[Click] [info ] renderTemplate: /home.htm - 6 ms
+[Click] [trace] invoked: HomePage.onDestroy()
+[Click] [info ] handleRequest: /home.htm - 24 ms</literallayout>
+
+ <para>Any unhandled <literal>Throwable</literal> errors are logged by the
+ ClickServlet.
+ </para>
+
+ <para>Note that Click Extras also provide log adaptors for
+ <ulink url="../../extras-api/org/apache/click/extras/service/Log4JLogService.html">Log4J</ulink>
+ and the <ulink url="../../extras-api/org/apache/click/extras/service/JdkLogService.html">JDK Logging API</ulink>.
+ </para>
+
+ <para>When an application is not in <literal>production</literal> mode the
+ error page displays detailed debugging information. When the application
+ mode is <literal>production</literal> no debug information is displayed to
+ prevent sensitive information being revealed. This behaviour can be changed
+ by modifying the deployed <filename>click/error.htm</filename> page template.
+ </para>
+
+ </sect3>
+ </sect2>
+
+ <sect2 id="application-controls" remap="h3">
+ <title>Controls</title>
+
+ <para>The optional <literal>controls</literal> element defines a list of
+ <literal>control</literal> elements which will be deployed on application
+ startup.
+ </para>
+
+ <literallayout><!ELEMENT <varname>controls</varname> (<symbol>control</symbol>*)></literallayout>
+
+ <para>The <symbol>control</symbol> registers
+ <ulink url="../../click-api/org/apache/click/Control.html">Control</ulink> classes
+ which will have their <ulink url="../../click-api/org/apache/click/Control.html#onDeploy(javax.servlet.ServletContext)">onDeploy()</ulink>
+ method invoked when the click application starts.
+ </para>
+
+ <literallayout><!ELEMENT <symbol>control</symbol> (#PCDATA)>
+ <!ATTLIST control <varname>classname</varname> CDATA #REQUIRED></literallayout>
+
+ <para>For example to have a <classname>CustomField</classname> control
+ deploy its resources on application startup, you would add the following
+ elements to your <filename>click.xml</filename> file:
+ </para>
+
+ <programlisting language="xml"><click-app>
+ ..
+
+ <controls>
+ <symbol><control</symbol> classname="<varname>com.mycorp.control.CustomField</varname>"/>
+ </controls>
+</click-app></programlisting>
+
+ </sect2>
+ </sect1>
+
+ <sect1 id="auto-deployed-files" remap="h2">
+ <title>Auto Deployed Files</title>
+
+ <para>To make pre-configured resources (templates, stylesheets, etc.)
+ available to web applications, Click automatically deploys configured
+ classpath resources to the <varname>/click</varname> directory at startup
+ (if not already present).
+ </para>
+
+ <para>You can modify these support files and Click will
+ <emphasis role="bold">not</emphasis> overwrite them. These files include:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para> click/error.htm - the Page
+ <link linkend="page-error-handling">Error Handling</link> template
+ </para>
+ </listitem>
+ <listitem>
+ <para> click/control.css - the Controls cascading stylesheet</para>
+ </listitem>
+ <listitem>
+ <para> click/control.js - the Controls JavaScript library</para>
+ </listitem>
+ <listitem>
+ <para> click/not-found.htm - the
+ <link linkend="page-not-found">Page Not Found</link> template
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>For example to customize the control styles you can place a customized
+ copy (or even a brand new version) of <filename>control.css</filename> under
+ the <varname>/click</varname> folder in your web project:
+ </para>
+
+ <literallayout>/webapp/click/control.css</literallayout>
+
+ <para>When Click starts up it will <emphasis role="bold">not</emphasis>
+ override your copy of <filename>control.css</filename> with its own default
+ version.
+ </para>
+
+ <para>Different controls might deploy different stylesheet, javascript or image
+ files, however the above principle still applies. By placing a customized copy
+ of the stylesheet, javascript or image under the <varname>/click</varname> folder,
+ you will override the default resource.
+ </para>
+
+ <para>Be aware that some of the more complex controls (checklist, colorpicker,
+ tree), deploys resources to subfolders under <varname>/click</varname>, for
+ example <literal>/click/checklist/*</literal>.
+ </para>
+
+ <para>A control's Javadoc will normally indicate what resources are deployed
+ for that control.
+ </para>
+
+ <para>It is generally easier to work with unpacked WARs and most servlet
+ containers do just that. However some contains such as WebLogic (at least
+ version 10) does not. To enable WebLogic to unpack the WAR go to the
+ <emphasis>Admin Console > server node > Web Applications</emphasis>
+ tab and check the <emphasis>Archived Real Path Enabled</emphasis> parameter.
+ </para>
+
+ <para>If Click cannot deploy resources because of restricted file system
+ permissions, warning messages will be logged.
+ </para>
+
+ <para>If your application server does not unpack the WAR/EAR or has restricted
+ permissions, you will need to package up these auto deployed files in your web
+ applications WAR file. To do this you should run you application on a development
+ machine without these restrictions and then package up the deployed files into
+ the WAR/EAR before deployment.
+ </para>
+
+ <sect2 id="deploying-custom-resources" remap="h3">
+ <title>Deploying Custom Resources</title>
+
+ <para> Click supports two ways of deploying pre-configured resources
+ (templates, stylesheets, JavaScript etc.) from a Jar to a web applications.
+ </para>
+
+ <orderedlist>
+ <listitem>
+ <para> Through a Control's
+ <ulink url="../../click-api/org/apache/click/Control.html#onDeploy(javax.servlet.ServletContext)">onDeploy()</ulink>
+ event handler. See the <link linkend="application-controls">Controls</link>
+ section above.
+ </para>
+ </listitem>
+ <listitem>
+ <para> By packaging the resources (stylesheets, JavaScript, Images etc.)
+ into a special folder called <emphasis>'META-INF/web'</emphasis>.
+ </para>
+ </listitem>
+ </orderedlist>
+
+ <para>As option #1 was already discussed above in section
+ <link linkend="application-controls">Controls</link>, lets look at option #2.
+ </para>
+
+ <para>When Click starts up, it scans each Jar in the classpath for
+ specially marked entries starting with 'META-INF/web/'. (Please note that
+ even though Click will scan the entire classpath it is strongly recommended
+ to host your Jar files inside your WAR lib folder e.g. WEB-INF/lib. Sharing
+ Jars on the classpath can lead to class loading issues.)
+ </para>
+
+ <para>Click will then copy all files found under 'META-INF/web/' to the web
+ application folder.
+ </para>
+
+ <para>
+ For example, given a Jar file with the following entries:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>META-INF/web/mycorp/edit_customer.js</para>
+ </listitem>
+ <listitem>
+ <para>META-INF/web/mycorp/edit_customer.css</para>
+ </listitem>
+ <listitem>
+ <para>mycorp/pages/EditCustomerPage.class</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Click will copy the files <emphasis>'/mycorp/edit_customer.js'</emphasis>
+ and <emphasis>'/mycorp/edit_customer.css'</emphasis> to the web application
+ folder.
+ </para>
+
+ <para>Thus if the web application is called 'webapp', the files will be
+ deployed as <emphasis>'webapp/mycorp/edit_customer.js'</emphasis> and
+ <emphasis>'webapp/mycorp/edit_customer.css'</emphasis>.
+ </para>
+
+ <para>Option #2 is especially useful when you need to deploy a large number
+ of resources from a Jar. Note, only Jars placed under the
+ <emphasis>'WEB-INF/lib'</emphasis> folder will be deployed.
+ </para>
+
+ </sect2>
+ </sect1>
+</chapter>
Added: incubator/click/trunk/click/documentation/xdocs/src/docbook/click/chapter-controls.xml
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/documentation/xdocs/src/docbook/click/chapter-controls.xml?rev=752572&view=auto
==============================================================================
--- incubator/click/trunk/click/documentation/xdocs/src/docbook/click/chapter-controls.xml (added)
+++ incubator/click/trunk/click/documentation/xdocs/src/docbook/click/chapter-controls.xml Wed Mar 11 18:55:49 2009
@@ -0,0 +1,1046 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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="chapter-controls" remap="h1">
+ <title>Controls</title>
+
+ <para> Click provides a rich set of Controls which support client side
+ rendering and server side processing. This section covers the following topics:
+ </para>
+
+ <orderedlist>
+ <listitem>
+ <para>
+ <link linkend="control-interface">Control Interface</link> - describes
+ the Control interface
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <link linkend="control-callback">Control Callback</link> - control
+ event callback pattern
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <link linkend="control-class">Control Classes</link> - control Java
+ classes
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <link linkend="control-message-properties">Control Message Properties</link>
+ - control message properties
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <link linkend="container">Container</link> - a Container is a Control
+ that can contain other Controls.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <link linkend="layout">Layouts</link> - describes layout options and
+ how to create custom layouts.
+ </para>
+ </listitem>
+ </orderedlist>
+
+ <para>While this section provides an overview how Controls work please see the
+ <ulink url="../../click-api/org/apache/click/control/package-summary.html">Javadoc</ulink>,
+ which provides extensive information and examples.
+ </para>
+
+ <sect1 id="control-interface" remap="h2">
+ <title>Control Interface</title>
+
+ <para> Controls provide the server side components that process user input,
+ and render their display to the user. Controls are equivalent to Visual
+ Basic Controls or Delphi Components.
+ </para>
+
+ <para>Controls handle the processing of user input in the
+ <ulink url="../../click-api/org/apache/click/Control.html#onProcess()">onProcess</ulink>
+ method and render their HTML display using the toString() method. The
+ execution sequence for a Control being processed and rendered is illustrated
+ in the figure below.
+ </para>
+
+ <figure id="control-post-sequence-diagram">
+ <title>Post Sequence Diagram - created with Enterprise Architect
+ courtesy <ulink url="http://www.sparxsystems.com.au">Sparx Systems</ulink>
+ </title>
+ <inlinemediaobject>
+ <imageobject>
+ <imagedata fileref="images/controls/control-post-sequence-diagram.png" format="PNG" scale="85"/>
+ </imageobject>
+ </inlinemediaobject>
+ </figure>
+
+ <para>In Click all control classes must implement the
+ <ulink url="../../click-api/org/apache/click/Control.html">Control</ulink> interface.
+ The Control interface is depicted in the figure below.
+ </para>
+
+ <figure id="control-class-diagram">
+ <title>Control Interface Diagram - created with Enterprise Architect
+ courtesy <ulink url="http://www.sparxsystems.com.au">Sparx Systems</ulink>
+ </title>
+ <inlinemediaobject>
+ <imageobject>
+ <imagedata fileref="images/controls/control-class-diagram.png" format="PNG" scale="85"/>
+ </imageobject>
+ </inlinemediaobject>
+ </figure>
+
+ <para>Methods on the Control interface include:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <ulink url="../../click-api/org/apache/click/Control.html#getHtmlImports()">getHtmlImports()</ulink>
+ - defines the controls HTML header imports.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink url="../../click-api/org/apache/click/Control.html#getMessages()">getMessages()</ulink>
+ - defines the controls localized messages map.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink url="../../click-api/org/apache/click/Control.html#getName()">getName()</ulink> /
+ <ulink url="../../click-api/org/apache/click/Control.html#setName(java.lang.String)">setName()</ulink>
+ Â - Â defines the controls name in the Page model or Form fields.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink url="../../click-api/org/apache/click/Control.html#getParent()">getParent()</ulink> /
+ <ulink url="../../click-api/org/apache/click/Control.html#setParent(java.lang.Object)">setParent()</ulink>
+ Â - Â defines the controls parent.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink url="../../click-api/org/apache/click/Control.html#onDeploy(javax.servlet.ServletContext)">onDeploy()</ulink>
+ - deploy resources on startup.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink url="../../click-api/org/apache/click/Control.html#onInit()">onInit()</ulink>
+ - on initialize event handler.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink url="../../click-api/org/apache/click/Control.html#onProcess()">onProcess()</ulink>
+ - process request event handler.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink url="../../click-api/org/apache/click/Control.html#onDestroy()">onDestroy()</ulink>
+ - on destroy event handler.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink url="../../click-api/org/apache/click/Control.html#render(org.apache.click.util.HtmlStringBuffer)">render()</ulink>
+ - generate the control's HTML representation.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ </sect1>
+
+ <sect1 id="control-callback" remap="h2">
+ <title>Control Callback</title>
+
+ <para>Click Controls provide an event callback mechanism similar to a
+ <classname>java.awt.ActionListener</classname> callback.
+ </para>
+
+ <para>Click supports two styles of action listeners. The first is using the
+ <ulink url="../../click-api/org/apache/click/ActionListener.html">ActionListener</ulink>
+ interface and
+ <ulink url="../../click-api/org/apache/click/control/AbstractControl.html#setActionListener(org.apache.click.ActionListener)">setActionListener(ActionListener)</ulink>
+ method which provides compile time safety.
+ </para>
+
+ <para>The second is to register the action listener via the
+ <ulink url="../../click-api/org/apache/click/Control.html#setListener(java.lang.Object, java.lang.String)">setListener(Object, String)</ulink>
+ method where you specify the call back method via its name. This second style
+ uses less lines of code, but has no compile time safety.
+ </para>
+
+ <para>Examples of these two action listener styles are provided below:
+ </para>
+
+ <programlisting language="java">public class ActionDemo extends BorderPage {
+
+ // Uses listener style 1
+ public ActionLink link = new ActionLink();
+
+ // Uses listener style 2
+ public ActionButton button = new ActionButton();
+
+ public ActionDemo() {
+
+ // Verbose but provides compile time safety
+ link.setActionListener(new ActionListener() {
+ public boolean onAction(Control source) {
+ return onLinkClick(source);
+ }
+ });
+
+ // Succinct but typos will cause runtime errors
+ button.setListener(this, "onButtonClick");
+ }
+
+ // Event Handlers ---------------------------------------------------------
+
+ public boolean onLinkClick(Control source) {
+ ..
+ return true;
+ }
+
+ public boolean onButtonClick() {
+ ..
+ return true;
+ }
+}</programlisting>
+
+ <para>All call back listener methods must return a boolean value. If they
+ return true the further processing of other controls and page methods should
+ continue. Otherwise if they return false, then any further processing should
+ be aborted. By returning false you can effectively exit at this point and
+ redirect or forward to another page. This execution logic is illustrated in
+ the <link linkend="activity-diagram">Page Execution Activity Diagram</link>.
+ </para>
+
+ <para>Being able to stop further processing and do something else can be very
+ handy. For example your Pages onRender() method may perform an expensive database
+ operation. By returning false in an event handler you can skip this step and
+ render the template or forward to the next page.
+ </para>
+
+ </sect1>
+
+ <sect1 id="control-class" remap="h2">
+ <title>Control Classes</title>
+
+ <para>Core control classes are defined in the package
+ <ulink url="../../click-api/org/apache/click/control/package-summary.html">org.apache.click.control</ulink>.
+ This package includes controls for the essential HTML elements.
+ </para>
+
+ <para>Extended control classes are provided in the Click Extras package
+ <ulink url="../../extras-api/org/apache/click/extras/control/package-summary.html">org.apache.click.extras.control</ulink>.
+ Click Extras classes can contain dependencies to 3rd party frameworks.
+ </para>
+
+ <para>A subset of these control classes are depicted in the figure below.
+ </para>
+
+ <figure id="control-package-class-diagram">
+ <title>Package Class Diagram - created with Enterprise Architect
+ courtesy <ulink url="http://www.sparxsystems.com.au">Sparx Systems</ulink>
+ </title>
+ <inlinemediaobject>
+ <imageobject>
+ <imagedata fileref="images/controls/control-package-class-diagram.png" format="PNG" scale="75"/>
+ </imageobject>
+ </inlinemediaobject>
+ </figure>
+
+ <para>The key control classes include:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <ulink url="../../click-api/org/apache/click/control/ActionLink.html">ActionLink</ulink>
+ - provides an anchor link which can invoke callback listeners.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink url="../../click-api/org/apache/click/control/Field.html">Field</ulink>
+ - provides the abstract form field control.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink url="../../click-api/org/apache/click/control/Form.html">Form</ulink>
+ - provides a form control for processing, validation and rendering.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink url="../../click-api/org/apache/click/control/Submit.html">Submit</ulink>
+ - provides an input type submit control which can invoke callback listeners.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink url="../../click-api/org/apache/click/control/TextField.html">TextField</ulink>
+ - provides an input type text control which can invoke callback listeners.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>The control classes are designed to support subclassing for customized
+ behaviour. All control fields have protected visibility and have public
+ accessor methods.
+ </para>
+
+ <para>You can also aggregate controls to build more complex controls. For
+ example the <ulink url="../../extras-api/org/apache/click/extras/control/CreditCardField.html">CreditCardField</ulink>
+ uses a <ulink url="../../click-api/org/apache/click/control/Select.html">Select</ulink>
+ control to render the different credit card types.
+ </para>
+
+ </sect1>
+
+ <sect1 id="control-message-properties" remap="h2">
+ <title>Message Properties</title>
+
+ <para>Control strings for field validation messages and HTML formatting
+ strings are externalized in the properties file. By using these properties
+ files you can localize a Click application for your particular language and
+ dialect.
+ </para>
+
+ <sect2 id="message-resolution" remap="h3">
+ <title>Message Resolution</title>
+
+ <para>Messages are looked up in a particular order enabling taylor specific
+ messages, for your controls, individual pages or across your entire
+ application. The order in which localized messages are resolved is:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><emphasis role="bold">Page scope messages</emphasis></term>
+ <listitem>
+ <para>Message lookups are first resolved to the Page classes message
+ bundle if it exists. For example a <classname>Login</classname> page
+ may define the message properties:
+ </para>
+
+ <literallayout>/com/mycorp/page/Login.properties</literallayout>
+
+ <para>If you want to tailor messages for a particular page this is
+ where to place them.
+ </para>
+
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis role="bold">Global page scope messages</emphasis></term>
+ <listitem>
+ <para>Next message lookups are resolved to the global pages message
+ bundle if it exists.
+ </para>
+
+ <literallayout>/click-page.properties</literallayout>
+
+ <para>If you want messages to be used across your entire application
+ this is where to place them.
+ </para>
+
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <para> </para>
+ <term><emphasis role="bold">Control scope messages</emphasis></term>
+ <listitem>
+ <para>Next message lookups are resolved to the Control classes
+ message bundle if it exists. For example a
+ <classname>CustomTextField</classname> control may define the
+ message properties:
+ </para>
+
+ <literallayout>/com/mycorp/control/CustomTextField.properties</literallayout>
+
+ <para>A custom control's messages can be placed here
+ (or the global control scope covered next) and overridden by one of the
+ above options.
+ </para>
+
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis role="bold">Global control scope messages</emphasis></term>
+ <listitem>
+ <para>Finally message lookups are resolved to the global application
+ control message bundle if the message has not already been found.
+ The global control properties file is:
+ </para>
+
+ <literallayout>/click-control.properties</literallayout>
+
+ <para>Control messages can be placed here and overridden by one of
+ the above options.
+ </para>
+
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ </sect2>
+
+ <sect2 id="control-properties" remap="h3">
+ <title>Control Properties</title>
+
+ <para>To customize the <filename>click-control.properties</filename> simply
+ add this file to your classpath and tailor the specific values.
+ </para>
+
+ <para>Note when customizing the message properties you must include all
+ the properties, not just the ones you want to override.
+ </para>
+
+ <literallayout># Click Control messages
+field-maxlength-error={0} must be no longer than {1} characers
+field-minlength-error={0} must be at least {1} characters
+field-required-error=You must enter a value for {0}
+
+file-required-error=You must enter a filename for {0}
+
+label-required-prefix=
+label-required-suffix=<span class="required">*</span>
+label-not-required-prefix=
+label-not-required-suffix=&nbsp;
+
+not-checked-error=You must select {0}
+
+number-maxvalue-error={0} must not be larger than {1}
+number-minvalue-error={0} must not be smaller than {1}
+
+select-error=You must select a value for {0}
+
+table-first-label=First
+table-first-title=Go to first page
+table-previous-label=Prev
+table-previous-title=Go to previous page
+table-next-label=Next
+table-next-title=Go to next page
+table-last-label=Last
+table-last-title=Go to last page
+table-goto-title=Go to page
+table-page-banner=<span class="pagebanner">{0} items found, displaying {1} to {2}.</span>
+table-page-banner-nolinks=
+ <span class="pagebanner-nolinks">{0} items found, displaying {1} to {2}.</span>
+table-page-links=<span class="pagelinks">[{0}/{1}] {2} [{3}/{4}]</span>
+table-page-links-nobanner=<span class="pagelinks-nobanner">[{0}/{1}] {2} [{3}/{4}]</span>
+table-no-rows-found=No records found.
+
+table-inline-first-image=/click/paging-first.gif
+table-inline-first-disabled-image=/click/paging-first-disabled.gif
+table-inline-previous-image=/click/paging-prev.gif
+table-inline-previous-disabled-image=/click/paging-prev-disabled.gif
+table-inline-next-image=/click/paging-next.gif
+table-inline-next-disabled-image=/click/paging-next-disabled.gif
+table-inline-last-image=/click/paging-last.gif
+table-inline-last-disabled-image=/click/paging-last-disabled.gif
+table-inline-page-links=Page {0} {1} {2} {3} {4}
+
+# Message displayed when a error occurs when the application is in "production" mode
+production-error-message=
+ <div id='errorReport' class='errorReport'>The application encountered an unexpected error.
+ </div>
+ </literallayout>
+
+ </sect2>
+
+ <sect2 id="accessing-messages" remap="h3">
+ <title>Accessing Messages</title>
+
+ <para>Field classes support a hierarchy of resource bundles for displaying
+ validation error messages and display messages. These localized messages
+ can be accessed through the Field methods:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <ulink url="../../click-api/org/apache/click/control/AbstractControl.html#getMessage(java.lang.String)">getMessage(String)</ulink>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink url="../../click-api/org/apache/click/control/AbstractControl.html#getMessage(java.lang.String,%20java.lang.Object)">getMessage(String, Object)</ulink>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink url="../../click-api/org/apache/click/control/AbstractControl.html#getMessage(java.lang.String,%20java.lang.Object[])">getMessage(String, Object[])</ulink>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink url="../../click-api/org/apache/click/control/AbstractControl.html#getMessages()">getMessages()</ulink>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink url="../../click-api/org/apache/click/control/Field.html#setErrorMessage(java.lang.String)">setErrorMessage(String)</ulink>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink url="../../click-api/org/apache/click/control/Field.html#setErrorMessage(java.lang.String,%20java.lang.Object)">setErrorMessage(String, Object)</ulink>
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>These methods use the <literal>Locale</literal> of the request to
+ lookup the string resource bundle, and use <classname>MessageFormat</classname>
+ for any string formatting.
+ </para>
+
+ </sect2>
+ </sect1>
+
+ <sect1 id="container" remap="h2">
+ <title>Container</title>
+
+ <para><ulink url="../../click-api/org/apache/click/control/Container.html">Container</ulink>
+ is a Control that can contain other Controls, thus forming a hierarchy
+ of components. Container enables components to add, remove and retrieve other
+ controls. Listed below are example Containers:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <ulink url="../../click-api/org/apache/click/control/Form.html">Form</ulink>
+ - an HTML form which provides default layout of fields and error feedback.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink url="../../click-api/org/apache/click/control/Panel.html">Panel</ulink>
+ - similar to
+ <ulink url="../../click-api/org/apache/click/Page.html">Page</ulink>, this
+ Container provides its own template and model.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink url="../../click-api/org/apache/click/control/FieldSet.html">FieldSet</ulink>
+ - draws a legend (border) around its child Controls.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>These Containers are depicted in the figure below.
+ </para>
+
+ <figure id="container-package-class-diagram">
+ <title>Container Class Diagram</title>
+ <inlinemediaobject>
+ <imageobject>
+ <imagedata fileref="images/controls/container-package-class-diagram.png" format="PNG" scale="70"/>
+ </imageobject>
+ </inlinemediaobject>
+ </figure>
+
+ <para>The following classes provides convenient extension points for creating
+ custom Containers:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <ulink url="../../click-api/org/apache/click/control/AbstractContainer.html">AbstractContainer</ulink>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink url="../../extras-api/org/apache/click/extras/control/AbstractContainerField.html">AbstractContainerField</ulink>
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Lets cover each of them here.
+ </para>
+
+ <sect2 id="abstractcontainer" remap="h3">
+ <title>AbstractContainer</title>
+
+ <para>Enables easy creation of custom Containers, for example an html
+ <emphasis>div</emphasis> or <emphasis>span</emphasis> element:
+ </para>
+
+ <programlisting language="java">public class Div extends AbstractContainer {
+
+ public Div(String name) {
+ super(name);
+ }
+
+ public String getTag() {
+ // Return the control's HTML tag.
+ return "div";
+ }
+}</programlisting>
+
+ <para>Lets try out the newly created <classname>Container</classname>
+ above: (note the <classname>MockContext</classname> used in this test is
+ described in the <ulink url="../../mock-api/overview-summary.html">Mock Test Support</ulink>
+ documentation)
+ </para>
+
+ <programlisting language="java">public class Test {
+ public static void main (String args[]) {
+ // Create mock context in which to test the container.
+ MockContext.initContext();
+
+ // Create a div instance called "mydiv"
+ String containerName = "mydiv";
+ Div mydiv = new Div(containerName);
+
+ // Add a control to the container
+ mydiv.add(new TextField("myfield"));
+
+ System.out.println(mydiv);
+ }
+}</programlisting>
+
+ <para>Executing the above example results in the following output:
+ </para>
+
+ <programlisting language="xml"><div name="mydiv" id="mydiv">
+ <input type="text" name="myfield" id="myfield" value="" size="20" />
+</div></programlisting>
+
+ </sect2>
+
+ <sect2 id="abstractcontainerfield" remap="h3">
+ <title>AbstractContainerField</title>
+
+ <para>AbstractContainerField extends Field and implements the Container
+ interface. This provides a convenient base class in case you run into
+ a situation where you need both a Field and Container.
+ </para>
+
+ <para>Below is an example of how AbstractContainerField might be used:
+ </para>
+
+ <programlisting language="java">public class FieldAndContainer extends AbstractContainerField {
+
+ public FieldAndContainer(String name) {
+ super(name);
+ }
+
+ // Return the html tag to render
+ public String getTag() {
+ return "div";
+ }
+}</programlisting>
+
+ <para>To test the new class we use the following snippet:
+ </para>
+
+ <programlisting language="java">public class Test {
+ public static void main (String args[]) {
+ // Create mock context in which to test the container.
+ MockContext.initContext();
+
+ // Create a FieldContainer instance called "field_container"
+ String containerName = "field_container";
+ FieldAndContainer fieldAndContainer = new FieldAndContainer(containerName);
+
+ // Add a couple of fields to the container
+ fieldAndContainer.add(new TextField("myfield"));
+ fieldAndContainer.add(new TextArea("myarea"));
+
+ System.out.println(fieldAndContainer);
+ }
+}</programlisting>
+
+ <para>Executing the snippet produces the output:
+ </para>
+
+ <programlisting language="xml"><div name="field_container" id="field_container">
+ <input type="text" name="myfield" id="myfield" value="" size="20"/>
+ <textarea name="myarea" id="myarea" rows="3" cols="20"></textarea>
+</div></programlisting>
+
+ </sect2>
+ </sect1>
+
+ <sect1 id="layout" remap="h2">
+ <title>Layouts</title>
+
+ <para>Controls such as <ulink url="../../click-api/org/apache/click/control/Form.html">Form</ulink>
+ takes care of layout and error reporting automatically, and for many use
+ cases the auto-layout approach is good enough. It is certainly very productive.
+ </para>
+
+ <para>However for custom or complex layouts, auto-layout is not always the best
+ choice. There are two approaches for creating custom layouts.
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Template approach - use a template engine such as Velocity,
+ Freemarker or JSP to declare the layout as HTML markup.
+ </para>
+ </listitem>
+ <listitem>
+ <para> Programmatic approach - build custom layout components using Java.
+ This option is very similar to building components using Swing.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <sect2 id="template-layout" remap="h3">
+ <title>Template layout</title>
+
+ <para>The <ulink url="../../click-api/org/apache/click/control/Form.html#manual-layout">Template</ulink>
+ approach separates the Page and layout logic. The Page is used to implement
+ the presentation logic such as creating controls, registering listeners
+ and copying data to domain objects, while the template is used to layout
+ the Page controls.
+ </para>
+
+ <para>Lets walk through an example using the template approach. Below
+ we create an EmployeePage which contains a Form and a bunch of fields
+ and submit button.
+ </para>
+
+ <programlisting language="java">// EmployeePage.java
+public EmployeePage extends Page {
+
+ private Form form;
+
+ public void onInit() {
+ // Create form
+ Form form = new Form("form");
+
+ // Add a couple of fields to the form
+ form.add(new TextField("firstname"));
+ form.add(new TextField("lastname"));
+ form.add(new IntegerField("age"));
+ form.add(new DoubleField("salary"));
+
+ // Add a submit button to form
+ form.add(new Submit("submit", "Add Employee"));
+
+ // Add form the page
+ addControl(form);
+ }
+}</programlisting>
+
+ <para>Lets imagine we want to create a layout using the HTML tags,
+ <div> and <ol>.
+ </para>
+
+ <para>We would then provide the markup for the <varname>employee.htm</varname>
+ template as shown below, using a template engine such as Velocity:
+ </para>
+
+ <programlisting language="xml"><!-- employee.htm -->
+${form.startTag()}
+ <div style="margin: 1em;">
+ <ol>
+ <li>
+ <label for="firstname">Firstname:</label>
+ ${form.fields.firstname}
+ </li>
+ <li>
+ <label for="lastname">Lastname:</label>
+ ${form.fields.lastname}
+ </li>
+ <li>
+ <label for="age">Age:</label>
+ ${form.fields.age}
+ </li>
+ <li>
+ <label for="salary">Salary:</label>
+ ${form.fields.salary}
+ </li>
+ </ol>
+ </div>
+ ${form.fields.submit}
+${form.endTag()}</programlisting>
+
+ <para>Using CSS the markup above can further be styled and transformed
+ into a nice looking form.
+ </para>
+
+ <para>There are pros and cons to using the template approach.
+ </para>
+
+ <para>One of the advantages is that the layout is explicit and one can
+ easily tweak it if needed. For example instead of using divs and ordered
+ lists, one can change the template to leverage a table layout.
+ </para>
+
+ <para>A disadvantage is added redundancy. In the example above we created
+ the fields in Java, and laid them out using markup in the template. If the
+ requirements should change to add a new field for example, one will have to
+ add the field in the Page as well as the template.
+ </para>
+
+ <para>However it is possible to "generify" the layout using template
+ engines such as Velocity, Freemarker and JSP.
+ <ulink url="../../click-api/org/apache/click/control/Form.html#velocity-macros">Macro.vm</ulink>
+ is an example of a generic form layout using Velocity.
+ </para>
+
+ </sect2>
+
+ <sect2 id="programmatic-layout" remap="h3">
+ <title>Programmatic layout</title>
+
+ <para>To combat the redundancy introduced by the Template approach, you can
+ take a programmatic approach and use normal Java and some Click classes to
+ build custom layouts.
+ </para>
+
+ <para>Click extras provides two useful classes in this situation namely,
+ <ulink url="../../extras-api/org/apache/click/extras/control/HtmlForm.html">HtmlForm</ulink>
+ and <ulink url="../../extras-api/org/apache/click/extras/control/HtmlFieldSet.html">HtmlFieldSet</ulink>.
+ </para>
+
+ <para>Unlike Form and FieldSet which renders its controls using a Table
+ layout, HtmlForm and HtmlFieldSet renders its controls in the order they
+ were added and does not add any extra markup. HtmlForm will be used in the
+ examples below.
+ </para>
+
+ <para>To make it easy to compare the two layout approaches we will recreate
+ the example from the template layout section, but using the programmatic
+ approach.
+ </para>
+
+ <para>When creating custom layouts, the HTML construct List <ul> is
+ pretty useful. Since Click does not provide this component, we will create
+ it as shown below. First we create the HTML list element <ol>, to
+ which list item elements <li> can be added:
+ </para>
+
+ <programlisting language="java">// HtmlList.java
+public class HtmlList extends AbstractContainer {
+
+ public String getTag() {
+ return "ol";
+ }
+
+ // Can only add ListItems: <li> tags
+ public Control add(Control control) {
+ if (!(control instanceof ListItem)) {
+ throw new IllegalArgumentException("Only list items can be added.");
+ }
+ return super.add(control);
+ }
+}</programlisting>
+
+ <para>Next we create the HTML list item element <li>:
+ </para>
+
+ <programlisting language="java">// ListItem.java
+public class ListItem extends AbstractContainer {
+
+ public String getTag() {
+ return "li";
+ }
+}</programlisting>
+
+ <para>Another component that will be used in the example is a FieldLabel
+ which renders an HTML label element for a target Field.
+ </para>
+
+ <programlisting language="java">// FieldLabel.java
+public class FieldLabel extends AbstractControl {
+
+ private Field target;
+
+ private String label;
+
+ public FieldLabel(Field target, String label) {
+ this.target = target;
+ this.label = label;
+ }
+
+ public String getTag() {
+ return "label";
+ }
+
+ // Override render to produce an html label for the specified field.
+ public void render(HtmlStringBuffer buffer) {
+ // Open tag: <label
+ buffer.elementStart(getTag());
+
+ // Set attribute to target field's id
+ setAttribute("for", target.getId());
+
+ // Render the labels attributes
+ appendAttributes(buffer);
+
+ // Close tag: <label for="firstname">
+ buffer.closeTag();
+
+ // Add label text: <label for="firstname">Firstname:
+ buffer.append(label);
+
+ // Close tag: <label for="firstname">Firstname:</label>
+ buffer.elementEnd(getTag());
+ }
+
+}</programlisting>
+
+ <para>Now the form can be assembled. Continuing with the employee example
+ from the <link linkend="template-layout">template approach</link>, we again
+ create an <classname>EmployeePage</classname>, but this time an
+ <classname>HtmlForm</classname> and <classname>HtmlList</classname> is used
+ to create the custom layout:
+ </para>
+
+ <programlisting language="java">// EmployeePage.java
+public class EmployeePage extends Page {
+ // A form instance variable
+ private HtmlForm form;
+
+ // Build the form when the page is initialized
+ public void onInit() {
+ // Create an HtmlForm which is ideal for composing manual layouts
+ form = new HtmlForm("form");
+
+ // Create a list and add it to the form.
+ HtmlList list = new HtmlList();
+ form.add(list);
+
+ // Add firstname field and pass in its name, label and the list to add the field to
+ addTextField("firstname", "Firstname:", list);
+ addTextField("lastname", "Lastname:", list);
+ addTextField("age", "Age:", list);
+ addTextField("salary", "Salary:", list);
+
+ // Add a submit button to form
+ form.add(new Submit("submit", "Add Employee"));
+
+ // Add the form to the page
+ addControl(form);
+ }
+
+ // Provide a helper method to add fields to the form
+ private void addTextField(String nameStr, String labelStr, List list) {
+ // Create a new ListItem <li> and add it to the List
+ ListItem item = new ListItem();
+ list.add(item);
+
+ // Create a textfield with the specified name
+ Field field = new TextField(nameStr);
+
+ // Create a field label, which associates the label with the field id.
+ // label.toString would output: <label for="firstname">Firstname:</name>
+ FieldLabel label = new FieldLabel(field, labelStr);
+
+ // Next add the label and field to the list item.
+ // item.toString would then produce:
+ // <li>
+ // <label for="firstname">Firstname:</name>
+ // <input type="text" name="firstname" id="form_firstname" value="" size="20"/>
+ // </li>
+ //
+ item.add(label);
+ item.add(field);
+ }
+}</programlisting>
+
+ <para>And lastly the <filename>employee.htm</filename> template would only
+ need to specify the name of the top level component, in this case
+ <varname>form</varname>.
+ </para>
+
+ <programlisting language="xml"><!--employee.htm-->
+<varname>${form}</varname></programlisting>
+
+ <para>which produces the following markup:
+ </para>
+
+ <programlisting language="xml"><form method="post" id="form" action="/myapp/employee.htm">
+<input type="hidden" name="form_name" id="form_form_name" value="form"/>
+ <ol>
+ <li>
+ <label for="firstname">Firstname:</label>
+ <input type="text" name="firstname" id="form_firstname" value="" size="20"/>
+ </li>
+ <li>
+ <label for="lastname">Lastname:</label>
+ <input type="text" name="lastname" id="form_lastname" value="" size="20"/>
+ </li>
+ <li>
+ <label for="age">Age:</label>
+ <input type="text" name="age" id="form_age" value="" size="20"/>
+ </li>
+ <li>
+ <label for="salary">Salary:</label>
+ <input type="text" name="salary" id="form_salary" value="" size="20"/>
+ </li>
+ </ol>
+ <input type="submit" name="submit" id="form_submit" value="Add Employee"/>
+</form></programlisting>
+
+ <para>Again using a CSS stylesheet, the markup above can be styled and
+ transformed into a fancy looking form.
+ </para>
+
+ <para>There is a <ulink url="http://www.avoka.com/click-examples/form/contact-details.htm">live demo</ulink>
+ showing the programmatic approach.
+ </para>
+
+ <para>The advantage of the programmatic approach is that there is no
+ redundancy. Each Field is created and added using normal Java. There is no
+ need to specify where the Field must reside in the markup.
+ </para>
+
+ <para>If new requirements arrive and more fields added, only the Page needs
+ to change. There is no need to change the template as the layout is taken
+ care of by CSS and the markup produced by the components.
+ </para>
+
+ <para>Disadvantages are that more upfront work is needed to write the
+ components and it is more difficult to
+ <emphasis>visualize</emphasis> what output would be rendered by the
+ components.
+ </para>
+
+ <para>However once your custom layout components are in place, it can be
+ reused across your project and boost productivity.
+ </para>
+
+ <para>Whether you use the <link linkend="template-layout">template</link>
+ or <link linkend="programmatic-layout">programmatic</link> layout approach,
+ is up to you. Both work well and have advantages and disadvantages over the
+ other.
+ </para>
+
+ </sect2>
+ </sect1>
+</chapter>