$Id: develop.xml,v 1.18 2008/10/17 11:33:58 hannes Exp $
Copyright © 2006 - 2012 Hannes Holtzhausen
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
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.
Table of Contents
This document will serve as a step by step guide to writing your first application using the Toolbox API's. To complete all of the tasks described you will require, the Toolbox Framework, a MySQL database server, a Java Servlet container, the FreeMarker Template Engine, Apache Ant (1.6) and J2SE (1.4.2). You can find the source for the example in the doc/samples/web/beans directory of the Toolbox distribution you installed.
The rest of this document assumes that you have installed a Toolbox distribution as discussed in the Installation document and that you have verified the distribution against a Java Servlet container. You can also find API documentation for all the interfaces and classes discussed in this document here
This example may seem long winded for the size of the application, but serves as an example of how to modulerise an application sufficiently to enhance maintainability and extensibility.
This section will provide all the steps required to develop the example application. The example application is a simple data driven application. The application inserts data into a number of tables and provides functionality to the view and update the contents of the database entries. Our application will be called beansdemo.
To start developing you require a source tree, or directory structure, suitable to hold all the source files required by the application. The Toolbox provides a utility script that creates an initial source tree structure. Perform the following to create a new source tree using the dirgen script:
Create the root of the source tree in a directory of your choice. The source root directory should reflect the application name:
The following directories will be visible in the beansdemo directory:
Table 1. Source Tree Description
|doc||All generated application documentation will be placed here. This include text files and Javadoc API documentation.|
|etc||All application configuration files will be created in this directory. This includes Java properties files, XML configuration and deployment descriptors.|
|java||All Java sources relating to the application will be created in this directory.|
The dirgen script provides a starting point, but these directories can be supplemented as required by adding additional top level and sub- directories. Our application will be using a database, and for this purpose we will create one additional directory named sql that will contain the scripts required to generate the required database resources.
This section assumes that you have a running MySQL server and that you have permissions to create users and databases.
Our application requires the use of a database. Create the following two SQL scripts in the sql directory of your source tree:
The next step is to execute our scripts against the MySQL server using the mysql client application. Execute the following commands from the sql directory of your source tree:
-u <root user>
Our database is configured and ready.
The Java Bean pattern is very useful for defining domain objects within an application realm. It allows us to decouple application logic from the details of the physical data store. Developing beans by hand can get rather tedious. The Toolbox provides a convenient utility, called the BeanGenerator, that is capable of generating Java Bean code based on an XML definition.
The utility can be invoked using the beangen script, located in the bin directory of the distribution, and has the following command synopsis:
beangen <-templatedir dir> <-template file> <-beanfile file | -beandir dir> <-outdir dir>
In the previous section we created the required database tables. Now we will create the required beans that will map to the tables using the BeanGenerator utility.
First we have to prepare our java source directory with the required package structure to accommodate our beans. Execute the following command in the java directory of your source tree.
Next we have to author the appropriate XML definitions for our beans in the etc/beans directory of your source tree.
The first section of the definition specifies the class name, package name, imports and class level comment that will be used when generating the bean. The Properties section of the definition specifies all the bean properties for which a get() and a set(..) method will be created. The Mappings section of the document specifies property to database field mappings.
We are now ready to execute the BeanGenerator utility that will create the required Java source files for our defined beans. Perform the following from the top of your source tree:
Our beans are ready for compilation and use.
Application Services, in the context of the Toolbox, are API's that expose the necessary application functionality by hiding all of the complex details involved in the implementation of the application logic.
The Toolbox provides an API, in the form of the toolbox.services.* packages, to develop application services. The API provides high level abstractions for data access, integration (Mail,JMS,etc) and configuration facilities.
First we have to prepare our java source directory with the required package structure to accommodate our service. Execute the following command in the java directory of your source tree.
Next we will develop the Application Service. For the purpose of this example we will implement the application service by first creating a java interface that defines the public interface of the service, followed by an implementation class implementing the interface.
This is not required when using the services API, but serves as an example of doing contract driven implementation; i.e isolating application clients from the implementation details of the service.
Create the following source files in the java/app/services directory of your source tree:
You will notice that the code contains no JDBC API calls. The API provides a high level abstraction for JDBC and provides a flexible configuration facility that will be discussed in the Configuration section.
At this stage we have completed our application backend development by creating the beans and service. In the next section we will start the presentation tier development.
When developing web applications it is useful to be able to handle certain aspects, such as HTTP form submissions, as isolated and atomic pieces of logic. The Toolbox provides an API, in the form of the toolbox.web package, that provides a layer of abstraction on top of Servlet technology that facilitates action driven web application development.
The API provides the WebAction interface to facilitate action driven web application development.
Our application requires that we capture and update information to the database tables. To satisfy this requirement we will develop three WebAction implementations to interact with our ProductService Application Service.
Our action implementations will be subclasses of the toolbox.web.BaseWebAction class. This base class provides access to configuration properties and convenience methods for developing action implementations.
First we have to prepare our java source directory with the required package structure to accommodate our actions. Execute the following command in the java directory of your source tree.
Create the following three source files in the java/app/web directory of your source tree:
The configuration of these action implementations will be covered in the Configuration section.
In some cases it is required to access application data from within a web application view. To ease the interaction between web application views and Application Services we can expose application data by ways of View Helpers.
Our application will be using the FreeMarker Template Engine to render web application views. The Toolbox provides a Servlet implementation that acts as a wrapper around the template engine. This implies that all view requests can be forwarded using a normal javax.servlet.RequestDispatcher to the Toolbox provided wrapper Servlet (toolbox.web.ViewServlet). The ViewServlet also provides a facility to expose methods, implemented using the FreeMarker template API, within view templates.
In our application there is a requirement to view all the entries in the database tables, aswell as a requirement to retrieve a single entity's information using a primary key. To make the interaction between the views and the Application Service as simple as possible we will implement three methods (View Helpers) using the freemarker.template.TemplateMethodModel interface. The interface defines one method, Object exec(List), that must be implemented.
First we have to prepare our java source directory with the required package structure to accommodate our view helpers. Execute the following command in the java directory of your source tree.
Create the following three source files in the java/app/web/helper directory of your source tree.
The configuration of these method implementations will be covered in the Configuration section.
Our application will be using the FreeMarker Template Engine to render the web application views. In this section we will author all the templates required by our application.
First we need to update our source tree to accommodate all the required templates and associated files. Execute the following commands in the htdocs directory of your source tree:
The Toolbox provides some useful template macros to facilitate with the development of XHTML pages. The templates can be viewed in the share/freemarker directory of the distribution.
Create the following templates in the htdocs/ftl directory of your source tree:
master.ftl. The master layout template. All content templates will be included in this template.
default.ftl. The default content template that is displayed when the application is accessed initially.
types.ftl. The product type content template containing the product type form and list of product types.
vendors.ftl. The vendor content template containing the vendor form and list of vendors.
products.ftl. The product content template containing the product form and list of products.
In the previous section we covered all the development aspects of our application. In this section we will discuss and create the required application configuration to make all the various components work together to deliver the application.
Configuration is often an aspect that is overlooked during application development. Configuration provides lots of flexibility with regards to application control and deployment.
The Toolbox provides various configuration facilities for all aspects of the developed application, but authoring all these configuration files can become a tedious and error prone task. For this purpose the Toolbox provides a utility called the ConfGenerator that enables us to create application configurations interactively or via properties files
The utility can be invoked using the $TOOLBOX_HOME/bin/confgen script and has the following command synopsis:
confgen <-list> | <-module module> <-templatedir dir> [-template file] <-outdir dir> [-outfile file] [-properties file]
The following table lists the completed configurations that we require to successfully run our application.
Table 2. Application Configurations
|services.xml||XML configuration file containing the configuration of all application services.|
|dao_direct_env.xml||Backend configuration file that contains details about the database connection, data dictionary and all Application Services.|
|product_service.xml||Configuration file for ProductServiceImpl class|
|orm_config.xml||Configuration file to configure the toolbox.dao.orm.ORMQueryServiceImpl class.|
|web_config.xml||Configuration file to configure all WebActions required by the web application.|
|view_servlet.xml||Configuration file to configure the FreeMarker wrapper servlet (ViewServlet).|
|web_validator.xml||Configuration file to configure HTTP form validation parameters used by WebAction implementations.|
|web.xml||Standard Java Servlet Deployment Descriptor to deploy the ControllerServlet, ViewServlet and associated filters.|
|registry_finaliser.properties||Properties file used by ServiceRegistryFinaliser of the toolbox.web package to destroy the correct service environment when the ControllerServlet is destroyed.|
The next step is to setup a properties file containing all the required properties to initialise our application configuration. Create the config.properties file in the root directory of your source tree.
Now we can use the ConfGenerator to initialise our application configuration. Execute the following commands from the root directory of your source tree.
The next and final step in the application configuration, is to add all our application specific configuration settings. These include our Application Service, WebActions, View Helpers and HTML form validations. The configuration table above can be used to complete all the required configuration.
A message resource file is required by the validator and view templates to display locale sensitive data. Create a properties file in the etc/resources directory of your source tree, named WebActionMessages.properties.
Our web application is now configured.
Up to this point we have not compiled a single Java source file. In this section we will describe the use of Apache Ant to build our Java sources and to build our application distribution file, including a WAR file that can be deployed to a Java Servlet Container.
Ant, like other build tools, allow us to group commands into targets within a configuration file. The targets can then be executed using a single invocation of the ant build tool. This greatly simplifies the process of building application distributions.
We will use two build files to configure the build process for our application. The first file will be to compile the Java sources and create the required jar files and the second will be to create the WAR file and application distribution archive.
In addition to the XML based build configuration files, ant provides a unique feature that enables us to configure generic build properties using standard java properties files.
We will start the build process by creating a generic properties file that will contain some basic configuration properties. Create the build.properties in the root directory of your source tree.
Next we will create the build.xml file that will be used to compile all our java sources and create the required jar files. Create the build.xml file in the java directory of your source tree.
Perform the following command in the java directory of your source tree to compile the java sources and create the required jar files.
The final step in our build process is to create a build.xml file that will assemble the WAR file and application distribution archive. Create the build.xml at the top of your source tree.
Perform the following command at the top of your source tree to create the application distribution and WAR file.
Our application is now ready to be deployed.
The only process that remains, is the process of installing and deploying our application. This document proposes a deployment scenario where the application resources that are not specific to the web component be deployed outside the Java Servlet Container. The following are some of reasons for this:
Container deployment directories are not standard across implementations/vendors and versions. This means that our application resources will always be in a different directory depending on the Container.
Installing applications in a standard known directory, facilitates central administration of application resources and global web component deployment strategies.
Upgrading or changing web containers will not imply a re-installation of the application, but merely redeployment of the web components from the application distribution already installed.
We have also opted to make use of a custom JDBC connection pool and not a JNDI based DataSource. This enables the application to be deployed to any Java Servlet Container without any configuration changes. The Toolbox does however provide the required configuration facilities to use JNDI based DataSources; refer to the Reference Guide and Configuration Reference for information on how to configure the DaoManager. A convenience database configuration for Tomcat is provided here.
Perform the following steps to configure your Servlet Container to successfully run the application.
Ensure that the MySQL JDBC driver is available on the container classpath.
Configure container JVM to be able to locate and run applications based on the Toolbox Services API.
Creata a file named service_registries.properties in a directory that is readable by your Servlet Container user.
Specify the following property inside the file. This property ensures that the Toolbox Services API can locate your applications registry configuration.
Add the following System property to the JVM of your Servlet Container. This will ensure that the Toolbox Services API knows where to find the service_registries.properties file.
We are ready to install and deploy our application. In the Configuration section of this document we configured our application installation directory to be /opt/local/applications/beansdemo. In the context of the Toolbox, /opt/local/applications will be your applications root directory. You may choose a different directory for this purpose, just remember to adjust your application configurations accordingly. Perform the following tasks to install the application distribution:
Next, deploy the beansdemo.war file, located in /opt/local/applications/beansdemo/war to your Java Servlet Container using it's provided deployment tool. If you are using Tomcat as your servlet container, perform the following tasks in the webapps directory of your Tomcat installation/instance:
The application is now deployed and should be accessible via a browser using the following URL: