Mapper Logo
.

Quick Usage Guide for MapperXML

Contents

Introduction

The purpose of this guide is to provide a quick guide to using MapperXML for the web. This guide assumes you have an environment already setup to run your servlets. This guide does not cover web deployment strategy since MapperXML does not have any special requirements.

Back to Contents

Requirements for MapperXML

The following are the current requirements for MapperXML:

  • Java VM 1.4
  • Servlet runner (eg TomCat, JBoss, WebSphere(tm), iPlanet(tm))
  • An XML Parser (eg JTidy, Xerces or JAXP) or a DOM builder (eg XMLC)
Back to Contents

Building the Main Servlet

The main servlet is simply a mediator or dispatcher in the MapperXML framework. It is responsible for creating ServletForms as needed and dispatching requests to them. There are a variety of implementations possible:

  • Create a servlet which dispatches requests to a single ServletForm
  • The servlet can act as a front controller which simply dispatches requests to the specific MapperXML ServletForm
  • You can use the MapperXML ServletApp which dispatches, pools and recycles ServletForms

The following code example is the simplest approach (although not best performance):

  public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    ServletForm form = new MyServletForm();
    try {
      form.doGet(request, response);
    }
    catch (Exception ex) {
      throw new ServletException("Problem encountered: " + ex.getMessage(), ex);
    }
  }
        

The following example uses MapperXML's ServletApp. The ServletApp makes use of a ServletFormFactory which parses the URL to determine which ServletForm to invoke, creates new ServletForms as needed, and recycles and pools used ServletForm.

package com.taursys.examples.simpleweb;

import javax.servlet.ServletException;
import javax.servlet.ServletConfig;
import com.taursys.servlet.ServletApp;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import com.taursys.debug.*;

public class MainServlet extends ServletApp {

  public void init(ServletConfig config) throws ServletException {
    super.init(config);
    getFactory().addPackage("/","com.taursys.examples.simpleweb");
    getFactory().setDefaultFormName("com.taursys.examples.simpleweb.FirstPage");
    // Set defaultClassLoader if mapperxml.jar is shared & not in your app's .war
    getFactory().setDefaultClassLoader(getClass().getClassLoader());
    // Set suffix for servlet forms - can be blank - default is .sf
    getFactory().setServletFormSuffix(".sf");
    // Set default logging
    Debug.setLoggerAdapter(new SimpleLogger(Debug.DEBUG));
  }

  public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    // request.setAttribute("com.yourname.resourcename", yourSharedResource);
    super.doGet(request, response);
  }
}
        

The remaining examples are based on using the above ServletApp.

Back to Contents

Building a ServletForm

The ServletForm in MapperXML corresponds to a single web page. The html web page is built and maintained with conventional web authoring tools. There are no special tags in the html document. The only requirements is that an identifier attribute be set on the html tags that contain the portion of the form you wish to dynamically change. By default, MapperXML uses the ID attribute to identify tags. Below is the html document which we will use in the following examples:

<html>
<head>
  <title>MapperXML Example: The FirstPage</title>
</head>
<body>
  <h1>MapperXML Example: The FirstPage</h1>
  <p>The current time is: <span id="currentTime">00:00:00</span></p>
  <p>This page was originally created at: <span id="createTime">00:00:00</span></p>
</body>
</html>
        

In order to manipulate the above html document, the ServletForm requires an in-memory representation. The ServletForm uses a W3C Document Object Model (DOM) to accomplish this. There are a number of ways to construct a DOM for the html document. There are no restrictions on the method you choose. Below are some examples:

  • Create the DOM by parsing the html document at runtime (eg using JTidy, Xerces or JAXP)
  • Create a Java class which will assemble the DOM (using a tool like XMLC)

