| <html> |
| <head> |
| <META |
| http-equiv="Content-Type" |
| content="text/html; charset=UTF-8"> |
| <meta |
| http-equiv="Content-Type" |
| content="text/html; charset=iso-8859-1"> |
| <link |
| rel="stylesheet" |
| href="../../../default_style.css" |
| type="text/css"> |
| <link |
| rel="stylesheet" |
| href="../../../webtools/wtp.css" |
| type="text/css"> |
| <title>flexible project concepts</title> |
| </head> |
| <body> |
| <table |
| width="100%" |
| cellspacing="5" |
| cellpadding="2" |
| border="0"> |
| <tbody> |
| <tr> |
| <td |
| width="60%" |
| align="left"><font class="indextop">jst j2ee</font> <br> |
| <font class="indexsub">flexible project concepts</font></td> |
| <td width="40%"><img |
| width="207" |
| hspace="50" |
| height="129" |
| align="middle" |
| src="../../../webtools/images/wtplogosmall.jpg"></td> |
| </tr> |
| </tbody> |
| </table> |
| <table |
| width="100%" |
| cellspacing="5" |
| cellpadding="2" |
| border="0"> |
| <col width="16"> |
| <col width="*"> |
| <tbody> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"><a name="top"></a></td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| bgcolor="#0080c0" |
| align="left" |
| colspan="2"><b><font |
| face="Arial,Helvetica" |
| color="#ffffff">Introduction</font></b></td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"> |
| <p>The following document provides an overview of the direction that the J2EE Tools team is going with |
| the design and implementation of the Flexible Project Structure support and API. The document will discuss |
| the following:</p> |
| </td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"> |
| <ul> |
| <li> |
| <p>the metamodel used to understand project structures,</p> |
| </li> |
| <li> |
| <p>the XML format used to store the model within each project,</p> |
| </li> |
| <li> |
| <p>a high level overview of the important components in the API,</p> |
| </li> |
| <li> |
| <p>how the modules are prepared for deployment, and</p> |
| </li> |
| <li> |
| <p>how modules are announced to the server.</p> |
| </li> |
| </ul> |
| </td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"> |
| <p>The design of the flexible project structure as enumerated by this document does not meet some of the |
| initial suggestions due to constraints within the base Eclipse platform. For instance, only one server |
| target is supported at a time (but users may switch the server target easily and recompile). Also, the |
| resources which compose a module must be wholly contained under a single project, but of course modules may |
| reference modules in other projects.</p> |
| </td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| bgcolor="#0080c0" |
| align="left" |
| colspan="2"><b><font |
| face="Arial,Helvetica" |
| color="#ffffff">Project Structural Model</font></b></td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"> |
| <p>The EMF structural model allows the tooling to understand various layouts for projects. Each logical |
| module contained in the project is represented by a WorkbenchModule element. The WorkbenchModule defines |
| information about the type of module, the resources consumed by the module from the project, and the |
| dependent modules. The WorkbenchModule is abstract, and as modeled, does not necessarily correspond to only |
| J2EE artifacts.</p> |
| </td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"> |
| <table |
| cellspacing="10" |
| cellpadding="10"> |
| <tr> |
| <td> |
| <p><img src="../images/module_structural_metamodel_rose.png"></p> |
| </td> |
| </tr> |
| <tr> |
| <td> |
| <p><i>Figure 1: The Module Structural Metamodel.</i></p> |
| </td> |
| </tr> |
| </table> |
| </td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"> |
| <p>The WorkbenchModule defines its deployedName, which is the name that will be used when the deployable |
| form of the module is constructed. For a web application, the deployedName might be |
| “MyWebApplication.war”. The WorkbenchModule may be uniquely referenced by a URI (stored on the |
| WorkbenchModule as the “handle”). The fully qualified URI to any module must begin with the |
| module protocol (“module:”), specify a subprotocol (“resource|classpath”) and then a |
| path to the referenced module. A WorkbenchModule with the deplyedName “MyWebApplication.war” |
| defined in a project named “MyWebModulesProject” would be referenced by the following URI: |
| “module:/resource/MyWebModulesProject/MyWebApplication.war”.</p> |
| </td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"> |
| <p>Each WorkbenchModule defines a ModuleType. The ModuleType defines a moduleTypeId, which indicates the |
| specific kind of module. The Web Tools Platform uses the moduleTypeId to determine how to handle the |
| WorkbenchModule. The ModuleType may also define the runtime-paths of special metadata resources which are |
| important to the WorkbenchModule. “Metadata” refers to resources which explain the details of |
| the specific modules. An example of such a file would be the “WEB-INF/web.xml” deployment |
| descriptor for Web Applications.</p> |
| </td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"> |
| <p>Each WorkbenchModule defines a list of WorkbenchModuleResources. Each WorkbenchModuleResource |
| provides “sourcePath” and the corresponding “deployedPath”. The |
| “sourcePath” can reference either a file or folder, but must reference a resource in the same |
| project. The “deployedPath” will specify a location relative to the deployed structure of the |
| WorbenchModule.</p> |
| </td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"> |
| <p>Each WorkbenchModule defines a list of DependentModules. Each DependentModule provides a handle which |
| must resolve to another WorkbenchModule, a deployedPath that defines where the constructed module will be |
| placed within the context of the deployed WorkbenchModule, and a dependencyType that can be either |
| “consume” or “use” to indicate how the contents of that DependentModule should be |
| absorbed by the WorkbenchModule.</p> |
| </td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| bgcolor="#0080c0" |
| align="left" |
| colspan="2"><b><font |
| face="Arial,Helvetica" |
| color="#ffffff">XML Format for WorkbenchModules</font></b></td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"> |
| <p>The EMF model is stored as an XML model on disk. A full schema of this format will follow. The |
| example below defines two modules in a single project. The first module (named: |
| “MyWebModule.war”) defines two resources – each containers – that should be included |
| in the deployed module. Three dependent modules are referenced, demonstrating the various ways that module |
| URIs may be used. The first reference points to a local module, defined in the same project. The second |
| reference (“module:/resource/AnotherProject/MyWebModuleLib2.jar”) uses a fully qualified URI |
| that points to a module in another project. The last reference points to a module which is already in a |
| deployable form and available on the classpath (“module:/classpath/AnotherTeamsUtilities.jar”). |
| The second module defined by the XML sample (“MyWebModuleLib.jar”) defines a WorkbenchModule of |
| the type “jst.utility”, which would be a simple Java library that could be used as a Utility Jar |
| in a *.ear module or a Web Library in a *.war module.</p> |
| </td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"> |
| <table |
| cellspacing="10" |
| cellpadding="10"> |
| <tr> |
| <td><pre> |
| |
| <project-modules id="moduleCoreId"> |
| <wb-module |
| deploy-name="MyWebModule.war"> |
| <wb-module |
| module-type-id="jst.web" /> |
| <wb-resource |
| deploy-path="WEB-INF/" |
| source- path="/MyModulesProject/MyWebModule/WebContent/WEB-INF" /> |
| <wb-resource |
| deploy-path="jsps/" |
| source- path="/MyModulesProject/MyWebModule/WebContent/myjsps" /> |
| <dependent-module |
| deploy-path="WEB-INF/lib" |
| handle="MyWebModuleLib.jar" /> |
| <dependent-module |
| deploy-path="WEB-INF/lib" |
| handle="module:/resource/AnotherProject/MyWebModuleLib2.jar" /> |
| <dependent-module |
| deploy-path="WEB-INF/lib" |
| handle="module:/classpath/AnotherTeamsUtilities.jar" /> |
| </wb-module> |
| <wb-module |
| deploy-name="MyWebModuleLib.jar"> |
| <wb-module |
| module-type-id="jst.utility" /> |
| <wb-resource |
| deploy-path="/" |
| source-path="/MyModulesProject/lib-src"/> |
| </wb-module> |
| </project-modules> |
| </pre></td> |
| </tr> |
| <tr> |
| <td> |
| <p><i>Figure 2: Sample metamodel XML format</i></p> |
| </td> |
| </tr> |
| </table> |
| </td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| bgcolor="#0080c0" |
| align="left" |
| colspan="2"><b><font |
| face="Arial,Helvetica" |
| color="#ffffff">Constraints enforced by the current solution</font></b></td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"> |
| <ol> |
| <li> |
| <p>The solution will not check dependencies for modules that are contained in the same project. To |
| get the full benefits of inter-module dependency checking, modules must be separated into different |
| projects. We do not have the necessary flexibility in constructing and scoping classpaths on a level |
| more granular than the project level, which would be needed to support this functionality.</p> |
| </li> |
| <li> |
| <p>The solution will not allow a single module to span more than one project. Within that project, |
| we will have fairly broad flexibility to specify which resources map to which modules. Each module |
| within a project must have its own source folder, but a module may contain more than one source folder. |
| It would be discouraged or completely disallowed for a single source folder to be contained by more than |
| one module. Modules may reference dependent modules in other projects (so a Web Application may |
| reference a Web Library outside of the project that contains the Web Application).</p> |
| </li> |
| <li> |
| <p>The solution will not allow more than one server target per module (and really per-project) at a |
| time. The ability to switch this server target (via some action or property setting) will continue to be |
| possible. Users that need the capability to develop for multiple server targets will need to manually |
| switch and test as necessary.</p> |
| </li> |
| <li> |
| <p>Each module in a project will have its own output folder structure automatically constructed for |
| it. The output structure will match the J2EE-spec output structure required for the module type (for |
| J2EE modules). A new builder will handle this responsibility and work cooperatively with the Java |
| builder to construct a deployable, on-disk representation of the module structure. The necessity for |
| this on-disk structure to match a J2EE-compliant layout is motivated by the requirement to have |
| in-workbench testing, so that users will not have to deal with a deployer actually constructing a |
| deployable module and shipping it off to a server to test their code. This approach is consistent with |
| existing Ant-based approaches and Application Servers which can run in a "debug" mode on disk. Our |
| value-add will be greater automation and integration with the workbench -- particularly for incremental |
| based support. The specialized module builder would not be necessary if the source was already in the |
| appropriate J2EE-spec compliant structure. The default creation will still encourage a single module per |
| project, which conforms to the correct J2EE structure.</p> |
| </li> |
| <li> |
| <p>Modules will be described using a simple XML format, and each project will contain one |
| .wtpmodules file that will describe all of the modules for that project. The level of tooling to help |
| users create these files is yet to be determined for WTP M4. This would be a great area for other |
| interested developers to suggest and provide tooling (e.g. a Wizard or Editor) to create these files |
| from existing structures.</p> |
| </li> |
| </ol> |
| </td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| bgcolor="#0080c0" |
| align="left" |
| colspan="2"><b><font |
| face="Arial,Helvetica" |
| color="#ffffff">Interaction Diagram for Important Components</font></b></td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"> |
| <p>The follow diagram highlights the important relationships between the components in the Flexible |
| Project API. Each project that supports a flexible project structure has a ModuleCoreNature associated with |
| it. The ModuleCoreNature is used to manage the WTP Modules Structural Model and used to access the Artifact |
| Edit Models. A project has exactly one Structural Model that defines all of the modules contained by the |
| project. A project may have multiple Artifact Edit Models. Each Artifact Edit Model represents the pieces of |
| a module that an operation or editor would want to modify, and are loaded and saved as a single unit.</p> |
| </td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"> |
| <table |
| cellspacing="10" |
| cellpadding="10"> |
| <tr> |
| <td><img src="../images/modulecore_interaction_diagram_rose.jpg"></td> |
| </tr> |
| <tr> |
| <td> |
| <p><i>Figure 3: Interaction diagram of the ModuleCore components</i></p> |
| </td> |
| </tr> |
| </table> |
| </td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"> |
| <p>The complexity of accessing the models is hidden from clients by the use of an Adapter pattern. When |
| a client needs to read or modify a deployment descriptor model, the client may adapt the ArtifactEditModel |
| to return an instance of the ArtifactEdit adapter or even request a specific subclass of ArtifactEdit with |
| API which is targeted to the specific type of Deployment Descriptor. Clients that need to edit or understand |
| the structural model of the modules in the project may use a similar pattern by adapting the |
| ModuleStructuralModel to a ModuleCore adapter, which will then have the necessary API to focus on the module |
| structural model.</p> |
| </td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"> |
| <p>The ArtifactEditModel and ModuleStructuralModel are each a subclass of the EditModel object. Edit |
| models have a life cycle that requires them to be notified when clients are using them and notified when |
| clients have completed their tasks. The ModuleCore and ArtifactEdit adapters will wrap the specific |
| instances of the edit models they originally adapted. At the end of the client’s usage, the edit model |
| must still be released. Releasing the edit model allows the framework to maintain an accurate reference |
| count so that when the edit model is no longer in use by any client, the resources that it references may be |
| unloaded.</p> |
| </td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| bgcolor="#0080c0" |
| align="left" |
| colspan="2"><b><font |
| face="Arial,Helvetica" |
| color="#ffffff">ArtifactEdit: Working with the Module Content Metamodel</font></b></td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"> |
| <p>The ArtifactEdit adapter pattern is used to facilitate access to the modules resources, and provide |
| API for specific module types. Clients must adapt the ArtifactEditModel to an ArtifactEdit adapter, which |
| will operate in the context of the ArtifactEditModel that created it. An ArtifactEditModel may be acquired |
| from the ModuleCoreNature using the specific WorkbenchModule the client is interested in.</p> |
| </td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"><pre> |
| public ArtifactEditModel getModuleEditModelForRead(WorkbenchModule wbModule, Object anAccessorKey) |
| </pre></td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"> |
| <p>Each module type will register an ArtifactEditAdapterFactory that creates a corresponding |
| ArtifactEdit instance or subclass. For instance, a module of type “jst.web” would register the |
| WebAppEditAdapterFactory.</p> |
| </td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"><pre> |
| IAdapterManager manager = Platform.getAdapterManager(); |
| manager.registerAdapters(new WebAppEditAdapterFactory(), ArtifactEditModel.class); |
| </pre></td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"> |
| <p>Web Tools Platform contributors may use SPI as above to expand the types of ArtifactEdit adapters |
| available to clients.</p> |
| </td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"> |
| <p>The following line would return the specific ArtifactEdit instance:</p> |
| </td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"><pre> |
| WebAppEdit util = (WebAppEdit)moduleEditModel.getAdapter(WebAppEdit.class); |
| </pre></td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"> |
| <p>The WebAppEdit class would have some of the specific module API previously found on the WebNature and |
| WebEditModel. Type specific API would be found here:</p> |
| </td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"><pre> |
| public WebApp getWebApp(); |
| public int getServletVersion(); |
| </pre></td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"> |
| <p>Additionally, API is inherited from a common superclass:</p> |
| </td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"><pre> |
| public int getJ2EEVersion(); |
| public createDeploymentDescriptorWithRoot(); |
| public EObject getRootObject(); |
| </pre></td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"> |
| <p>The API that will be provided to consumers is still under development, and suggestions for the kinds |
| of API that are required are always welcome.</p> |
| </td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| bgcolor="#0080c0" |
| align="left" |
| colspan="2"><b><font |
| face="Arial,Helvetica" |
| color="#ffffff">Deployable Module Builder</font></b></td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"> |
| <p>The Deployable Module Builder extends the Eclipse Incremental Builder framework in order to create |
| and maintain a deployable module output structure for flexible module projects, which are now supported by |
| the Web Tools Platform. The builder is added to any project which contains the Module Core Nature indicating |
| that a given project is flexible. The can construct appropriate deploy structures for multiple modules of |
| possibly varying types within the same project. The deploy structure for each J2EE module will be the |
| corresponding J2EE-compliant runtime structure, but the builder may be extended to handle other types of |
| modules that are not J2EE-specific. The deploy structures created by the builder may then be used to run on |
| a server.</p> |
| </td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"> |
| <p>The Deployable Module Builder is scoped to the project level, as all Eclipse builders are, however |
| this specific builder is more concerned about the individual modules within a given project. The design of |
| the builder focuses on these individual modules, rather than a project-level artifact. The builder uses the |
| WorkbenchModule definitions from the Modules Structural Model to understand what structures need to be |
| created. Each operation arranges the deployable structure according to J2EE specifications by processing |
| each of the WorkbenchModuleResources contained in its WorkbenchModule. The deployable structure is created |
| in the project using the format “RootProject/.deployables/module_name”. The builder also manages |
| all module dependencies making sure dependent modules are handled appropriately. Once all WorkbenchModules |
| for the given project have been constructed, the Java builder will then compile all source code and the |
| *.class files will be pushed into the predefined output locations within their corresponding WorkbenchModule |
| deployed structure. The API defined by the Server Tools component will then be used to correctly adapt a |
| WorkbenchModule to an IModule in order to run the modules on the server.</p> |
| </td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"> |
| <p>Each module type (EJB, Web App, App Client, Connector) must register its own type of deployable |
| module builder. The registration mechanism is not yet complete, but will allow for total extensibility |
| within the framework in how deployable modules are constructed. (Note: Currently in the M3 initial |
| implementation, the only module which contributes a deployable module builder is Web Application, which |
| means only a Web Application project can support flexible project structures.)</p> |
| </td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"> |
| <p>The following screen shots show a flexible Web Module project before and after the Deployable Module |
| Builder has run.</p> |
| </td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"> |
| <table |
| cellspacing="10" |
| cellpadding="10"> |
| <tr> |
| <td><img src="../images/flexibleproject_screenshot1.png"></td> |
| </tr> |
| <tr> |
| <td> |
| <p><i>Figure 4: A flexible project before a build.</i></p> |
| </td> |
| </tr> |
| </table> |
| </td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"> |
| <table |
| cellspacing="10" |
| cellpadding="10"> |
| <tr> |
| <td><img src="../images/flexibleproject_screenshot2.png"></td> |
| </tr> |
| <tr> |
| <td> |
| <p><i> Figure 5: A flexible project after a build with 3 web modules defined within the |
| project. </i></p> |
| </td> |
| </tr> |
| </table> |
| </td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"> |
| <table |
| cellspacing="10" |
| cellpadding="10"> |
| <tr> |
| <td><img src="../images/flexibleproject_screenshot3.png"></td> |
| </tr> |
| <tr> |
| <td> |
| <p><i> Figure 6: The individual output module J2EE compliant contents. </i></p> |
| </td> |
| </tr> |
| </table> |
| </td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| bgcolor="#0080c0" |
| align="left" |
| colspan="2"><b><font |
| face="Arial,Helvetica" |
| color="#ffffff">Server Integration</font></b></td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"> |
| <p>The contents of the “.deployables” folder are represented as IModules to the Server |
| Tooling, which is a model format that the server can deploy. The Server API contains a ServerUtil object |
| that listens for project changes. A project change occurs after the deploy builder creates a |
| “.deployables” folder. After the project change, ServerUtil will query for a DeployableFactory |
| via an extension point. Currently, Server Tools assigns a single DeployableFactory per project, which must |
| be expanded to allow multiple modules and modules types per project. The DeployableFactory will create |
| multiple J2EE ModuleDelegates depending on the WorkbenchModules defined for the project (see ModuleCore |
| API). Each J2EE ModuleDelegate will set its context and metadata location based on the location of the |
| deployable structure created for the WorkbenchModule. Next, the DeployableFactory creates an IModule (as |
| defined by the Server Tools API) caches the IModule by the project. As already stated, single module per |
| project approach must change to support multiple modules per project.</p> |
| </td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"> |
| <p>Once the Run on server action is invoked by the user, the WorkbenchModule will be adapted to an |
| IModule, which the Server Tools understand and can deploy.</p> |
| </td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"> |
| <table |
| cellspacing="10" |
| cellpadding="10"> |
| <tr> |
| <td><img src="../images/deployable_module_builder_overview.jpg"></td> |
| </tr> |
| <tr> |
| <td> |
| <p><i> Figure 6: Interaction diagram of the Server Integration components </i></p> |
| </td> |
| </tr> |
| </table> |
| </td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"> |
| <p></p> |
| </td> |
| </tr> |
| <tr> |
| <td |
| valign="top" |
| align="right"> </td> |
| <td valign="top"> |
| <p><i>Last updated Feb 16 2004</i></p> |
| </td> |
| </tr> |
| </tbody> |
| </table> |
| </body> |
| </html> |