The Enhydra Application Framework provides all the infrastructure of
a Web application, but none of the content. You simply add an application
object and a set of presentation objects, and you have a complete Web application.
The Enhydra tools help you to create and compile your application. After
compiling, the result is a singe jar file that is a Servlet. This Servlet
may be served to the Net by the Enhydra Multiserver, or it may be installed
in any Servlet-capable Web server.
The Enhydra Application Framework is like an abstract class in that it does most of the work, and it specifies what pieces you must provide. But rather than being a single class, it is a collection of cooperating classes. Together these classes implement a Servlet which is an almost complete Web application. Similar to how an abstract class can not be instantiated, the Enhydra Application Framework does not implement a complete, usable, application. It has two places where you need to provide Java classes. Your classes fill in the gaps, resulting in a complete application.
You must provide one application object, and a set of presentation objects (one for each URL you want in your application).
You are strongly urged to run the Application Wizard (bin/NewApp) to
create a sample Enhydra application so you can see how applications are
laid out. Newapp creates Java code that implements an application object
and two presentation objects. Throughout this document examples will refer
to the files NewApp creates. See the NewApp documentation
for details on how to use it.
Applications typically do three things to the application object:
Aside from the preprocessor function, which is optional, application objects do not deal with HTML, handle requests or otherwise talk to the net. This is the job of the presentation objects.
Note: your application object must implement the interface com.lutris.appserver.server.Application. We recommend you extend the class com.lutris.appserver.server.StandardApplication. See the Javadoc on these two classes for more detailed information.
In your application's config file, the key Server.AppClass tells the
framework which class to use as the application object.
Presentation objects were given that name because they are in charge of how your application's data and results are presented to the client (the Web browser). See the section "Lutris Recommends" below for more details.
When a request is sent to your application, the framework receives it (through the Servlet interface), and determines which presentation object to pass the request on to. The presentation object is then located (via the class loader), instantiated and called. All this happens automatically. Presentation objects do not need to notify the framework that they exist. The framework, driven by the URLs it is asked for, will attempt to locate the corresponding Java classes.
Only requests for URLs that end in ".po" (presentation object) will result in calling a presentation object. All other types of requests are handled by serving a static file, just like a normal Web server. This lets you mix dynamic content pages (.po) in with normal html files (.html) and images (.gif, .jpeg). Rather than being files on a disk, these are typically archived into the application's jar file. The class loader is used to read the files (getResourceAsStream()). This lets you archive your entire application, pictures and all, into a single jar file. If you run "bin/NewApp MyApp", an example of this is the file myApp/presentation/media/enhydra.gif. When a request for the URL media/enhydra.gif arrives, the framework automatically reads the file and writes it to the net, without bothering the application.
If you run "bin/NewApp MyApp", then the files myApp/presentation/Welcome.jhtml and myApp/presentation/Redirect.java are the two presentation objects for the application (the .jhtml file is compiled into a Java file by Enhydra JDDI, which is then compiled into a Java class). The application only has two presentation objects: the URLs Welcome.po and Redirect.po are the only URLs the application responds to. All other URLs result in the standard file not found response (an optional special case is the URL /. See the config file MyApp.conf for an explanation).
In the application's config file, the key Server.PresentationPrefix specifies the root of the Java packages containing the presentation objects (with / instead of . separators). Suppose that the presentation prefix is "application/foo/bar". Then suppose a request arrives for the URL "login/remote/Login.po". The framework will put these two together resulting in the class name "application.foo.bar.login.remote.Login". The framework will then attempt to load this class. If it is found, the request is sent to it. If it is not found a file not found response is returned.
Note: presentation objects must implement the interface com.lutris.appserver.server.httpPresentation.HttpPresentation. See the Javadoc for this class for more details.
Because most presentation objects emit dynamic HTML, they can be written
using Document Object Model (DOM) access to the HTML (see Writing
Presentation Objects with XMLC below). or they can be created by the
Enhydra JDDI compiler. They can also be written by hand, by simply writing
a Java class that implements HttpPresentation.
In the HTML, you add "ID=Name" to whatever tag you want access to. For example:
<B ID=FirstName>John</B> <I ID=LastName>Doe</I>
The resulting class will have getFirstName(), setFirstName(), getLastName() and setLastName() classes. You simply call the set method, then call the class's toHtml() method to get the HTML for the entire page (which you would then write out to the Net). If you want DOM access to the whole page, simply add an ID field to the <BODY> tag.
We have found that for large projects is it very important to minimize the interference between the software engineers and the graphic designers, who use use HTML tools that have a tendency to reformat entire files. The small amount of extra work to coordinate with designers in the beginning of the project will be paid back many times over at the end of the project when the engineers can fix bugs while the graphic artists redo the entire style of the site, and the two changes will not interfere with each other.
DOM allows access to XML files. So the XML Compiler will also allow
for presentation objects to serve dynamic content XML.
You create a ".jhtml" file. You may start by simply renaming a plain HTML file. Then, by adding special <JDDI> tags, you add Java code to the file. As a timesaving shortcut you may also use "JDDI fields" in the HTML. You set their values in Java code, then in the HTML you simply put (@fieldName@), and the Enhydra JDDI field will be replaced with it's value. It's a way to avoid having to use <JDDI> tags every place you want dynamic content.
Most JDDI fields are set in your Java code, however a few are automatically created for you. For each cgi-bin argument to your page, an Enhydra JDDI field is initialized. Suppose the query string "?name=Andy" is appended to the URL to your presentation object. Then you could access this value by using the Enhydra JDDI field (@cgiArgs.name:Smith@). All the names will start with cgiArgs.. Only the values are created, nothing happens if you do not add the Enhydra JDDI field to your HTML. In the previous example, the ":Smith" is used to provide default text. This prevents an error from occuring if no query string is sent to the URL.
Please refer to the Enhydra JDDI documentation for more details.
At compile time, Enhydra JDDI reads in the .jhtml file and outputs a
temporary Java file. This Java file is then compiled, resulting in a class
file. The temporary Java file is then deleted. The temporary file is a
Java class that implements HttpPresentation: you have simply used JDDI
to do the work of coding up a presentation object for you. But the resulting
presentation objects are not special: the framework does not know how the
presentation object was created.
A good rule of thumb is: if you have a lot more code than content, you
may want to simply write the class yourself. The framework does not differentiate
between presentation objects: anything an Enhydra JDDI presentation object
can do a "by hand" presentation object can do (i.e., the framework doesn't
know how the class was made).
Designing your application this way minimizes the impact on your application when you switch databases, file formats or URL layouts. The Enhydra Application Framework only requires that you use presentation objects. The business and data classes you create are up to you. When you run NewApp, it creates directories business and data for you to add these objects.
An additional benefit of designing your application this way is that
you will be able to use the Data
Object Design Studio (DODS) to create your data objects for you. This
tool will be released very soon (it is in final testing). You graphically
create your objects, and it creates both Java code that implements them
(with get and set methods that talk SQL to the database), and the SQL code
to create the required tables in your database. Please subscribe to the
Enhydra mailing list
to receive an announcement when DODS is released.
Any data that is application-wide (shared across all pages and all users)
should be kept in the application object. Any data that is user-wide (needed
across all URLs a user goes to, but one copy per user) should be kept in
SessionData. Any data that is page-specific (only needed by one page, but
shared across all accesses to the page) should be stored as static fields
of the presentation object.
The database manager maintains a pool of JDBC connections to a database, allowing for much faster database access. SQL queries are also cached, again allowing for faster database access.