In our example we will use a parser to create the DOM. The ServletForm defines an initForm() method which you can override. This method is only invoked once per instance. This is a good place to create the DOM. The build in behavior will invoke a default parser (see Javadoc for com.taursys.dom.DocumentAdapterBuilderFactory.newDocumentAdapterBuilder for more information).

  public MyForm() {
    this.setDocumentURI("resource:///forms/MyForm.html");
  }

  protected void initForm() throws java.lang.Exception {
    // invoke superclass to parse MyForm.html
    super.initForm();	
  }
        

Alternatively, you can manually create or parse the DOM.

  public MyForm() {
  }

  protected void initForm() throws java.lang.Exception {
    super.initForm(); // no action if documentURI property is undefined
    DOMParser parser = new DOMParser();
    InputSource is = new InputSource(
        FirstPage.class.getResourceAsStream("FirstPage.html"));
    parser.parse(is);
    this.setDocument(parser.getDocument());
  }
        

Note: MapperXML uses a DocumentAdapter to hold and manipulate the DOM Document. The DocumentAdapter protects the application from differences between the DOM versions. The World Wide Web Consortium's Java Language Binding for the DOM, has changed the DOM's interface as new versions are released. The different versions have added and removed methods (normally a bad thing to do in Java). This created a challange to be able to design an application that could work with any version. Using an Adapter pattern solved the problem. There can be different implementations of the DocumentAdapter interface that can work with the various versions of the DOM. The current version of MapperXML contains a single, general purpose adapte,: DOM_1_20000929_DocumentAdapter, which works with most DOM versions.

At this point you can run the application and it will display the html page unchanged. Now we can add code to dynamically change the content. There are two ways the change the content:

The following show a very simple example of directly manipulating the DOM through the MapperXML document. Add this code to the end of the initForm method:

    // Display the original time this form was created
    getDocumentAdapter().setElementText("createTime", new Date().toString());
        
Back to Contents

Invoking the ServletForm

The path to invoke the ServletApp and ServletForm depends on how your Servlet runner works and what you have specified in your deployment descriptor (web.xml for Servlet 2.2+) and/or how you have have mapped your servlet in the Servlet runner configuration file (pre Servlet 2.2).

Some IDE environments (eg JBuilder(tm)) have built-in Servlet runners. You will have to consult with your IDE documentation for examples of invoking and mapping servlets.

The invocation syntax consists of the following parts:

        protocol://host[:port]/context/servlet-mapping[/servlet-form[.suffix]][?query-parameters]
        

The following are the parts of the url:

  • port - this is the port that your servlet runner is listening on. If it is using the default (:80) then you can ommit it, otherwise it is required
  • context - the context for your servlet application.
  • servlet-mapping - the path to invoke your servlet. This depends on what you have in web.xml or the servlet runner configuration file.
  • servlet-form - if you omit the servlet-form from the url, the ServletApp will invoke the default ServletForm you set.
  • suffix - the suffix used for ServletForms. The suffix is set in your ServletApp (see example above). The suffix can be set to blank. The default suffix is ".sf".
  • query-parameters - You can include query parameters if needed.

The following are some examples of invocation:

        http://localhost:8080/servlets/com.taursys.examples.test.MyServletApp
            - invokes MyServletApp and uses its default ServletForm

        http://localhost:8080/mapperex/main/MyPage.sf
            - invokes the ServletApp that is mapped to "/main/*" and the
            ServletForm "MyPage".

        http://www.myhost.com/mapperex/main?action=Save
            - invokes the ServletApp that is mapped to "/main/*" and the
            default ServletForm with the query parameter action=Save.
        

NOTE: The examples in this document will use the notation [servlet-url] to represent "protocol://host[:port]/context/servlet-mapping".

Back to Contents

Using Components in the ServletForm

MapperXML has a number of components available which you can use with your web application. These components are very similar to GUI components and behave much the same. Below are the core components:

  • TextField - acts as a normal field. It can receive input and can render its value to the DOM.
  • Parameter - acts as an input only component. it is notified of input before other components and before the open() method is invoked.
  • SelectField - acts like a JComboBox. Like the TextField it can receive input and can render its value to the DOM.
  • Trigger - acts like a JButton. It is triggered when its textValue is received.
  • Template - acts somewhat like a JTable. It can display multiple occurances of data items. It can be used to fill an html table.

