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 [1/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...
Author: sabob
Date: Wed Mar 11 18:55:49 2009
New Revision: 752572
URL: http://svn.apache.org/viewvc?rev=752572&view=rev
Log:
Added Click Book
Added:
incubator/click/trunk/click/documentation/docs/user-guide.html
incubator/click/trunk/click/documentation/xdocs/ (with props)
incubator/click/trunk/click/documentation/xdocs/README.txt
incubator/click/trunk/click/documentation/xdocs/build-docbook.xml
incubator/click/trunk/click/documentation/xdocs/build.xml
incubator/click/trunk/click/documentation/xdocs/project.properties
incubator/click/trunk/click/documentation/xdocs/src/
incubator/click/trunk/click/documentation/xdocs/src/css/
incubator/click/trunk/click/documentation/xdocs/src/css/html/
incubator/click/trunk/click/documentation/xdocs/src/css/html/stylesheet.css
incubator/click/trunk/click/documentation/xdocs/src/docbook/
incubator/click/trunk/click/documentation/xdocs/src/docbook/click/
incubator/click/trunk/click/documentation/xdocs/src/docbook/click/chapter-best-practices.xml
incubator/click/trunk/click/documentation/xdocs/src/docbook/click/chapter-configuration.xml
incubator/click/trunk/click/documentation/xdocs/src/docbook/click/chapter-controls.xml
incubator/click/trunk/click/documentation/xdocs/src/docbook/click/chapter-introduction.xml
incubator/click/trunk/click/documentation/xdocs/src/docbook/click/chapter-pages.xml
incubator/click/trunk/click/documentation/xdocs/src/docbook/click/click-book.xml
incubator/click/trunk/click/documentation/xdocs/src/images/
incubator/click/trunk/click/documentation/xdocs/src/images/best-practices/
incubator/click/trunk/click/documentation/xdocs/src/images/click-logo.png (with props)
incubator/click/trunk/click/documentation/xdocs/src/images/configuration/
incubator/click/trunk/click/documentation/xdocs/src/images/controls/
incubator/click/trunk/click/documentation/xdocs/src/images/external.png (with props)
incubator/click/trunk/click/documentation/xdocs/src/images/introduction/
incubator/click/trunk/click/documentation/xdocs/src/images/pages/
incubator/click/trunk/click/documentation/xdocs/src/styles/
incubator/click/trunk/click/documentation/xdocs/src/styles/html/
incubator/click/trunk/click/documentation/xdocs/src/styles/pdf/
Modified:
incubator/click/trunk/click/documentation/docs/ (props changed)
incubator/click/trunk/click/documentation/toc.html
Propchange: incubator/click/trunk/click/documentation/docs/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Wed Mar 11 18:55:49 2009
@@ -1,5 +1,6 @@
+.~lock.click-cheat-sheet.odg#
mock-api
+user-guide
click-api
-Thumbs.db
extras-api
-.~lock.click-cheat-sheet.odg#
+Thumbs.db
Added: incubator/click/trunk/click/documentation/docs/user-guide.html
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/documentation/docs/user-guide.html?rev=752572&view=auto
==============================================================================
--- incubator/click/trunk/click/documentation/docs/user-guide.html (added)
+++ incubator/click/trunk/click/documentation/docs/user-guide.html Wed Mar 11 18:55:49 2009
@@ -0,0 +1,59 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<!--
+ 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.
+-->
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
+ <meta name="Author" content="Malcolm Edgar"/>
+ <meta name="description" lang="en" content="Apache Click Java web application framework"/>
+ <meta name="keywords" lang="en" content="Apache Click, Click Framework, Java, JEE, J2EE, web application framework, open source"/>
+ <title>Apache Click</title>
+ <link rel="stylesheet" type="text/css" href="../help.css"/>
+</head>
+<body>
+
+<h1>User Guide</h1>
+<p/>
+Click comes with a comprehensive user guide to get you started quickly. It starts
+off with an introductory chapter showing how to work with pages and templates
+and moves on to some of the most popular controls, Form and Table.
+
+<p/>
+It also explains in depth the Page and Control life cycle, configuration and
+best practices.
+
+<p/>
+The user guide is available in three flavors:
+
+<ul>
+ <li>
+ <a href="user-guide/html/index.html">HTML multiple pages</a>
+ </li>
+ <li>
+ <a href="user-guide/htmlsingle/click-book.html">HTML single page (320 KB)</a>
+ </li>
+ <li>
+ <a target='_blank' class='external' href="user-guide/pdf/click-book.pdf">PDF (480 KB)</a>
+ </li>
+</ul>
+
+</body>
+</html>
+
Modified: incubator/click/trunk/click/documentation/toc.html
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/documentation/toc.html?rev=752572&r1=752571&r2=752572&view=diff
==============================================================================
--- incubator/click/trunk/click/documentation/toc.html (original)
+++ incubator/click/trunk/click/documentation/toc.html Wed Mar 11 18:55:49 2009
@@ -45,7 +45,7 @@
</td></tr>
<tr><td>
-<a target='topic' class='navLinkTopic' href='docs/introduction.html' title=' Click Introduction'>
+<a target='topic' class='navLinkTopic' href='docs/user-guide/html/ch01.html' title=' Click Introduction'>
Introduction </a>
</td></tr>
@@ -60,18 +60,8 @@
</td></tr>
<tr><td>
-<a target='topic' class='navLinkTopic' href='docs/pages.html' title=' Click Page Classes'>
-Pages</a>
-</td></tr>
-
-<tr><td>
-<a target='topic' class='navLinkTopic' href='docs/controls.html' title=' Click HTML Controls'>
-Controls</a>
-</td></tr>
-
-<tr><td>
-<a target='topic' class='navLinkTopic' href='docs/configuration.html' title=' Click Application Configuration'>
-Configuration</a>
+<a target='topic' class='navLinkTopic' href='docs/user-guide.html' title=' User Guide'>
+User Guide</a>
</td></tr>
<tr><td>
@@ -80,11 +70,6 @@
</td></tr>
<tr><td>
-<a target='topic' class='navLinkTopic' href='docs/best-practices.html' title=' Click Development Best Practices'>
-Best Practices</a>
-</td></tr>
-
-<tr><td>
<a target='topic' class='navLinkTopic' href='docs/faq.html' title=' Frequently Asked Questions'>
FAQ</a>
</td></tr>
@@ -110,7 +95,7 @@
</td></tr>
<tr><td>
-<a target='blank' class='navLinkTopic' href='docs/click-cheat-sheet.pdf' title=' Click Framework Cheat Sheet'>
+<a target='_blank' class='navLinkTopic' href='docs/click-cheat-sheet.pdf' title=' Click Framework Cheat Sheet'>
Cheat Sheet PDF</a>
<img src='images/external.png' align='baseline' border='0'/>
</td></tr>
@@ -168,7 +153,7 @@
</td></tr>
<tr><td>
-<a target='blank' class='navLinkTopic' href='docs/velocity/VelocityUsersGuide.pdf' title=' Velocity Users Guide'>
+<a target='_blank' class='navLinkTopic' href='docs/velocity/VelocityUsersGuide.pdf' title=' Velocity Users Guide'>
Users Guide PDF</a>
<img src='images/external.png' align='baseline' border='0'/>
</td></tr>
Propchange: incubator/click/trunk/click/documentation/xdocs/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Wed Mar 11 18:55:49 2009
@@ -0,0 +1,3 @@
+lib
+target
+click-docbook
Added: incubator/click/trunk/click/documentation/xdocs/README.txt
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/documentation/xdocs/README.txt?rev=752572&view=auto
==============================================================================
--- incubator/click/trunk/click/documentation/xdocs/README.txt (added)
+++ incubator/click/trunk/click/documentation/xdocs/README.txt Wed Mar 11 18:55:49 2009
@@ -0,0 +1,62 @@
+Click Book
+==========
+
+The Click book is written in Docbook, and makes use of the Velocity
+Docbook Framework (DBF) and Apache FOP (FOP) to generate output various formats
+such as PDF, HTML (multiple pages) and HTML (single page).
+
+
+Project Layout
+==============
+
+The project consists of the folowing:
+
+build.xml the documentation build script
+project.properties the documentation properties
+src/css/html/ contains the HTML stylesheet and Code Syntax Highlighter
+src/docbook/click/ contains the Click Docbook document
+src/images/ contains all the documentation images
+src/style/html/ contains the Docbook HTML transformation rules
+src/style/pdf/ contains the Docbook PDF transformation rules
+
+
+Dependencies
+============
+
+This project has the following dependencies:
+
+# Velocity Docbook Framework (DBF) version 1.0: http://velocity.apache.org/docbook/
+# Apache FOP (at least version 0.95): http://xmlgraphics.apache.org/fop/0.95/index.html
+# Docbook XLS project version 1.75.0: http://docbook.sourceforge.net/snapshots/
+# XSLTHL syntax highlighter version 2.0.1: http://sourceforge.net/projects/xslthl
+
+A separate project, called 'Click Docbook', was created to distributes the
+above dependencies in a zip file.
+
+
+Building Click Book
+===================
+
+Click Book is built using the J2SE 1.4.2 and Ant 1.6.5.
+
+The Ant build.xml and build.properties files are located in this directory.
+
+The main Ant targets include:
+
+ all build Click Book in PDF, HTML (multi) and HTML (single) format
+ pdf build Click Book in PDF format
+ html build Click Book in HTML multi page format
+ htmlsingle build build Click Book in HTML single page format
+
+Before building the documentation, all third-party library dependencies must be
+downloaded using the command:
+
+ ant get-deps
+
+The 'get-deps' command will downlooad the dependency from the 'Click Docbook'
+project. The dependency is a 9MB zip file containing all that is needed to
+build the documentation.
+
+To build the Click Book in all available formats run:
+
+ ant all
Added: incubator/click/trunk/click/documentation/xdocs/build-docbook.xml
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/documentation/xdocs/build-docbook.xml?rev=752572&view=auto
==============================================================================
--- incubator/click/trunk/click/documentation/xdocs/build-docbook.xml (added)
+++ incubator/click/trunk/click/documentation/xdocs/build-docbook.xml Wed Mar 11 18:55:49 2009
@@ -0,0 +1,132 @@
+<?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.
+-->
+
+<project name="build-docbook" default="all" basedir=".">
+
+ <!-- Load the properties -->
+ <property file="project.properties"/>
+
+ <!-- Ensure Velocity Docbook Framework is available -->
+ <available file="${dbf.path}" property="dbf.downloaded"/>
+ <fail message="The Velocity Docbook Framework is not available. To resolve this download the dependencies (~9 MB) with 'ant get-deps'.">
+ <condition>
+ <or><isfalse value="${dbf.downloaded}"/></or>
+ </condition>
+ </fail>
+
+ <import file="${dbf.basedir}/build-docbook.xml"/>
+
+ <property name="docbook.dir" value="click"/>
+ <property name="docbook.file" value="click-book"/>
+
+ <!-- ======================================================================== -->
+ <!-- == == -->
+ <!-- == Build all the Velocity Docbook Documentation == -->
+ <!-- == == -->
+ <!-- ======================================================================== -->
+ <target name="all" description="Build all documentation">
+
+ <!-- Build the Users Guide -->
+ <antcall target="html"/>
+ <antcall target="htmlsingle"/>
+ <antcall target="pdf"/>
+
+ <delete quiet="true" dir="${target.dir}/${docbook.dir}/tmp"/>
+
+ <!--<fixcrlf srcdir="target/click" includes="**/*.html" eol="crlf" /> -->
+ </target>
+
+ <!-- ======================================================================== -->
+ <!-- == == -->
+ <!-- == Create the PDF documentation == -->
+ <!-- == == -->
+ <!-- ======================================================================== -->
+
+ <target name="pdf" description="Generates a single PDF file" depends="prepare">
+
+ <taskdef name="fop"
+ classname="org.apache.fop.tools.anttasks.Fop">
+ <classpath>
+ <fileset dir="${dbf.basedir}/lib">
+ <include name="*.jar"/>
+ </fileset>
+ </classpath>
+ </taskdef>
+
+ <transform type="pdf" target="tmp" title="pdf" xsl="fo" dir="${docbook.dir}" file="${docbook.file}"/>
+
+ <mkdir dir="target/${docbook.dir}/pdf"/>
+
+ <fop format="application/pdf"
+ basedir="${src.dir}"
+ fofile="${pdf.target.file}.xml"
+ outfile="target/${docbook.dir}/pdf/${docbook.file}.pdf" />
+
+ <!-- Copy artifacts to output folder -->
+ <delete dir="${output}/pdf/"/>
+ <copy todir="${output}/pdf/">
+ <fileset dir="target/${docbook.dir}/pdf/"/>
+ </copy>
+
+ </target>
+
+ <target name="html" description="Generate HTML docs in multiple files">
+
+ <ant antfile="${dbf.basedir}/build-docbook.xml" target="html">
+ <property name="docbook.dir" value="${docbook.dir}"/>
+ <property name="docbook.file" value="${docbook.file}"/>
+ </ant>
+
+ <!-- Copy artifacts to output folder -->
+ <delete dir="${output}/html/"/>
+ <copy todir="${output}/html/">
+ <fileset dir="target/${docbook.dir}/html/">
+ <exclude name="**/*.zip"/>
+ </fileset>
+ </copy>
+
+ </target>
+
+ <target name="htmlsingle" description="Generate HTML docs in a single, big file">
+
+ <ant antfile="${dbf.basedir}/build-docbook.xml" target="htmlsingle">
+ <property name="docbook.dir" value="${docbook.dir}"/>
+ <property name="docbook.file" value="${docbook.file}"/>
+ </ant>
+
+ <!-- Copy artifacts to output folder -->
+ <delete dir="${output}/htmlsingle/"/>
+ <copy todir="${output}/htmlsingle/">
+ <fileset dir="target/${docbook.dir}/htmlsingle/">
+ <exclude name="**/*.zip"/>
+ </fileset>
+ </copy>
+ </target>
+
+ <!-- ======================================================================== -->
+ <!-- == == -->
+ <!-- == Clean up the target directory == -->
+ <!-- == == -->
+ <!-- ======================================================================== -->
+ <target name="clean" description="Delete temporary and distribution directories for docs">
+ <ant antfile="${dbf.basedir}/build-docbook.xml" target="clean"/>
+ </target>
+</project>
Added: incubator/click/trunk/click/documentation/xdocs/build.xml
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/documentation/xdocs/build.xml?rev=752572&view=auto
==============================================================================
--- incubator/click/trunk/click/documentation/xdocs/build.xml (added)
+++ incubator/click/trunk/click/documentation/xdocs/build.xml Wed Mar 11 18:55:49 2009
@@ -0,0 +1,79 @@
+<?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.
+-->
+
+<!--
+NOTE: This build file depends on the Velocity Docbook Framework and won't
+work unless that framework is installed. Set the property 'dbf.basedir' in
+project.properties to refer to the installation directory before using this
+script.
+-->
+<project name="click-book" default="all" basedir=".">
+
+ <!-- Load the properties -->
+ <property file="project.properties"/>
+
+ <target name="all" description="Build all documentation" depends="prepare">
+ <ant antfile="build-docbook.xml" target="all"/>
+ </target>
+
+ <target name="clean" depends="prepare"
+ description="--> Delete temporary and distribution directories for docs">
+ <delete dir="target"/>
+ <delete dir="${dbf.basedir}"/>
+ </target>
+
+ <target name="html" description="Generate HTML docs in multiple files" depends="prepare">
+ <ant antfile="build-docbook.xml" target="html"/>
+ </target>
+
+ <target name="htmlsingle" description="Generate HTML docs in a single, big file" depends="prepare">
+ <ant antfile="build-docbook.xml" target="htmlsingle"/>
+ </target>
+
+ <target name="extract" unless="dbf.extracted">
+ <unzip src="${dbf.path}" dest="${dbf.basedir}/"/>
+ </target>
+
+ <target name="get-deps">
+ <mkdir dir="lib"/>
+ <get src="http://click-docbook.googlecode.com/svn/trunk/build/${dbf.zip}"
+ dest="${dbf.path}"
+ verbose="true"
+ usetimestamp="true"/>
+ </target>
+
+ <target name="pdf" description="Generates a single PDF file" depends="prepare">
+ <ant antfile="build-docbook.xml" target="pdf"/>
+ </target>
+
+ <target name="prepare">
+ <available file="${dbf.path}" property="dbf.downloaded"/>
+ <fail message="The Velocity Docbook Framework is not available. To resolve this download the dependencies (~9 MB) with 'ant get-deps'.">
+ <condition>
+ <or><isfalse value="${dbf.downloaded}"/></or>
+ </condition>
+ </fail>
+
+ <available file="${dbf.basedir}" property="dbf.extracted"/>
+ <antcall target="extract"/>
+ </target>
+
+</project>
Added: incubator/click/trunk/click/documentation/xdocs/project.properties
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/documentation/xdocs/project.properties?rev=752572&view=auto
==============================================================================
--- incubator/click/trunk/click/documentation/xdocs/project.properties (added)
+++ incubator/click/trunk/click/documentation/xdocs/project.properties Wed Mar 11 18:55:49 2009
@@ -0,0 +1,31 @@
+# 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.
+
+# Basedir for the docbook framework
+dbf.basedir = click-docbook
+
+# DBF zip file name
+dbf.zip = click-docbook-0.1.zip
+
+# DBF path
+dbf.path = lib/${dbf.zip}
+
+# Documentation output folder
+output = ../docs/user-guide
+
+# The size of the PDF pages.
+paper.type= Letter
Added: incubator/click/trunk/click/documentation/xdocs/src/css/html/stylesheet.css
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/documentation/xdocs/src/css/html/stylesheet.css?rev=752572&view=auto
==============================================================================
--- incubator/click/trunk/click/documentation/xdocs/src/css/html/stylesheet.css (added)
+++ incubator/click/trunk/click/documentation/xdocs/src/css/html/stylesheet.css Wed Mar 11 18:55:49 2009
@@ -0,0 +1,357 @@
+/*
+ * 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.
+ */
+
+html {
+ padding: 0pt;
+ margin: 0pt;
+}
+
+body {
+ margin-top: 1em;
+ margin-bottom: 1em;
+ margin-right: 15px;
+ margin-left: 15px;
+
+ font-family: verdana,arial,helvetica,lucida-sans,sans-serif;
+ font-size: 12px;
+}
+
+div {
+ margin: 0pt;
+}
+
+p {
+ text-align: justify;
+ margin-bottom: .6em;
+ line-height: 1.2;
+ font-size: 12px;
+}
+
+hr {
+ margin-top: .6em;
+ margin-bottom: .6em;
+ margin-left: 0pt;
+ margin-right: 0pt;
+ border: 1px solid gray;
+ background: gray;
+}
+
+h1,h2,h3,h4,h5 {
+ color: #000000;
+}
+
+a {
+ text-decoration: underline;
+}
+
+a:hover {
+ text-decoration: underline;
+}
+
+h1,h2,h3,h4,h5 {
+ line-height: 1.3;
+ margin-top: 1.5em;
+}
+
+h1.title {
+ text-align: left;
+
+ margin-top: 2em;
+ margin-bottom: 2em;
+ margin-left: 0pt;
+ margin-right: 0pt;
+ color: #000080;
+}
+
+h2.subtitle, h3.subtitle {
+ text-align: left;
+ margin-top: 2em;
+ margin-bottom: 2em;
+ text-transform: uppercase;
+}
+
+h3.author, p.othercredit {
+ font-size: 0.9em;
+ font-weight: normal;
+ font-style: oblique;
+ text-align: left;
+ color: #525D76;
+}
+
+div.titlepage {
+}
+
+div.section {
+}
+
+
+div.authorgroup
+{
+ text-align: left;
+ margin-bottom: 3em;
+ display: block;
+}
+
+div.toc, div.list-of-examples, div.list-of-figures {
+ margin-bottom: 3em;
+}
+
+.toc dt {
+ padding-bottom: 1px;
+}
+
+div.itemizedlist {
+ margin-top: 0.5em;
+ margin-bottom: 0.5em;
+}
+
+ol,ul {
+}
+
+li {
+}
+
+pre {
+ margin: .75em 0;
+ line-height: 1.0;
+ color: black;
+}
+
+pre.programlisting {
+ font-size: 9pt;
+ padding: 5pt 2pt;
+ border: 1pt solid black;
+ background: #eeeeee;
+ font-family: "Courier New",courier;
+}
+
+div.table {
+ margin: 1em;
+ padding: 0.5em;
+ text-align: center;
+}
+
+div.table table {
+ display: block;
+}
+
+div.table td {
+ padding-right: 5px;
+ padding-left: 5px;
+}
+
+div.table p.title {
+ text-align: center;
+ margin-left: 5%;
+ margin-right: 5%;
+}
+
+p.releaseinfo, .copyright {
+ font-size: 0.7em;
+ text-align: left;
+ margin: 0px;
+ padding: 0px;
+}
+
+div.example {
+
+}
+
+div.note, div.important, div.informalexample, div.tip, div.caution {
+ margin: 1em;
+ padding: 0.5em;
+ border: 1px solid gray;
+ background-color: #f8f8e0;
+}
+
+div.important th, div.note th, div.tip th {
+ text-align: left;
+ border-bottom: solid 1px gray;
+}
+
+div.navheader, div.navheader table {
+ font-family: sans-serif;
+ font-size: 12px;
+}
+
+div.navfooter, div.navfooter table {
+ font-family: sans-serif;
+ font-size: 12px;
+}
+
+div.figure {
+ text-align: left;
+ margin-top: 1em;
+ margin-bottom: 1em;
+}
+
+div.figure p.title {
+ text-align: left;
+ margin: 0.5em;
+ padding: 0.5em;
+}
+
+div.example p.title {
+}
+
+div.figure img {
+ padding: 0.5em;
+ margin: 0.5em;
+}
+
+div.revhistory {
+ font-size: 0.8em;
+ width: 90%;
+ margin-left: 5%;
+ margin-top: 3em;
+ margin-bottom: 3em;
+}
+
+div.revhistory table {
+ font-family: sans-serif;
+ font-size: 12px;
+ border-collapse: collapse;
+}
+
+div.revhistory table tr {
+ border: solid 1px gray;
+}
+
+div.revhistory table th {
+ border: none;
+}
+
+div.literallayout {
+ background-color: #EEEEEE;
+ border: 1px solid #AAAAAA;
+ padding: 5pt 1em;
+ line-height: normal;
+ font-family: "Courier New",courier;
+}
+
+code.filename, code.filename span.pln {
+}
+
+code.varname, code.varname span.pln, code.varname span.atv, code.varname span.atn {
+ color: blue;
+ font-weight: normal;
+}
+
+span.symbol, span.symbol span.pln, span.symbol span.atn, span.symbol span.tag,
+span.symbol span.atv {
+ color: red;
+ font-weight: normal;
+}
+
+span.command, span.command span.pln {
+ color: #7F0055;
+}
+
+span.token, span.token span.pln, span.token span.atv {
+ color: maroon;
+}
+
+span.package {
+ font-family: monospace;
+}
+
+code.computeroutput {
+ background-color: #FFFFC0;
+ border: 1px solid #A7BCD6;
+ margin: 0.5em;
+ padding: 0.5em;
+}
+
+div.informaltable table {
+ border: 1px solid black;
+}
+
+div.informaltable th {
+ padding: 6px 10px 2px;
+ background-color: navy;
+ color: white;
+}
+
+div.calloutlist td {
+ padding-right: 10px;
+}
+
+span.bold {
+ font-weight: bold;
+}
+
+a.external {
+ background: url(../images/external.png) center right no-repeat;
+ padding-right: 14px;
+}
+
+div.screenshot {
+ /* Clear the float using overflow: hidden*/
+ overflow: hidden;
+ /* IE6 doesn't clear float unless we set width*/
+ width: 100%;
+}
+
+div.screenshot div {
+ border: 1px solid gray;
+ padding: 1em;
+ margin-top: 1em;
+ margin-bottom: 1em;
+ float: left;
+}
+
+/* Syntax highlighting styles start */
+.str{color:#2A00FF;}
+.kwd{color:#7F0055;
+ font-weight:bold;}
+.com{color:#3F7F5F;}
+.typ{color:#000;}
+.lit{color:#066;}
+.pun{color:#660;}
+.pln{color:#000;}
+.tag{color:#000099;
+ font-weight:bold;}
+.atn{color:#009900;}
+.atv{color:#000;}
+.dec{color:#606;}
+
+pre.programlisting{
+ padding:1em;
+ border:1px solid #888;
+ text-align: left;
+ line-height: normal;
+}
+
+@media print{
+ .str{color:#2A00FF;}
+ .kwd{color:#7F0055;
+ font-weight:bold;}
+ .com{color:#3F7F5F;
+ font-style:italic;}
+ .typ{color:#000;
+ font-weight:bold;}
+ .lit{color:#044;}
+ .pun{color:#440;}
+ .pln{color:#000;}
+ .tag{color:#000099;
+ font-weight:bold;}
+ .atn{color:#009900;}
+ .atv{color:#000;}
+}
+/* Syntax highlighting styles end */
Added: incubator/click/trunk/click/documentation/xdocs/src/docbook/click/chapter-best-practices.xml
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/documentation/xdocs/src/docbook/click/chapter-best-practices.xml?rev=752572&view=auto
==============================================================================
--- incubator/click/trunk/click/documentation/xdocs/src/docbook/click/chapter-best-practices.xml (added)
+++ incubator/click/trunk/click/documentation/xdocs/src/docbook/click/chapter-best-practices.xml Wed Mar 11 18:55:49 2009
@@ -0,0 +1,979 @@
+<?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-best-practices" remap="h1">
+ <title>Best Practices</title>
+
+ <para> This section discusses Best Practices for designing and building Click
+ application. The following topics are covered:
+ </para>
+
+ <orderedlist>
+ <listitem>
+ <para>
+ <link linkend="security">Security</link> - use JEE role based security
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <link linkend="packages-classes">Packages and Classes</link> - project
+ package structures and page classes
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <link linkend="automapping">Page Auto Mapping</link> - use
+ Convention over Configuration
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <link linkend="navigation">Navigation</link> - use Page classes
+ to forward and redirect
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <link linkend="templating">Templating</link> - to standardize your
+ web application
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <link linkend="menus">Menus</link> - centralize your page navigation
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <link linkend="logging">Logging</link> - use Log4j in a base page
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <link linkend="error-handling">Error Handling</link> - use custom
+ error page
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <link linkend="performance">Performance</link> - enhancing page
+ performance
+ </para>
+ </listitem>
+ </orderedlist>
+
+ <sect1 id="security" remap="h2">
+ <title>Security</title>
+
+ <para> For application security it is highly recommended that you use the
+ declarative JEE Servlet path role based security model. While Click pages
+ provide an <methodname>onSecurityCheck()</methodname> method for rolling your own
+ programatic security model, the declarative JEE model provides numerous
+ advantages.
+ </para>
+
+ <para>These advantages include:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para> Its an industry standard pattern making development and maintenance
+ easier.
+ </para>
+ </listitem>
+ <listitem>
+ <para> Application servers generally provide numerous ways of integration
+ with an organisations security infrastructure, including LDAP directories
+ and relational databases.
+ </para>
+ </listitem>
+ <listitem>
+ <para> Servlet security model support users bookmarking pages. When users
+ go to access these pages later, the container will automatically authenticate
+ them before allowing them to access the resource.
+ </para>
+ </listitem>
+ <listitem>
+ <para> Using this security model you can keep your Page code free of
+ security concerns. This makes you code more reusable, or at least easier
+ to write.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>If your application has very fine grained or complex security requirements
+ you may need to combine both the JEE declarative security model and a
+ programmatic security model to meet your needs. In these cases its
+ recommended you use declarative security for course grained access and
+ programmatic security for finner grained access control.
+ </para>
+
+ <sect2 id="declarative-security" remap="h4">
+ <title>Declarative Security</title>
+
+ <para> The declarative JEE Servlet security model requires users to be
+ authenticated and in the right roles before they can access secure resources.
+ Relative to many of the JEE specifications the Servlet security model is
+ surprisingly simple.
+ </para>
+
+ <para>
+ For example to secure admin pages, you add a security
+ constraint in your <filename>web.xml</filename> file. This requires users
+ to be in the <varname>admin</varname> role before they can access to any
+ resources under the <symbol>admin</symbol> directory:
+ </para>
+
+ <programlisting language="xml"><security-constraint>
+ <web-resource-collection>
+ <web-resource-name>admin</web-resource-name>
+ <url-pattern><symbol>/admin/*</symbol></url-pattern>
+ </web-resource-collection>
+ <auth-constraint>
+ <role-name><varname>admin</varname></role-name>
+ </auth-constraint>
+</security-constraint></programlisting>
+
+ <para>The application user roles are defined in the <filename>web.xml</filename>
+ file as <literal>security-role</literal> elements:
+ </para>
+
+ <programlisting language="xml"><security-role>
+ <role-name><varname>admin</varname></role-name>
+</security-role></programlisting>
+
+ <para>The Servlet security model supports three different authentication method:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>BASIC</literal> - only recommended for internal
+ applications where security is not important. This is the easiest
+ authentication method, which simply displays a dialog box to users
+ requiring them to authenticate before accessing secure resources.
+ The BASIC method is relatively unsecure as the username and password
+ are posted to the server as a Base64 encoded string.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>DIGEST</literal> - recommended for internal applications
+ with a moderate level of security. As with BASIC authentication,
+ this method simply displays a dialog box to users requiring them to
+ authenticate before accessing secure resources. Not all application
+ servers support DIGEST authentication, with only more recent
+ versions of Apache Tomcat supporting this method.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>FORM</literal> - recommended applications for where
+ you need a customised login page. For applications requiring a high
+ level of security it is recommended that you use the FORM method
+ over HTTPS.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>The authentication method is specified in the <login-method> element.
+ For example to use the BASIC authentication method you would specify:
+ </para>
+
+ <programlisting language="xml"><login-config>
+ <auth-method><varname>BASIC</varname></auth-method>
+ <realm-name>Admin Realm</realm-name>
+</login-config></programlisting>
+
+ <para>To use the FORM method you also need to specify the path to the login
+ page and the login error page:
+ </para>
+
+ <programlisting language="xml"><login-config>
+ <auth-method><varname>FORM</varname></auth-method>
+ <realm-name>Secure Realm</realm-name>
+ <form-login-config>
+ <form-login-page><symbol>/login.htm</symbol></form-login-page>
+ <form-error-page><symbol>/login.htm?auth-error=true</symbol></form-error-page>
+ </form-login-config>
+</login-config></programlisting>
+
+ <para>In your Click <filename>login.htm</filename> page you need to include a
+ special <varname>j_security_check</varname> form which includes the input
+ fields <varname>j_username</varname> and <varname>j_password</varname>.
+ For example:
+ </para>
+
+ <programlisting language="xml"><command>#if</command> ($request.getParameter("<symbol>auth-error</symbol>"))
+<div style="margin-bottom:1em;margin-top:1em;color:red;">
+ Invalid User Name or Password, please try again.<br/>
+ Please ensure Caps Lock is off.
+</div>
+<command>#end</command>
+
+<form method="POST" action="<varname>j_security_check</varname>" name="form">
+<table border="0" style="margin-left:0.25em;">
+ <tr>
+ <td><label>User Name</label><font color="red">*</font></td>
+ <td><input type="text" name="<varname>j_username</varname>" maxlength="20" style="width:150px;"/></td>
+ <td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td><label>User Password</label><font color="red">*</font></td>
+ <td><input type="password" name="<varname>j_password</varname>" maxlength="20" style="width:150px;"/></td>
+ <td><input type="image" src="$context/images/login.png" title="Click to Login"/></td>
+ </tr>
+</table>
+</form>
+
+<script type="text/javascript">
+ document.form.j_username.focus();
+</script></programlisting>
+
+ <para>When using FORM based authentication do <emphasis role="bold">NOT</emphasis>
+ put application logic in a Click Login Page class, as the role of this page
+ is to simply render the login form. If you attempt to put navigation logic
+ in your Login Page class, the JEE Container may simply ignore it or throw
+ errors.
+ </para>
+
+ <para>Putting this all together below is a <filename>web.xml</filename>
+ snippet which features security constraints for pages under the admin
+ path and the user path. This configuration uses the FORM method for
+ authentication, and will also redirect unauthorized (403) requests to the
+ <filename>/not-authorized.htm</filename> page.
+ </para>
+
+ <programlisting language="xml"><web-app>
+
+ ..
+
+ <error-page>
+ <error-code>403</error-code>
+ <location><varname>/not-authorized.htm</varname></location>
+ </error-page>
+
+ <security-constraint>
+ <web-resource-collection>
+ <web-resource-name>admin</web-resource-name>
+ <url-pattern><varname>/admin/*</varname></url-pattern>
+ </web-resource-collection>
+ <auth-constraint>
+ <role-name><symbol>admin</symbol></role-name>
+ </auth-constraint>
+ </security-constraint>
+
+ <security-constraint>
+ <web-resource-collection>
+ <web-resource-name>user</web-resource-name>
+ <url-pattern><varname>/user/*</varname></url-pattern>
+ </web-resource-collection>
+ <auth-constraint>
+ <role-name><symbol>admin</symbol></role-name>
+ <role-name><symbol>user</symbol></role-name>
+ </auth-constraint>
+ </security-constraint>
+
+ <login-config>
+ <auth-method><varname>FORM</varname></auth-method>
+ <realm-name>Secure Zone</realm-name>
+ <form-login-config>
+ <form-login-page><varname>/login.htm</varname></form-login-page>
+ <form-error-page><varname>/login.htm?auth-error=true</varname></form-error-page>
+ </form-login-config>
+ </login-config>
+
+ <security-role>
+ <role-name><symbol>admin</symbol></role-name>
+ </security-role>
+
+ <security-role>
+ <role-name><symbol>user</symbol></role-name>
+ </security-role>
+
+</web-app></programlisting>
+ </sect2>
+
+ <sect2 id="alternatve-security-solutions" remap="h4">
+ <title>Alternative Security solutions</title>
+
+ <para> There are also alternative security solutions that provide extra
+ features not available in JEE, such as RememberMe functionality, better
+ resource mapping and <literal>Post Logon Page</literal> support.
+ (<literal>Post Logon Page</literal> support allows one to specify a default
+ URL where the user will be forwarded after successful login. This feature
+ allows one to embed a login form in all non-secure pages and after successful
+ authentication the user will be forwarded to their home page.)
+ </para>
+
+ <para>Below are some of the alternative security solutions available:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <ulink url="http://static.springframework.org/spring-security/site/index.html">Spring Security</ulink>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink url="http://securityfilter.sourceforge.net/">SecurityFilter</ulink>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink url="http://www.jsecurity.org/">JSecurity</ulink>
+ </para>
+ </listitem>
+ </itemizedlist>
+ </sect2>
+
+ <sect2 id="resources" remap="h4">
+ <title>Resources</title>
+
+ <para>For more information on using security see the resources below:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <ulink url="http://stc.cis.brown.edu/~stc/Projects/Shibboleth/Version-3/Checklist/Tomcat-Authn/FormBasedAuthentication.pdf">
+ Form Based Authentication
+ </ulink> by Louis E. Mauget
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink url="http://java.sun.com/products/servlet/download.html">Servlet Specification</ulink>
+ by Sun Microsystems
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink url="http://en.wikipedia.org/wiki/Basic_authentication_scheme">
+ Basic authentication scheme
+ </ulink>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink url="http://en.wikipedia.org/wiki/Digest_access_authentication">
+ Digest authentication scheme
+ </ulink>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink url="http://en.wikipedia.org/wiki/Https">Https URI scheme</ulink>
+ </para>
+ </listitem>
+ </itemizedlist>
+ </sect2>
+ </sect1>
+
+ <sect1 id="packages-classes" remap="h2">
+ <title>Packages and Classes</title>
+
+ <para> An excellent way to design your project package structure is the
+ classify packages initially by technology. So in a Click application all
+ of our pages would be contained under a <package>page</package> package.
+ This also works very well with the Page automapping feature.
+ </para>
+
+ <para>
+ All the projects domain entity classes would be contained under a
+ <package>entity</package> package, and service classes would be contained
+ under a <package>service</package> directory. Note alternative names for the
+ <package>entity</package> package include domain or model. We also typically
+ have a <package>util</package> package for any stray classes which don't quite
+ fit into the other packages.
+ </para>
+
+ <para>In Java, package names are singular by convention, so we have a util
+ package rather than a utils package.
+ </para>
+
+ <para>An example project structure for a MyCorp web application is illustrated
+ below:
+ </para>
+
+ <figure id="example-project-structure">
+ <title>Example project structure</title>
+ <inlinemediaobject>
+ <imageobject>
+ <imagedata fileref="images/best-practices/packages-classes.png" format="PNG" scale="85"/>
+ </imageobject>
+ </inlinemediaobject>
+ </figure>
+
+ <para>In this example application we use declarative role and path based security.
+ All the pages in the <package>admin</package> package and directory require the
+ <literal>"admin"</literal> role to be access, while all the pages in the
+ <package>user</package> package and directory require the <literal>"user"</literal>
+ role to be accessed.
+ </para>
+
+ <sect2 id="page-classes" remap="h4">
+ <title>Page Classes</title>
+
+ <para>A best practice when developing application Page classes is to
+ place common methods in a base page class. This is typically used for
+ providing access methods to application services and logger objects.
+ </para>
+
+ <para>For example the BasePage below provides access to Spring configured
+ service objects and a Log4J logger object:
+ </para>
+
+ <programlisting language="java">public class BasePage extends Page implements ApplicationContextAware {
+
+ /** The Spring application context. */
+ protected ApplicationContext applicationContext;
+
+ /** The page Logger instance. */
+ protected Logger logger;
+
+ /**
+ * Return the Spring configured Customer service.
+ *
+ * @return the Spring configured Customer service
+ */
+ public CustomerService getCustomerService() {
+ return (CustomerService) getBean("customerService");
+ }
+
+ /**
+ * Return the Spring configured User service.
+ *
+ * @return the Spring configured User service
+ */
+ public UserService getUserService() {
+ return (UserService) getBean("userService");
+ }
+
+ /**
+ * Return the page Logger instance.
+ *
+ * @return the page Logger instance
+ */
+ public Logger getLogger() {
+ if (logger == null) {
+ logger = Logger.getLogger(getClass());
+ }
+ return logger;
+ }
+
+ /**
+ * @see ApplicationContextAware#setApplicationContext(ApplicationContext)
+ */
+ public void setApplicationContext(ApplicationContext applicationContext) {
+ this.applicationContext = applicationContext;
+ }
+
+ /**
+ * Return the configured Spring Bean for the given name.
+ *
+ * @param beanName the configured name of the Java Bean
+ * @return the configured Spring Bean for the given name
+ */
+ public Object getBean(String beanName) {
+ return applicationContext.getBean(beanName);
+ }
+
+}</programlisting>
+
+ <para>Applications typically use a border template and have a
+ <classname>BorderPage</classname> which extends <classname>BasePage</classname>
+ and defines the template. For example:
+ </para>
+
+ <programlisting language="java">public class BorderPage extends BasePage {
+
+ /** The root Menu item. */
+ public Menu rootMenu = new Menu();
+
+ /**
+ * @see Page#getTemplate()
+ */
+ public String getTemplate() {
+ return "/border-template.htm";
+ }
+}</programlisting>
+
+ <para>Most application pages subclass <classname>BorderPage</classname>, except
+ AJAX pages which have no need for a HTML border template and typically extend
+ <classname>BasePage</classname>. The <classname>BorderPage</classname> class
+ should not include common logic, other than that required for rendering the
+ border template. Common page logic should be defined in the
+ <classname>BasePage</classname> class.
+ </para>
+
+ <para>To prevent these base Page classes being auto mapped, and becoming
+ directly acessible web pages, ensure that there are no page templates which
+ could match their class name. For example the <classname>BorderPage</classname>
+ class above will not be auto mapped to <filename>border-template.htm</filename>.
+ </para>
+
+ </sect2>
+ </sect1>
+
+ <sect1 id="automapping" remap="h2">
+ <title>Page Auto Mapping</title>
+
+ <para>You should use the Click page automapping configuration feature.
+ See the <link linkend="application-automapping">Page Automapping</link>
+ topic for details.
+ </para>
+
+ <para>Automapping will save you from having to manually configure URL path to
+ Page class mappings in your <filename>click.xml</filename> file. If you follow
+ this convention it is very easy to maintain and refactor applications.
+ </para>
+
+ <para>You can also quickly determine what the corresponding Page class is for a
+ page HTML template and visa versa, and if you use the ClickIDE Eclipse plugin
+ you can switch between a page's class and template by pressing Ctrl+Alt+S.
+ </para>
+
+ <para>An example <filename>click.xml</filename> automapping configuration is
+ provided below (automapping is enabled by default):
+ </para>
+
+ <programlisting language="xml"><click-app>
+ <pages package="com.mycorp.dashboard.page"/>
+</click-app></programlisting>
+
+ <para>To see how the page templates are mapped to Page classes set the application
+ <link linkend="application-mode">mode</link> to
+ <literal>debug</literal> and at startup the mappings will be listed out. An
+ example Click startup listing is provided below:
+ </para>
+
+ <literallayout>[Click] [debug] automapped pages:
+[Click] [debug] /category-tree.htm -> com.mycorp.dashboard.page.CategoryTree
+[Click] [debug] /process-list.htm -> com.mycorp.dashboard.page.ProcessList
+[Click] [debug] /user-list.htm -> com.mycorp.dashboard.page.UserList</literallayout>
+ </sect1>
+
+ <sect1 id="navigation" remap="h2">
+ <title>Navigation</title>
+
+ <para> When navigating between Pages using forwards and redirects, you should
+ refer to the target page using the Page class rather than using path. This
+ provides you compile time checking and will save you from having to update
+ path strings in Java code if you move pages about.
+ </para>
+
+ <para>To forward to another page using the Page class:
+ </para>
+
+ <programlisting language="java">public class CustomerListPage extends Page {
+
+ public ActionLink customerLink = new ActionLink(this,"onCustomerClick");
+
+ ..
+
+ public boolean onCustomerClick() {
+ Integer id = customerLink.getValueInteger();
+ Customer customer = getCustomerService().getCustomer(id);
+
+ CustomerDetailPage customerDetailPage = (CustomerDetailPage)
+ getContext().createPage(CustomerDetailPage.class);
+
+ customerDetailPage.setCustomer(customer);
+ setForward(customerDetailPage);
+
+ return false;
+ }
+}</programlisting>
+
+ <para>To redirect to another page using the Page class you can obtain the pages
+ path from the <classname>Context</classname>. In the example below we are passing
+ through the customer id as a request parameter to the target page.
+ </para>
+
+ <programlisting language="java">public class CustomerListPage extends Page {
+
+ public ActionLink customerLink = new ActionLink(this, "onCustomerClick");
+
+ ..
+
+ public boolean onCustomerClick() {
+ String id = customerLink.getValueInteger();
+
+ String path = getContext().getPagePath(CustomerDetailPage.class);
+ setRedirect(path + "?id=" + id);
+
+ return false;
+ }
+}</programlisting>
+
+ <para>A quick way of redirecting to another page is to simply refer to the target
+ class. The example below logs a user out, by invalidating their session, and
+ then redirects them to the application home page.
+ </para>
+
+ <programlisting language="java">public boolean onLogoutClick() {
+ getContext().getSession().invalidate();
+
+ setRedirect(HomePage.class);
+
+ return false;
+}</programlisting>
+ </sect1>
+
+ <sect1 id="templating" remap="h2">
+ <title>Templating</title>
+
+ <para>Use Page templating it is highly recommended. Page templates provide
+ numerous advantages including:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>greatly reduce the amount of HTML you need to maintain</para>
+ </listitem>
+ <listitem>
+ <para>ensure you have a common look and feel across your application</para>
+ </listitem>
+ <listitem>
+ <para>make global application changes very easy</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>To see how to use templates see the
+ <link linkend="page-templating">Page Templating</link> topic. Also see the
+ Click <ulink url="../../examples.html">Examples</ulink> use of page templating.
+ </para>
+
+ </sect1>
+
+ <sect1 id="menus" remap="h2">
+ <title>Menus</title>
+
+ <para> For many applications using the
+ <ulink url="../../extras-api/org/apache/click/extras/control/Menu.html">Menu</ulink>
+ control to centralize application navigation is very useful. Menus are
+ defined in a <filename>WEB-INF/menu.xml</filename> file which is very easy to
+ change.
+ </para>
+
+ <para>A menu is typically defined in the a page border template so they are
+ available through out the application. The Menu control does not support HTML
+ rendering, so you need to define a Velocity macro to programmatically render
+ the menu. You would call the macro in your border template with code like this:
+ </para>
+
+ <literallayout><symbol>#</symbol><varname>writeMenu</varname>(<symbol>$</symbol>rootMenu)</literallayout>
+
+ <para>An advantage of using a macro to render your menu is that you can reuse
+ the code across different applications, and to modify an applications menu you
+ simply need to edit the <filename>WEB-INF/menu.xml</filename> file. A good
+ place to define your macros is in the webroot <filename>/macro.vm</filename>
+ file as it is automatically included by Click.
+ </para>
+
+ <para>Using macros you can create dynamic menu behaviour such as only rendering
+ menu items a user is authorized to access with
+ <ulink url="../../extras-api/org/apache/click/extras/control/Menu.html#isUserInRoles()">isUserInRoles()</ulink>.
+ </para>
+
+ <literallayout><command>#if</command> (<symbol>$</symbol>menu.isUserInRoles())
+ ..
+<command>#end</command></literallayout>
+
+ <para>You can also use JavaScript to add dynamic behaviour such as drop down menus,
+ for example see the Menu page in Click
+ <ulink url="../../examples.html">Examples</ulink>.
+ </para>
+ </sect1>
+
+ <sect1 id="logging" remap="h2">
+ <title>Logging</title>
+
+ <para> For page logging you should use
+ <ulink url="http://logging.apache.org/log4j/">Log4j</ulink> library. An
+ alternative library is the
+ <ulink url="http://jakarta.apache.org/commons/logging/">Commons Logging</ulink>.
+ If you are using Commons Logging please be aware that there have been class
+ loader issues with this library on some application servers. If you are using
+ Commons Logging please make sure you have the latest version.
+ </para>
+
+ <para>The best place to define your logger is in a common base page, for example:
+ </para>
+
+ <programlisting language="java">public class BasePage extends Page {
+
+ protected Logger logger;
+
+ public Logger getLogger() {
+ if (logger == null) {
+ logger = Logger.getLogger(getClass());
+ }
+ return logger;
+ }
+}</programlisting>
+
+ <para>Using this pattern all your application bases should extend
+ <classname>BasePage</classname> so they can use the
+ <methodname>getLogger()</methodname> method.
+ </para>
+
+ <programlisting language="java">public class CustomerListPage extends BasePage {
+
+ public void onGet() {
+ try {
+ ..
+ } catch (Exception e) {
+ getLogger().error(e);
+ }
+ }
+}</programlisting>
+
+ <para>If you have some very heavy debug statement you should possibly use an
+ <methodname>isDebugEnabled</methodname> switch so it is not invoked if debug is
+ not required.
+ </para>
+
+ <programlisting language="java">public class CustomerListPage extends BasePage {
+
+ public void onGet() {
+ if (getLogger().isDebugEnabled()) {
+ String msg = ..
+
+ getLogger().debug(msg);
+ }
+
+ ..
+ }
+}</programlisting>
+
+ <para>Please note the Click logging facility is not designed for application use,
+ and is for Click internal use only. When Click is running in
+ <literal>production</literal> mode it will not produce any logging output.
+ </para>
+
+ </sect1>
+
+ <sect1 id="error-handling" remap="h2">
+ <title>Error Handling</title>
+
+ <para> In Click unhandled errors are directed to the
+ <ulink url="../../click-api/org/apache/click/util/ErrorPage.html">ErrorPage</ulink>
+ for display. If applications require additional error handling they can create
+ and register a custom error page in <filename>WEB-INF/click.xml</filename>.
+ For example:
+ </para>
+
+ <programlisting language="xml"><pages package="com.mycorp.page" automapping="true"/>
+ <page path="click/error.htm" classname="ErrorPage"/>
+</pages></programlisting>
+
+ <para>Generally applications handle transactional errors using service layer code
+ or via a servlet
+ <ulink url="http://java.sun.com/products/servlet/2.3/javadoc/javax/servlet/Filter.html">Filter</ulink>
+ and would not need to include error handling logic in an error page.
+ </para>
+
+ <para>Potential uses for a custom error page include custom logging. For example
+ if an application requires unhandled errors to be logged to an application
+ log (rather than System.out) then a custom
+ <ulink url="../../click-api/org/apache/click/util/ErrorPage.html">ErrorPage</ulink>
+ could be configured. An example <classname>ErrorPage</classname> error logging
+ page is provided below:
+ </para>
+
+ <programlisting language="java">package com.mycorp.page.ErrorPage;
+..
+
+public class ErrorPage extends org.apache.click.util.ErrorPage {
+
+ public void onDestory() {
+ Logger.getLogger(getClass()).error(getError());
+ }
+}</programlisting>
+ </sect1>
+
+ <sect1 id="performance" remap="h2">
+ <title>Performance</title>
+
+ <para>Yahoo published a list of
+ <ulink url="http://developer.yahoo.com/performance/rules.html">best practices</ulink>
+ for improving web application performance.
+ </para>
+
+ <para>Click Framework provides a
+ <ulink url="../../extras-api/org/apache/click/extras/filter/PerformanceFilter.html">PerformanceFilter</ulink>
+ which caters for some of these rules. However not all rules can be easily automated.
+ </para>
+
+ <para>This section will outline ways to apply rules which are not covered by the
+ PerformanceFilter namely,
+ <ulink url="http://developer.yahoo.com/performance/rules.html#num_http">#1 - Minimize HTTP Requests (by combining files)</ulink>
+ and <ulink url="http://developer.yahoo.com/performance/rules.html#minify">#10 - Minify Javascript and CSS</ulink>.
+ </para>
+
+ <para>Rule #1 also mentions
+ <ulink url="http://alistapart.com/articles/sprites">CSS Sprites</ulink>,
+ a method for combining multiple images into a single master image. CSS Sprites
+ are not covered here.
+ </para>
+
+ <para>It is worth pointing out that its not necessary to blindly optimize
+ every page in your application. Instead concentrate on popular pages, for
+ example a web site's <emphasis>Home Page</emphasis> would be a good
+ candidate.
+ </para>
+
+ <para>There are a couple of tools that are useful in applying Rule #1 and #10:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <ulink url="http://developer.yahoo.com/yui/compressor/">YUICompressor</ulink>
+ - minifies and compresses JavaScript and CSS files so less bytes have to
+ be transferred across the wire.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink url="http://code.google.com/p/javaflight-code/">Ant Task for YUICompressor</ulink>
+ - an Ant task that uses YUICompressor to compress JavaScript and CSS files.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink url="http://www.crockford.com/javascript/jsmin.html">JSMin</ulink>
+ - similar to YUICompressor but only minifies (remove whitespace and newlines)
+ JavaScript files and does no compression at all. An advantage of JSMin
+ over YUICompressor is that its faster and can be used at runtime to minify
+ JavaScript, while YUICompressor is most often used at build time.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Below are some articles outlining how to use YUICompressor and Ant to
+ concatenate and compress JavaScript and CSS files:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <ulink url="http://www.julienlecomte.net/blog/2007/09/16/">Article</ulink>
+ explaining how to use Ant and YUICompressor for compression.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink url="http://javaflight.blogspot.com/2008/01/introducing-yui-compressor-ant-task.html">Article</ulink>
+ outlining how to use a special YUICompressor Ant Task for compression.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Using one of the approaches above you can concatenate and compress all
+ JavaScript and CSS for your Pages into two separate files, for example
+ <filename>home-page.css</filename>
+ and <filename>home-page.js</filename>. Note that the two files must include
+ all the JavaScript and CSS that is generated by the Page and its Controls.
+ Then you can instruct Click to <emphasis>only</emphasis> include the two
+ compressed files, home-page.css and home-page.js.
+ </para>
+
+ <para>Click makes use of the utility class
+ <ulink url="../../click-api/org/apache/click/util/PageImports.html">PageImports</ulink>
+ to include the CSS and JavaScript. PageImports exposes the method
+ <ulink url="../../click-api/org/apache/click/util/PageImports.html#setInitialized(boolean)">setInitialized(boolean)</ulink>,
+ which controls when PageImports are fully initialized. Once PageImports have
+ been initialized, no other CSS and JavaScript will be included.
+ </para>
+
+ <para>Knowing this one can override
+ <ulink url="../../click-api/org/apache/click/Page.html#getPageImports()">Page.getPageImports()</ulink>,
+ and import the necessary JavaScript and CSS files and then set PageImports to
+ <literal>initialized</literal>, forcing PageImports to skip other CSS and
+ JavaScript files.
+ </para>
+
+ <para>Here is an example:</para>
+
+ <programlisting language="java">public class HomePage extends Page {
+
+ private Form form = new Form("form");
+
+ public void onInit() {
+ form.add(new EmailField("email");
+ addControl(form);
+ }
+
+ public void getPageImports () {
+ PageImports pageImports = super.getPageImports();
+ String contextPath = getContext().getRequest().getContextPath();
+
+ String cssInclude = contextPath + "/assets/css/home-page.css";
+ pageImports.addImport("<link type=\"text/javascript\" href=\"" + cssInclude + "\"/>");
+
+ String jsInclude = contextPath + "/assets/js/home-page.js";
+ pageImports.addImport("<script type=\"text/javascript\"
+ src=\"" + jsInclude + "\"></script>");
+
+ // Set pageImports to initialized so that no other CSS and JavaScript
+ // files will be included.
+ pageImports.setInitialized(true);
+ }
+}</programlisting>
+
+ <para>Using the following <filename>border-template.htm</filename>:
+ </para>
+
+ <programlisting language="xml"><html>
+ <head>
+ <title>Click Examples</title>
+ ${cssImports}
+ </head>
+ <body>
+
+ ...
+
+ ${jsImports}
+ </body>
+</html></programlisting>
+
+ <para>the rendered HTML will include one CSS and one JavaScript import:</para>
+
+ <programlisting language="xml"><html>
+ <head>
+ <title>Click Examples</title>
+ <link type="text/css" rel="stylesheet"
+ href="/click-examples/assets/css/home-page.css" title="Style"/>
+ </head>
+ <body>
+
+ ...
+
+ <script type="text/javascript" src="/click-examples/assets/js/home-page.js"></script>
+ </body>
+</html></programlisting>
+
+ <para>A live demo is available
+ <ulink url="http://www.avoka.com/click-examples/general/page-imports-example.htm">here</ulink>
+ </para>
+
+ </sect1>
+</chapter>