blob: b013b2f44f1917e01c21f33a984e57734a97a076 [file] [log] [blame]
<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">&nbsp;</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">&nbsp;</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">&nbsp;</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">&nbsp;</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">&nbsp;</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">&nbsp;</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">&nbsp;</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 &ldquo;MyWebApplication.war&rdquo;. The
WorkbenchModule may be uniquely referenced by a URI (stored on the
WorkbenchModule as the &ldquo;handle&rdquo;). The fully qualified URI to any module
must begin with the module protocol (&ldquo;module:&rdquo;), specify a subprotocol
(&ldquo;resource|classpath&rdquo;) and then a path to the referenced module. A
WorkbenchModule with the deplyedName &ldquo;MyWebApplication.war&rdquo; defined in a
project named &ldquo;MyWebModulesProject&rdquo; would be referenced by the following
URI: &ldquo;module:/resource/MyWebModulesProject/MyWebApplication.war&rdquo;.
</p>
</td>
</tr>
<tr>
<td valign="top" align="right">&nbsp;</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.
&ldquo;Metadata&rdquo; refers to resources which explain the details of the specific
modules. An example of such a file would be the &ldquo;WEB-INF/web.xml&rdquo;
deployment descriptor for Web Applications.
</p>
</td>
</tr>
<tr>
<td valign="top" align="right">&nbsp;</td><td valign="top">
<p>
Each WorkbenchModule defines a list of WorkbenchModuleResources. Each
WorkbenchModuleResource provides &ldquo;sourcePath&rdquo; and the corresponding
&ldquo;deployedPath&rdquo;. The &ldquo;sourcePath&rdquo; can reference either a file or folder,
but must reference a resource in the same project. The &ldquo;deployedPath&rdquo;
will specify a location relative to the deployed structure of the
WorbenchModule.
</p>
</td>
</tr>
<tr>
<td valign="top" align="right">&nbsp;</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 &ldquo;consume&rdquo; or &ldquo;use&rdquo; 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">&nbsp;</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: &ldquo;MyWebModule.war&rdquo;) defines two
resources &ndash; each containers &ndash; 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
(&ldquo;module:/resource/AnotherProject/MyWebModuleLib2.jar&rdquo;) 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
(&ldquo;module:/classpath/AnotherTeamsUtilities.jar&rdquo;). The second module
defined by the XML sample (&ldquo;MyWebModuleLib.jar&rdquo;) defines a
WorkbenchModule of the type &ldquo;jst.utility&rdquo;, 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">&nbsp;</td><td valign="top">
<table cellspacing="10" cellpadding="10">
<tr>
<td>
<pre>
&lt;project-modules id="moduleCoreId"&gt;
&lt;wb-module
deploy-name="MyWebModule.war"&gt;
&lt;wb-module
module-type-id="jst.web" /&gt;
&lt;wb-resource
deploy-path="WEB-INF/"
source- path="/MyModulesProject/MyWebModule/WebContent/WEB-INF" /&gt;
&lt;wb-resource
deploy-path="jsps/"
source- path="/MyModulesProject/MyWebModule/WebContent/myjsps" /&gt;
&lt;dependent-module
deploy-path="WEB-INF/lib"
handle="MyWebModuleLib.jar" /&gt;
&lt;dependent-module
deploy-path="WEB-INF/lib"
handle="module:/resource/AnotherProject/MyWebModuleLib2.jar" /&gt;
&lt;dependent-module
deploy-path="WEB-INF/lib"
handle="module:/classpath/AnotherTeamsUtilities.jar" /&gt;
&lt;/wb-module&gt;
&lt;wb-module
deploy-name="MyWebModuleLib.jar"&gt;
&lt;wb-module
module-type-id="jst.utility" /&gt;
&lt;wb-resource
deploy-path="/"
source-path="/MyModulesProject/lib-src"/&gt;
&lt;/wb-module&gt;
&lt;/project-modules&gt;
</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">&nbsp;</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">&nbsp;</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">&nbsp;</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">&nbsp;</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">&nbsp;</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&rsquo;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">&nbsp;</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">&nbsp;</td><td valign="top">
<p>
<pre>
public ArtifactEditModel getModuleEditModelForRead(WorkbenchModule wbModule, Object anAccessorKey)
</pre>
</p>
</td>
</tr>
<tr>
<td valign="top" align="right">&nbsp;</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 &ldquo;jst.web&rdquo; would register the WebAppEditAdapterFactory.
</p>
</td>
</tr>
<tr>
<td valign="top" align="right">&nbsp;</td><td valign="top">
<p>
<pre>
IAdapterManager manager = Platform.getAdapterManager();
manager.registerAdapters(new WebAppEditAdapterFactory(), ArtifactEditModel.class);
</pre>
</p>
</td>
</tr>
<tr>
<td valign="top" align="right">&nbsp;</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">&nbsp;</td><td valign="top">
<p>The following line would return the specific ArtifactEdit instance:</p>
</td>
</tr>
<tr>
<td valign="top" align="right">&nbsp;</td><td valign="top">
<p>
<pre>
WebAppEdit util = (WebAppEdit)moduleEditModel.getAdapter(WebAppEdit.class);
</pre>
</p>
</td>
</tr>
<tr>
<td valign="top" align="right">&nbsp;</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">&nbsp;</td><td valign="top">
<p>
<pre>
public WebApp getWebApp();
public int getServletVersion();
</pre>
</p>
</td>
</tr>
<tr>
<td valign="top" align="right">&nbsp;</td><td valign="top">
<p>Additionally, API is inherited from a common superclass:</p>
</td>
</tr>
<tr>
<td valign="top" align="right">&nbsp;</td><td valign="top">
<p>
<pre>
public int getJ2EEVersion();
public createDeploymentDescriptorWithRoot();
public EObject getRootObject();
</pre>
</p>
</td>
</tr>
<tr>
<td valign="top" align="right">&nbsp;</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">&nbsp;</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">&nbsp;</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 &ldquo;RootProject/.deployables/module_name&rdquo;. 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">&nbsp;</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">&nbsp;</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">&nbsp;</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">&nbsp;</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">&nbsp;</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">&nbsp;</td><td valign="top">
<p>
The contents of the &ldquo;.deployables&rdquo; 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
&ldquo;.deployables&rdquo; 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">&nbsp;</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">&nbsp;</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">&nbsp;</td><td valign="top">
<p></p>
</td>
</tr>
<tr>
<td valign="top" align="right">&nbsp;</td><td valign="top">
<p>
<i>Last updated Feb 16 2004</i>
</p>
</td>
</tr>
</tbody>
</table>
</body>
</html>