To use components in a ServletForm, you must do the following:

  • Use the HTMLComponentFactory to automatically create and bind components. (See MapperXML Application Developer Guide section 3.8)
  • -- OR --
  • Create the component (usually as an instance variable)
  • Set the component properties (set the 'id' property to bind it to the DOM)
  • Add the component to a container (ServletForm itself or another sub-container)
Back to Contents

Using a TextField Component

A text field can be used to both input and display data. Set the 'id' property to have it display its value in the DOM. Set the 'parameter' property to have it receive input form the request. Below is an example which sets the current time when the form is opened.

package com.taursys.examples.simpleweb;

import com.taursys.servlet.ServletForm;
import com.taursys.xml.TextField;
import com.taursys.util.DataTypes;
import org.xml.sax.InputSource;
import org.apache.xerces.parsers.DOMParser;
import java.util.Date;

public class FirstPage extends ServletForm {
  TextField currentTime = new TextField(DataTypes.TYPE_DATE);

  public FirstPage() {
    try {
      jbInit();
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }

  private void jbInit() throws Exception {
    currentTime.setParameter("mytime");
    currentTime.setId("currentTime");
    this.add(currentTime);
  }

  protected void initForm() throws java.lang.Exception {
    super.initForm();
    DOMParser parser = new DOMParser();
    InputSource is = new InputSource(
        FirstPage.class.getResourceAsStream("FirstPage.html"));
    parser.parse(is);
    this.setDocument(parser.getDocument());
    getDocumentAdapter().setElementText("createTime", new Date().toString());
  }

  protected void openForm() throws java.lang.Exception {
    currentTime.setValue(new Date());
  }
}
        

With the above code, the current time will now appear on the form each time it is invoked. The value of the TextComponent is being set each time the form is open.

To make this an input field, simply set the 'parameter' property. For this example, we will allow the override of the current time through an http query parameter called 'mytime'. Modify the jbInit method as follows:

  private void jbInit() throws Exception {
    currentTime.setId("currentTime");
    currentTime.setParameter("mytime");
    this.add(currentTime);
  }
        

Now invoke the servlet form with an additional query parameter: [servlet-url]/FirstPage.sf?mytime=March+27,+2002+8:00:00+AM+AKST

You may need to modify the time format for your locale. The default time format uses DateFormat.getDateTimeInstance( DateFormat.LONG, DateFormat.LONG) to format/parse dates. You can change the format and pattern used by setting properties on the component.

Note: You may have noticed that this url explicitly invokes the FirstPage servlet for using the syntax: <servlet url>/<ServletFormName.sf>. This is a feature of the ServletFormFactory in the ServletApp.

When you invoke the form with the 'mytime' query parameter, the time that appears on the web page is what you passed - not the actual current time. Although the current time is still set in the openForm method, the input value overwrites it.

Note: Input values are dispatched to TextFields AFTER the openForm method.

Back to Contents

Using a Parameter Component

A Parameter is an input-only component. It receives its values before other components, just before the openForm method is invoked. The Parameter is typically used to gather criteria information needed for opening a form (example account number, social security number). You need to set the 'parameter' property for the Parameter component and add it to the container. Below is an example of using a Parameter:

<html>
  <head>
    <title>MapperXML Example: Using A Parameter</title>
    <style></style>
  </head>
  <body>
    <h1>MapperXML Example: Using A Parameter</h1>
    <form method="post" action="/servlet/com.taursys.examples.simpleweb.MainServlet/ParameterPage.sf">
    <input type="text" name="searchKey" value=""/><br/>
    <input type="submit" value="Submit Guess"/>
    </form>
    <br/>
    <p id="results">something to be said</p>
  </body>
</html>
        

Create a ServletForm using the Parameter component:

package com.taursys.examples.simpleweb;

import com.taursys.servlet.ServletForm;
import com.taursys.xml.TextField;
import com.taursys.xml.Parameter;
import com.taursys.util.DataTypes;
import org.xml.sax.InputSource;
import org.apache.xerces.parsers.DOMParser;

public class ParameterPage extends ServletForm {
  Parameter searchKey = new Parameter();
  TextField results = new TextField();

