How to combine handlers

Introduction

Typical applications of the Brazil system combine one or more existing components together with custom additions, consisting of one or more implementations of:
handlers
The primary extension interface, which allows for the custom handling of URL's.
filters
A special type of handler, used in conjunction with the FilterHandler that permits content obtained from other handlers to be rewritten.
templates
Are classes that work in conjunction with the TemplateFilter or TemplateHandler that allow html/XML content to be processed on an entity by entity basis.

When the server is created, it is provided with a Java Properties object, which both defines the interrelationships among the components (handlers, filters, and templates), as well as providing the means for information to be shared among them. This document presents several configurations -- Java properties objects -- that are represented as Java properties files, which may be used directly by the sample Main program.

Traditional Web Server Configurations

The trivial example provides the server with no properties. In this case, the server, listening on port 8080, uses the FileHandler to deliver ordinary files, using the current directory as the document root. This allows the system to be tested out of the box, with no configuration provided.

The following configuration could be used as a simple, traditional web-server. It delivers normal files, runs CGI scripts, provides directory listings, and a "custom" page for not-found documents. On Unix systems, it permits individual users to have "personal pages".
Simple traditional web server configuration

handler=simple
simple.class=sunlabs.brazil.server.ChainHandler
simple.handlers=home file cgi directory missing
home.class=sunlabs.brazil.handler.HomeDirHandler
file.class=sunlabs.brazil.server.FileHandler
cgi.class=sunlabs.brazil.handler.CgiHandler
cgi.suffix=.cgi
directory.class=sunlabs.brazil.handler.DirectoryHandler
missing.class=sunlabs.brazil.handler.NotFoundHandler

Since the server dispatches all requests to a single handler, The ChainHandler allows for multiple handlers to have a chance at servicing the request.

The HomeDirHandler demonstrates the use of side effects, or the ability of one handler to communicate with another by changing the server configuration "on the fly", by modifying the server properties. In this case, the document root the fileHandler uses to find files.

A slightly more complex example

In this example, we've added a password protected section, the ability to "publish" pages, and the redirection to another site of all content in /moved. Changes from the previous configuration are in bold face.
Expanded traditional web server configuration

handler=simple
simple.class=sunlabs.brazil.server.ChainHandler
simple.handlers=home moved protected publish file cgi directory missing
home.class=sunlabs.brazil.handler.HomeDirHandler
file.class=sunlabs.brazil.server.FileHandler
cgi.class=sunlabs.brazil.handler.CgiHandler
cgi.suffix=.cgi
directory.class=sunlabs.brazil.handler.DirectoryHandler
missing.class=sunlabs.brazil.handler.NotFoundHandler
#
# Redirect all request in /moved/... to a new site
#
moved.class=sunlabs.brazil.handler.UrlMapperHandler
moved.match=/moved/(.*)
moved.replace=http://www.moved.here/new/\\1
moved.ignoreCase=true
moved.redirect=true
#
# require basic authentication for all files under /protected/... 
#
protected.class=sunlabs.brazil.handler.BasicAuthHandler
protected.realm=a-secret
protected.prefix=/protected/
protected.mapFile=data.credentials
#
#  Allow netscape style publishing of pages
#
publish.class=sunlabs.brazil.handler.PublishHandler
publish.realm=Sample server web site administration
publish.mapFile=publish.credentials
publish.prefix=/

Brazil style server configuration

Although Brazil can be used to mimic traditional web server functionality, as shown above, it was intended to be used for more dynamic content generation. In the simple example below, we implement a "company phone book" application, using a single "html" file. Here is the server configuration:
Brazil style configuration file for "phone book" application

# Company telephone directory application, demonstrating a sample
# use of the TemplateHandler, incorporating:
# - SetTemplate     for substituting data into html "Template" pages
# - SqlTemplate     for doing data base queries
# - BSLTemplate     for allowing conditional html code, and dynamic
#                   table generation
#
handler=org
org.class=sunlabs.brazil.template.TemplateHandler
org.templates= \
   sunlabs.brazil.template.SetTemplate \
   sunlabs.brazil.template.SqlTemplate \
   sunlabs.brazil.template.BSLTemplate 
#
# Place all query data into the request.props
# object, so we can manipulate it from our template. This provides
# a simple mechanism for replacing the functionality of most CGI
# scripts.
#
org.query=Query.
#
# Use the "mm" jdbc drivers to talk to the MySql database.
# Make sure the jar file containing the driver is in the classpath.
#
org.driver=org.gjt.mm.mysql.Driver
#
# Provide the server and database names to the SQL template
#
org.url=jdbc:mysql://mack.eng/test?user=brazil&password=xxxx

The server configuration operates with the following HTML file. Notice that additional HTML entities are incorporated along with the ordinary HTML, and used by the templates to generate dynamic content. Each template defines one or more new "html entities", that it processes, replacing them with standard HTML, In this example, the SqlTemplate processes the text between <sql>...</sql> and provides data to the other two templates. The SetTemplate replaces entities of the form <get name=xxx> with the value of xxx. The BSLTemplate implements a simple HTML based scripting language (the Brazil Scripting Language) that processes entities of the form:

to allow for dynamic and conditional HTML generation. Note that the form embedded in the page submits the form data back to itself, which is used to create the next version of the page.
HTML template for "phone book" application

<title>Sample company phone book using the SQLtemplate</title>
<h1>Welcome to the company telephone book</h1>
<p>
This page uses SQL to retrieve phonebook information
from an SQL database.
<hr>
<form>
Last name:<input name=name>
</form>
<p>
<if org.error>
  <center><font color=red>Error: <b>
  <get org.error>
  </b></font></center>
</if>
<if Query.name>
  <sql debug eval prefix=names>
    select id, last, first, mi , phone, location
      from namelist
      where last='${Query.name}'
  </sql>
  <table border=2>
    <foreach name=index property=names.rows>
      <tr>
        <foreach name=field list="first mi last phone location">
          <td><get name=names.namelist.${field}.${index}></td>
        </foreach>
      </tr>
    </foreach>
  </table>
</if>

Additional Examples

As the previous example illustrates, Brazil applications typically involve server configurations operating in conjunction with a set of HTML files to provide the desired functionality, and often use the session management capability to provide individualized content to various users.

More than a dozen example Brazil applications are included with this distribution, in the samples directory. Some are complete, working applications, whereas others are examples that demonstrate how to use a particular set of features.

See the included README file for more information.