Adapt Manual

This is a brief introduction for version 3.5 of Adapt (May 2002). It does not cover all the available facilities of the system. For a more complete picture, browse the API documentation.

Contents

Installation
Configuration
Databases
Users
Background
Versions

Installation

These instructions are based on Tomcat and MySql. For more information on Web servers and database systems, see below.

On Windows:

On Unix/Linux:

You can check that the Adapt system has been installed properly by creating a minimal JSP page, say example1.jsp, containing:

<%@ page import="adapt3.*" %>
<%
   Adapt a = new Adapt(pageContext); 
   a.p("Hello");
%>

The first line imports the adapt3 package. The <% and %> brackets tell JSP that some Java code is being included in the page. The first line of Java creates an Adapt object, which provides support services for the page. The next line prints a string into the HTML for the page; it is just an abbreviation for out.print("Hello").

Configuration

To configure the Adapt system, you can create a page init.jsp in the root directory of your Web site. The Adapt system arranges for this page to be visited, if it exists, every time the Web server is started up.

The init.jsp page can be used, for example, to set up database parameters once and for all for the whole site. Once the jar file containing the JDBC driver is installed in the Web server, an init.jsp page can be written something like this:

<%@ page import="adapt3.*" %>
<%
   Adapt a = new Adapt(pageContext); 
   a.forInclusionOnly();

   String name = "site-db";
   String login = "";
   String password = "";
   String address = "jdbc:mysql://computer-name/db-name";
   String driver = "org.gjt.mm.mysql.Driver";

   Database.clear();
   Database.create(name, login, password, address, driver, 5);
   Adapt.setDefaultDb(name);
%>

Since this page may contain a potentially sensitive database password, if it is stored on a shared computer, its file permissions should be set so that only the Web server (and suitably privileged users) can access it. On the other hand, there is no restriction on which users can visit it. In fact, after the Web server is started up, it will be visited by the first user to browse a page which uses Adapt.

The call a.forInclusionOnly() restricts the page so that it can not be visited directly in a browser, but only indirectly by being "called" from some other page on the same site. This effectively ensures that the page can only be visited as a result of Adapt's initialisation mechanism. The forInclusionOnly call can be removed or commented out for debugging while the page is being developed or altered.

The String variables represent the database parameters. The name is an arbitrary nickname used to access the database from other pages in the Web site. For a simple mysql database with all the default settings, no login name or password is needed to access the database, but the normal practice is to set up a protective login name and password for use by the Web server alone.

The call to Database.clear() is not strictly necessary, but allows, for example, init.jsp to be called from a protected reset or debug page which re-initialises Adapt while the Web server is running.

The call to Database.create() constructs an object which holds the database parameters and a pool of connections to the database. This object is stored statically so that it can be shared across the whole site, and it can be accessed using its abbreviated name, as in the following call to Adapt.setDefaultDb() which ensures that all anonymous database accesses on the site will use this database.

When developing init.jsp, the call to Database.create() may appear to succeed even if the setup is not correct, because the database is not contacted until it is used. A query must be made to test the setup and the parameters.

In addition to database parameters, the init.jsp page is typically also used to set up a site-wide collection of local users, with their passwords and permissions. See the section below on users.

Databases

