blob: 8047864c0f8e3111e0c55e5aa3c384d2f7c0aab6 [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"><pre>
public ArtifactEditModel getModuleEditModelForRead(WorkbenchModule wbModule, Object anAccessorKey)
</pre></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"><pre>
IAdapterManager manager = Platform.getAdapterManager();
manager.registerAdapters(new WebAppEditAdapterFactory(), ArtifactEditModel.class);
</pre></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"><pre>
WebAppEdit util = (WebAppEdit)moduleEditModel.getAdapter(WebAppEdit.class);
</pre></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"><pre>
public WebApp getWebApp();
public int getServletVersion();
</pre></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"><pre>
public int getJ2EEVersion();
public createDeploymentDescriptorWithRoot();
public EObject getRootObject();
</pre></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>