  public ParameterPage() {
    try {
      jbInit();
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }

  private void jbInit() throws Exception {
    searchKey.setParameter("searchKey");
    results.setId("results");
    this.add(searchKey);
    this.add(results);
  }

  protected void initForm() throws java.lang.Exception {
    super.initForm();
    DOMParser parser = new DOMParser();
    InputSource is = new InputSource(
        ParameterPage.class.getResourceAsStream("ParameterPage.html"));
    parser.parse(is);
    this.setDocument(parser.getDocument());
  }

  protected void openForm() throws java.lang.Exception {
    // Set results based on SearchKey
    if (searchKey.getText().length() != 0) {
      if (searchKey.getText().equals("gold"))
        results.setText("You win the prize!!");
      else
        results.setText("Try again. (hint: a yellow precious metal).");
    } else {
      results.setText("Try and guess the password.");
    }
  }
}
        

Invoke the form: [servlet-url]/ParameterPage.sf.

Back to Contents

Binding Components to Value Holders

One of the features of the MapperXML framework is the ability to bind components to ValueHolders. The components in MapperXML all use the Model-View-Controller pattern. The models store their actual value in a ValueHolder. Components (actually their models) create their own default ValueHolders: VariantValueHolder(DataTypes.TYPE_STRING). You can also create your own ValueHolders and bind the components to these instead. The following example will illustrate this capability.

Back to Contents

Displaying Values from a Value Object

For this example we will use a new ServletForm. Below is the html for the new form:

<html>
  <head>
    <title>MapperXML Example: Using A VOValueHolder</title>
    <style></style>
  </head>
  <body>
    <h1>MapperXML Example: Using A VOValueHolder</h1>
    <p>Hello <span id="firstName">John</span> <span id="lastName">Smith</span></p>
  </body>
</html>
        

Next create a ServletForm with two TextFields (firstName and lastName) and a ValueHolder for the person:

package com.taursys.examples.simpleweb;

import com.taursys.servlet.ServletForm;
import com.taursys.xml.TextField;
import com.taursys.util.DataTypes;
import org.xml.sax.InputSource;
import org.apache.xerces.parsers.DOMParser;
import com.taursys.model.VOValueHolder;

public class VOValueHolderPage extends ServletForm {
  TextField firstName = new TextField();
  TextField lastName = new TextField();
  VOValueHolder person = new VOValueHolder();

  public VOValueHolderPage() {
    try {
      jbInit();
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }

  private void jbInit() throws Exception {
    firstName.setPropertyName("firstName");
    firstName.setValueHolder(person);
    firstName.setId("firstName");
    lastName.setPropertyName("lastName");
    lastName.setValueHolder(person);
    lastName.setId("lastName");
    this.add(firstName);
    this.add(lastName);
  }

  protected void initForm() throws java.lang.Exception {
    super.initForm();
    DOMParser parser = new DOMParser();
    InputSource is = new InputSource(
        VOValueHolderPage.class.getResourceAsStream("VOValueHolderPage.html"));
    parser.parse(is);
    this.setDocument(parser.getDocument());
  }
}
        

Next override the openForm method to create the value object and bind it to the person ValueHolder.