To author JSP pages well using Adapt, you need to know Java and JSP and SQL, and then use the Adapt API documentation for reference. However, the package provides a class called Adapt which provides abbreviations and convenience methods which, in simple circumstances at least, avoid the need to use any other classes (including Java's servlet-related classes). We have already seen a minimal example:

<%@ page import="adapt3.*" %>
<%
   Adapt a = new Adapt(pageContext); 
   a.p("Hello");
%>

The first few lines and the last line import the package, drop into Java, and create an Adapt object. These lines are always needed. After that, calls in the Adapt class can be used to carry out a wide variety of common tasks. The simplest is to insert text into the page being generated:

   a.p("text");         // insert text into the page (like print)
   a.pl("text");        // insert text and a newline (like println)

To insert a long piece of plain text into the page, it may be more convenient to drop out of Java and then back in again, e.g.:

   ...
%>                     <!-- This ends the preceding Java -->
A long piece of
multi-line HTML text
<%                     // This takes you back into Java
   ...

The query() method makes a database query on the default site database and sets the current table within the Adapt object to the results. The rows() and cols() methods give you the size of the table, and the ph() and pd() methods allow you to insert column headers and data from the table. The following example demonstrates some generic code for displaying a table of results as an HTML table.

   a.query("select * from people");

   a.pl("<table>");
   a.p("<tr align=left>");
   for (int c = 0; c < a.cols(); c++)
   {  a.p("<th>"); a.ph(c);
   }
   a.pl();
   for (int r = 0; r < a.rows(); r++)
   {  a.p("<tr>");
      for (int c = 0; c < a.cols(); c++)
      {  a.p("<td>");
         a.pd(r,c);
      }
      a.pl();
   }
   a.pl("</table>");

From this, you can see that rows and columns are indexed from zero. For the pd() method, there is a version where you pass in the name of the column rather than its index:

   a.pd(r, "surname");

The Adapt package also provides classes Database and Table to hold database and table objects. These are used by the Adapt class, but can also be used directly by the programmer. For example, where data needs to be inserted from multiple queries, the getTable() and setTable() methods can be used to save and restore results. For example:

   a.query("select * from people");
   Table people = a.getTable();
   a.query("select * from places");
   Table places = a.getTable();
   ...
   a.setTable(people);
   ...
   a.setTable(places);
   ...

In addition, the Database class holds a site-wide global list of available databases, accessible using static methods. For example, Database.create() can be used to to set up the parameters to contact a new database, or Database.find() can be used to access one which has already been created for site-wide use in the init.jsp page. The method a.setDb() can then be used to make that database the current one for making queries.

Users

A site may have a number of local users with varying privileges for accessing and updating information on a site. If so, the site administrator can set up a site-wide list of such users using the User.add() method. Each user has a username, an encrypted password, and a list of groups they belong to. This information may be stored in the database, and extracted when the site is initialised by putting code like this into the init.jsp page:

   Adapt.setRealm("Computer Science at Bristol");
   a.query("select username, password, groups from users");
   for (int r = 0; r < a.rows(); r++)
   {  String username = a.d(r,"username");
      String password = a.d(r,"password");
      String groups = a.d(r,"groups");
      User.add(new User(username, password, groups));
   }

The way in which users register their passwords is not covered here, but the plain passwords should be encrypted with the Password.encrypt() method before being stored in the database. The groups are specified as a string with role names separated by dots or commas. It is convenient to include a dot at the start and end, e.g. ".staff.admin.", so that an SQL query can conveniently be used to find everyone with a particular role, e.g. select * from people where groups like '%.staff.%'.

Once the user list has been set up in the init.jsp page, then page authors can protect pages by using the a.protect() method, just after creating the Adapt object for the page:

<%@ page import="adapt3.*" %>
<%
   Adapt a = new Adapt(pageContext);
   a.protect("staff");
   ...
%>

This causes a challenge to be made by the browser. The a.protect() call uses the Password.check() method to check the password that the user types in against the stored encrypted password. The realm name set up in the Adapt.setRealm() call in the init.jsp page is a nickname for a Web site (or group of sites), and is presented to the user in the browser's challenge window. The browser uses this to avoid asking the user for a password when the same site is visited again. If the site has some other protection mechanism (e.g. if .htaccess files are used to protect plain HTML pages in the Apache Web server), the realm names can be set up to be the same so that the user only gets one challenge and not two for pages on the site.

Background

HTML

To use Adapt, you need to be familiar with writing HTML pages. As far as possible, standard HTML or XHTML should be used, to ensure that pages can be read by any browser. For example, many people are not aware that the doctype and title tags are compulsory, but the html, head and body tags are optional. The various versions of the standard can be consulted, and there are many good introductory tutorials:

A very useful quick check of whether a page is standard or not is to go to the validator site and type in the URL of the page you want to check, or use the HTML Tidy program:

Browsers differ in the version of HTML they support (they usually don't even say which!), the extent to which they follow the standard, and in the way in which they implement certain features. If you want your Web pages to be visible to a wide audience, use core features only. You should use more advanced features, especially style sheets, frames, and scripting, with caution, and check that all the browsers you expect to be used to access your site actually display the same results. (Try recent versions of Internet Explorer, Netscape on Windows, and Netscape on Unix. The last two are different because they depend on the native GUI libraries of the platforms they run on.)

JSP and Servlets

Information about JSP and Servlets can be obtained from many sources, including Sun's JSP site, and tutorials:

The Adapt package is designed to be used either in JSP pages or in servlets (although its use in servlets is less well tested). JSP pages and servlets provide exactly the same services (a JSP page is translated into a servlet the first time it is visited after being created or edited). However, JSP pages are quicker and easier to develop, so beginners are recommended to stick to JSP pages, and this tutorial deals only with JSP pages.

One of the aims of Adapt is to reduce the programmer's need to use the fancy features of JSP, so only a few JSP features are needed, and they are explained here.

Plain text. A JSP page can be regarded as an HTML page with embedded Java. If none of the special JSP tags are used, the text is translated into a servlet which prints that text to the browser output stream. The effect is identical to a plain HTML file.

Embedded Java. The <% and %> tags are used to surround a piece of embedded Java code. This code is inserted by the JSP translater between the statements which print the preceding and following HTML text. If most of a page consists of embedded Java, it can be helpful to reverse your point of view and think of the tags %> and <% as being used to print a lump of fixed HTML text.

Definitions. The normal text and embedded Java of a JSP page are translated into a single method within a servlet, namely the method which is called when the page is visited. The <%! and %> tags surround a definition, which is a piece of code which is inserted inside the servlet class, but not inside any method. This feature is used to define supporting methods and supporting (inner) classes for the main Java code. Variables are not usually defined within <%! ... %> tags, because such variables would be shared by all visitors to the page instead of being local to each visit, and would have to be protected against concurrent visits using synchronisation mechanisms. Non-local data is usually handled by putting it in a session object to share it among all visits of one user, or by putting it in a context object, or a static variable of some importable class, to make it global to the whole site.

Declarations. The <%@ and %> tags surround a special JSP declaration. The most important of these is <%@ page import="..." %> which is used to import classes and packages into the translated servlet. These classes or packages must belong to the Java run time system (e.g. java.io.*), or be installed in the Web server (e.g. in Tomcat's lib directory) or be installed in the Web site itself (as class files in the classes subdirectory or as jar files in the lib subdirectory of the WEB-INF directory). Unlike JSP pages, these classes or packages are not necessarily reloaded automatically by the Web server when they are altered, so you may have to restart the Web server each time you change them.

Comments. The <%-- and --%> tags surround JSP comments. These are not translated into the servlet. Within plain HTML text, HTML comments can also be used. They are transmitted to the browser, but do not appear (except using "view source"). Within embedded Java code, Java comments can also be used. They are translated into the servlet, but then discarded when the servlet itself is compiled.

SQL

As well as writing HTML with Java embedded in it, you also need to be able to write database queries in SQL. Although this documentation provides examples of simple SQL queries, it does not cover more advanced aspects of SQL. Once again, standard SQL should be used as far as possible, so that your pages can be used with any database system. Unfortunately, the SQL standard is not online (you have to buy it), so it is better to consult a book or an online tutorial such as:

http://w3.one.net/~jhoffman/sqltut.htm

The SQL query language is only partially standardized, and every database system has dialect variations, so the SQL manual for your particular database system may need to be consulted as well.

Java

For more complex Web pages, you may have to brush up on your Java, and on the features of JSP and Servlet programming which are not covered by Adapt. A good book which covers a wide variety of topics is:

Core Servlets

Tomcat

Adapt can be used with any Web server which supports JSP (version 1.1), and there is an official list at http://java.sun.com/products/jsp/industry.html. These notes are based on Windows, but Unix is similar. Download the latest stable version of Tomcat (e.g. jakarta-tomcat-4.0.3.zip) from jakarta.apache.org/tomcat.

Unzip the file to produce a directory which you can rename to (say) C:\tomcat. To configure, edit the files C:\tomcat\bin\startup.bat and C:\tomcat\bin\shutdown.bat. At or near the top of each, add these lines (assuming you have the Java compiler installed in C:\jdk1.3 )

Tomcat 3                               Tomcat 4

SET TOMCAT_HOME=C:\tomcat              SET CATALINA_HOME=C:\tomcat
SET JAVA_HOME=C:\jdk1.3                SET JAVA_HOME=C:\jdk1.3

Start Tomcat by typing startup in a DOS shell, or by double clicking on startup.bat. In the latter case, you can shut down Tomcat just by closing its window.

Visit http://computer-name:8080 with your browser. You can build your Web site inside C:\tomcat\webapps\ROOT, or you can edit C:\tomcat\conf\server.xml to arrange for Tomcat to manage some other directory on your computer.

One of the problems with the above setup on Windows is that error messages, and debugging messages produced using System.out.println(...) statements, appear in a DOS window which is only 25 lines deep with no scrollbar. Here is a way to fix this on some versions of Windows. Edit startup.bat and find the line near the bottom which reads

call "...tomcat" start ...

Change the word start to run. This ensures that tomcat runs in the same window, rather than creating a new window for itself. Make a shortcut to startup.bat (which you can keep on your desktop or put in your Start menus). Edit the properties of the shortcut (e.g. by using the properties item on right mouse button menu). Go to the layout pane, and change the height in the "Screen buffer size" entry fromm 25 to (say) 250. Now the window you get when you double click on the shortcut should have a scrollbar which you can use to see the most recent 250 lines.

MySQL

These notes are based on Windows, but are easily adapted for Unix. Download the latest stable version of MySQL (e.g. mysql-3.23.41-win.zip ) from www.mysql.com. Unzip into a temporary directory and run setup.exe, installing into C:\mysql .

Start the server by running C:\mysql\bin\mysqld --standalone. This command can be put into the Start/Programs/Startup menu so that the server is started whenever the computer is switched on. Alternatively, on Windows NT or 2000, run mysqld --install, goto Start/Settings/Control-Panel/Services, find the mysql entry that has just been installed, check that it is set to automatic, and start it.

Type mysqladmin create db-name using whatever database name you choose. Now you can run mysql to get a command line interface to the database. The first command to give is use db-name.

To install a JDBC driver so that mysql can be accessed from Java, download (e.g.) mm.mysql.jdbc-2.0.4-bin.jar from mmmysql.sourceforge.net and put it in C:\tomcat\lib\. The driver string to use in Java is "org.gjt.mm.mysql.Driver" and the form of the address string is "jdbc:mysql://computer-name/db-name".

Versions of Adapt

Version 1 of Adapt consisted of a few extra HTML tags for looping through rows and columns of database queries, and inserting data from fields. There was no facility for programming.

Version 2 was a re-implementation of the same idea in JSP, using the tag library mechanism to define the extra tags. This was reasonably successful, but for more complicated JSP pages, there were some irritations. First, the tags had to follow the XML conventions, making them longer and more complex, so for example a simple insertion of data of the form <d name> in version 1 became <a:d col='name'/> in version 2. Second, the facilities for making decisions and looping were clumsy and incomplete, meaning that it was still desirable or necessary to drop into Java on occasions. Third, the interactions between the tags and the Java, and the problems with switching back and forth between them, were complex, making errors likely and difficult to debug.

There were several ways to progress from here. First, the JSP tags could have been extended, but they would never make a complete and decent programmming language in their own right, and their implementation was already very complex. (All "scripting" languages tend to go the same way; they start by providing a simple and non-technical service, they develop into something more complex, and then because they are still incomplete, they get replaced by a "real" programming language.) Second, the interaction between the JSP tags and Java could have been improved, but this would still have left the problem of switching back and forth. In the event, the third option was chosen, which is to aim for everything on a page (except plain text) to be written in Java. The challenges were to reduce the normal verbosity of Java to a minimum, and to ensure that simple effects could be achieved in simple ways with negligible knowledge of Java.

Version 3.0 provides all the main Adapt features directly in Java. In addition to some conventional classes such as Table and User, there is a class Adapt which is designed to provide abbreviations and simplifications.

Version 3.1 added the Upload class.
Version 3.2 fixed a bug in the Upload class.
Version 3.3 added the tr() method.
Version 3.4 added the Download class.
Version 3.5 added the fetch(), setReportSQLExceptions(), sendSecure(), checkSecure() methods.