  protected void openForm() throws java.lang.Exception {
    Person personVO = new Person(1629, "Pulaski", "Katherine", null);
    person.setValueObject(personVO);
  }

Invoke the form: [servlet-url]/VOValueHolderPage.sf

When the form displays, you will see ' Hello Katherine Pulaski' on the form. The value object can come from any data source (database, J2EE).

The firstName and lastName components are both bound to the person ValueHolder, but are bound to different properties of the Person value object. The 'propertyName' property is what specifies which specific property a component is bound to. The components determine their data type based on the data type of the value object property.

Note: The value object must not be null the first time the components try to access their properties, otherwise you will get the exception: "javax.servlet.ServletException: Unhandled Exception in ServletForm: ModelException occurred during rendering.: ValueObject and ValueObjectClass are both null.". If your value object might be null at runtime, set the 'valueObjectClass' property of the ValueHolder: person.setValueObjectClass(Person.class)

Back to Contents

Storing Values in a Value Object

In addition to displaying values, MapperXML components can receive input and store their values in ValueHolders. This is accomplished by simply building a ServletForm like the above example, and setting the 'parameter' property as shown in an earlier example. If a component receives a parameter, it will store that value in the ValueHolder.

The following example will illustrate this feature. This example will use an HTML form to send and receive the data. The value object will be stored in the session. Below is the new HTML document:

<html>
  <head>
    <title>MapperXML Example: The InputPage</title>
    <style></style>
  </head>
  <body>
    <h1>MapperXML Example: The InputPage</h1>
    <form method="post" action="/servlet/com.taursys.examples.simpleweb.MainServlet/InputPage.sf">
    <input type="text" name="firstName" id="firstName" value="John"/><br/>
    <input type="text" name="lastName" id="lastName" value="Smith"/><br/>
    <input type="submit"/>
    </form>
  </body>
</html>
        

Next build the ServletForm much the same as the first example, except that you will also set the 'parameter' property for the firstName and lastName components.

package com.taursys.examples.simpleweb;

import com.taursys.servlet.ServletForm;
import com.taursys.html.HTMLInputText;
import com.taursys.util.DataTypes;
import org.xml.sax.InputSource;
import org.apache.xerces.parsers.DOMParser;
import com.taursys.model.VOValueHolder;

public class InputPage extends ServletForm {
  HTMLInputText firstName = new HTMLInputText();
  HTMLInputText lastName = new HTMLInputText();
  VOValueHolder person = new VOValueHolder();

  public InputPage() {
    try {
      jbInit();
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }

  private void jbInit() throws Exception {
    firstName.setParameter("firstName");
    firstName.setPropertyName("firstName");
    firstName.setValueHolder(person);
    firstName.setId("firstName");
    lastName.setParameter("lastName");
    lastName.setPropertyName("lastName");
    lastName.setValueHolder(person);
    lastName.setId("lastName");
    this.add(firstName);
    this.add(lastName);
  }

  protected void initForm() throws java.lang.Exception {
    super.initForm();
    DOMParser parser = new DOMParser();
    InputSource is = new InputSource(
        InputPage.class.getResourceAsStream("InputPage.html"));
    parser.parse(is);
    this.setDocument(parser.getDocument());
  }
}

}

Finally, override the openForm method to retrieve the value object from the session. If the object is not in the session (first time), then create a new value object and store it.

  protected void openForm() throws java.lang.Exception {
    // Try to retrieve from session else create
    Person personVO = (Person)getRequest().getSession().getAttribute("ThePerson");
    if (personVO == null) {
      // Create the value object and store
      personVO = new Person(1629, "Pulaski", "Katherine", null);
      getRequest().getSession().setAttribute("ThePerson", personVO);
    }
    // Bind value object to person ValueHolder
    person.setValueObject(personVO);
  }
        

Invoke the form: [servlet-url]/InputPage.sf

When the form first displays, it shows Katherine Pulaski. You can edit the first and last name and press the submit button. Now the next time it displays, it will show your information (assumes your browser supports cookies).

Back to Contents

Displaying Multiple Values from a Collection

MapperXML provides two components which work together to support displaying collections of data. The first component is a CollectionValueHolder which can hold a Java Collection of items. The second component is a Template which replicates and fills a portion of the Document. The Template component is bound to a section of the DOM Document which contains the detail items to display. A typical example is one which binds a Template to a table row "<tr>". The Template can be bound to any element which can contain other elements.

The follwing example will illustrate this feature. Below is the HTML used for this example:

<html>
  <head>
    <title>MapperXML Example: A Template</title>
    <style></style>
  </head>
  <body>
    <h1>MapperXML Example: A Template</h1>
    <table border="1">
      <tr>
        <td >First Name</td>
        <td >Last Name</td>
      </tr>
      <tr id="report">
        <td id="firstName">John</td>
        <td id="lastName">Smith</td>
      </tr>
    </table>
  </body>
</html>
        

The ServletForm will be similar to the previous examples. The notable difference is the fact that the data fields are contained within the Template component instead of the ServleForm container. The other difference is that we are using aa VOCollectionValueHolder to hold multiple value objects. Below is the code for the ServletForm:

public class TemplatePage extends ServletForm {
  TextField firstName = new TextField();
  TextField lastName = new TextField();
  Template report = new Template();
  VOCollectionValueHolder people = new VOCollectionValueHolder();

  public TemplatePage() {
    try {
      jbInit();
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }

  private void jbInit() throws Exception {
    firstName.setPropertyName("firstName");
    firstName.setValueHolder(people);
    firstName.setId("firstName");
    lastName.setPropertyName("lastName");
    lastName.setValueHolder(people);
    lastName.setId("lastName");
    report.setId("report");
    report.setCollectionValueHolder(people);
    report.add(firstName);
    report.add(lastName);
    this.add(report);
  }

  protected void initForm() throws java.lang.Exception {
    super.initForm();
    // Use Xerces to Parse document to a DOM and store as this form's document
    // You can use any method you like to create the DOM
    DOMParser parser = new DOMParser();
    InputSource is = new InputSource(
        TemplatePage.class.getResourceAsStream("TemplatePage.html"));
    parser.parse(is);
    this.setDocument(parser.getDocument());
  }

  protected void openForm() throws java.lang.Exception {
    // Retrieve or create the value objects
    ArrayList array = new ArrayList();
    array.add(new Person(1629, "Picard", "Jean Luc", null));
    array.add(new Person(2044, "Riker", "William", null));
    array.add(new Person(1326, "Crusher", "Beverly", null));
    people.setCollection(array);
  }

Invoke the form: [servlet-url]/TemplatePage.sf

When the form displays, it creates a <tr> for each item in the collection.

Back to Contents

Specialized Components for the ServletForm

MapperXML contains a number of specialized components for use with ServletForms. These are peer components to specialized HTML form components. Most of these components are simple subclasses of the core components with specialized renderers. The following are examples for each of the specialized components.

Back to Contents

Using a SelectField and HTMLSelect Components

The SelectField, like its Swing counterpart, is a compound component. It has part to hold a list of possible selections and a part to hold the selected value. The HTMLSelect component is a specialized version of the SelectField which can render its value to an HTML <select> control. There are a number of ways these components can be used. In the following example, a color will be selected from a list and stored in the Person's favoriteColor property and it will be displayed on the form. Below is the HTML:

<html>
  <head>
    <title>MapperXML Example: The SelectPage</title>
  </head>
  <body>
    <h1>MapperXML Example: The SelectPage</h1>
    <form method="post" action="/servlet/com.taursys.examples.simpleweb.MainServlet/SelectPage.sf">
    <select name="color" id="color">
      <option>X</option>
    </select>
    <input type="submit"/>
    <br/>
    <p>You picked <span id="selectedColor">black</span></p>
    </form>
  </body>
</html>
        

The code is much like code in the prior examples. Here is the code for the example:

package com.taursys.examples.simpleweb;

import com.taursys.servlet.*;
import com.taursys.util.DataTypes;
import org.xml.sax.InputSource;
import org.apache.xerces.parsers.DOMParser;
import com.taursys.model.VOValueHolder;
import com.taursys.model.ObjectArrayValueHolder;
import com.taursys.xml.SelectField;
import com.taursys.html.*;

public class SelectPage extends ServletForm {
  HTMLSelect color = new HTMLSelect();
  SelectField selectedColor = new SelectField();
  VOValueHolder person = new VOValueHolder();

  public SelectPage() {
    try {
      jbInit();
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }

  private void jbInit() throws Exception {
    color.setParameter("color");
    color.setId("color");
    color.setValueHolder(person);
    color.setPropertyName("favoriteColor");
    color.setNullDisplay("--choose a color--");
    selectedColor.setId("selectedColor");
    // Link selectedColor to same model as color
    selectedColor.setModel(color.getModel());
    this.add(selectedColor);
    this.add(color);
  }

  protected void initForm() throws java.lang.Exception {
    super.initForm();
    // Use Xerces to Parse document to a DOM and store as this form's document
    // You can use any method you like to create the DOM
    DOMParser parser = new DOMParser();
    InputSource is = new InputSource(
        InputPage.class.getResourceAsStream("SelectPage.html"));
    parser.parse(is);
    this.setDocument(parser.getDocument());
    // Setup the list of Colors to choose from
    String[] colors = {
      "Red",
      "Orange",
      "Yellow",
      "Green",
      "Blue",
      "Indigo",
      "Violet",
      };
    color.setList(new ObjectArrayValueHolder(colors));
  }

  protected void openForm() throws java.lang.Exception {
    // Try to retrieve from session else create
    Person personVO = (Person)getRequest().getSession().getAttribute("ThePerson");
    if (personVO == null) {
      // Create the value object and store
      personVO = new Person(1629, "Pulaski", "Katherine", null);
      getRequest().getSession().setAttribute("ThePerson", personVO);
    }
    // Bind value object to person ValueHolder
    person.setValueObject(personVO);
  }
}
        

Invoke the form: [servlet-url]/SelectPage.sf

Choose different colors and Submit the form. This example also demonstrates the following featured:

  • how multiple components can share the same model
  • how to use a SelectField to display a lookup value
Back to Contents

Using theCheckboxField and a HTMLCheckbox Components

The CheckboxField like its Swing counterpart is a 2 state component (selected/unselected). The HTMLCheckbox is a specialized version of the CheckboxField to work with an HTML <input type="checkbox> control.

(to be continued ********************************)

Back to Contents

Actions and Events in the ServletForm

MapperXML components use an event driven model. You can add listeners to the components to provide custom response to events. The entire response cycle for a ServletForm is event driven. The cycle begins when the ServletApp invokes the ServletForm's doGet method. By default, the ServletForm's doGet method does the following:

  • Initializes the form (if not already initialized) by invoking the initForm method. Normally you will override this method.
  • Dispatches request parameter values to Parameter components by invoking the dispatchParameters method. By default, this method delegates the work to a Dispatcher subcomponent.
  • Opens the form by invoking the openForm method. Normally you would override this method.
  • Dispatches request input values to Field components by invoking the dispatchInput method. By default, this method delegates the work to a Dispatcher subcomponent.
  • Dispatches request action values to Trigger components by invoking the dispatchActions method. By default, this method delegates the work to a Dispatcher subcomponent.
  • Sends back the response by invoking the sendResponse method. By default, this method invokes the renderDispatcher to tell all components to render their values to the HTML document. It then sets the response type to text/html. Finally it invokes an XMLWriter to render the Document as XML/HTML. You can override this method to customize the repsonse.
  • Finally, it closes the form by invoking the closeForm method. You can override this method to close any resources or do cleanup.
  • If an Exception occurs during any of the above steps, the handleException method is invoked. You can override this method to provide custom Exception handling. By default, this method simply re-throws the Exception and lets the ServletApp handle it.

Using the Trigger Component

The Trigger component is similar to a Swing JButton. It has two core properties: the parameter name to listen for, and the triggering text value. You can add a TriggerListener to the Trigger component to respond to trigger events. The following example demonstrates the use of the Trigger component. Below is the HTML:

<html>
  <head>
    <title>MapperXML Example: The ActionPage</title>
  </head>
  <body>
    <h1>MapperXML Example: The ActionPage</h1>
    <form method="post" action="/servlet/com.taursys.examples.simpleweb.MainServlet/ActionPage.sf">
    <p>Last Name:
    <input type="text" name="lastName" id="lastName" value="John"/>
    </p>
    <br/>
    <input type="submit" name="action" value="High"/>
    <input type="submit" name="action" value="Low"/>
    <br/>
    <p>The following happened: <span id="happened">nothing</span></p>
    </form>
  </body>
</html>
        

The following is the code for the example:

package com.taursys.examples.simpleweb;

import com.taursys.servlet.ServletForm;
import org.xml.sax.InputSource;
import org.apache.xerces.parsers.DOMParser;
import com.taursys.html.HTMLInputText;
import com.taursys.xml.Trigger;
import com.taursys.xml.TextField;
import com.taursys.xml.event.*;
import com.taursys.model.ModelException;
import com.taursys.debug.Debug;

public class ActionPage extends ServletForm {
  HTMLInputText lastName = new HTMLInputText();
  Trigger button1 = new Trigger();
  Trigger button2 = new Trigger();
  TextField happened = new TextField();

  public ActionPage() {
    try {
      jbInit();
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }

  private void jbInit() throws Exception {
    lastName.setParameter("lastName");
    lastName.setId("lastName");
    lastName.addInputListener(new com.taursys.xml.event.InputListener() {
      public void inputReceived(InputEvent e) {
        lastName_inputReceived(e);
      }
    });
    button1.setParameter("action");
    button1.setText("High");
    button1.addTriggerListener(new com.taursys.xml.event.TriggerListener() {
      public void actionPerformed(TriggerEvent e) throws Exception {
        button1_actionPerformed(e);
      }
    });
    button2.setParameter("action");
    button2.setText("Low");
    button2.addTriggerListener(new com.taursys.xml.event.TriggerListener() {
      public void actionPerformed(TriggerEvent e) throws Exception {
        button2_actionPerformed(e);
      }
    });
    happened.setId("happened");
    this.add(lastName);
    this.add(button1);
    this.add(button2);
    this.add(happened);
  }

  protected void initForm() throws java.lang.Exception {
    super.initForm();
    // Use Xerces to Parse document to a DOM and store as this form's document
    // You can use any method you like to create the DOM
    DOMParser parser = new DOMParser();
    InputSource is = new InputSource(
        InputPage.class.getResourceAsStream("ActionPage.html"));
    parser.parse(is);
    this.setDocument(parser.getDocument());
  }

  protected void openForm() throws java.lang.Exception {
    happened.setText("absolutely nothing");
  }

  void button1_actionPerformed(TriggerEvent e) throws Exception {
    happened.setText(happened.getText() + " - High button pressed");
  }

  void button2_actionPerformed(TriggerEvent e) throws Exception {
    happened.setText(happened.getText() + " - Low button pressed");
  }

  void lastName_inputReceived(InputEvent e) {
    try {
      happened.setText("lastName submitted=" + lastName.getText());
    } catch (ModelException ex) {
      Debug.error("Error during inputReceived for lastName", ex);
    }
  }
}
        

Invoke the form: [servlet-url]/ActionPage.sf

When you simply invoke the URL the response is "absolutely nothing". Press the two buttons and observe the response. Also fill in the name field. Finally, try simply invoking the URL and add "?lastName=Test".

(to be continued)

Back to Contents
.
Create MapperXML components and bind them to the DOM