| <html><head><META http-equiv="Content-Type" content="text/html; charset=UTF-8"><link type="text/css" href="../../../default_style.css" rel="stylesheet"><link type="text/css" href="../../../webtools/wtp.css" rel="stylesheet"><title>flexible project concepts</title></head><body><table border="0" cellpadding="2" cellspacing="5" width="100%"><tbody><tr><td align="left" width="60%"><font class="indextop">jst j2ee</font><br><font class="indexsub">flexible project concepts</font></td><td width="40%"><img src="../../../webtools/images/wtplogosmall.jpg" align="middle" height="129" hspace="50" width="207" alt="WTP Logo" usemap="logomap"><map id="logomap" name="logomap"><area coords="0,0,207,129" href="/webtools/" alt="WTP Home"></map></td></tr></tbody></table><table border="0" cellpadding="2" cellspacing="5" width="100%"><col width="16"><col width="*"><tbody><tr><td align="right" valign="top"> | |
| | |
| </td><td valign="top"><a name="top"></a></td></tr><tr><td colspan="2" align="left" bgcolor="#0080c0" valign="top"><b><font color="#ffffff" face="Arial,Helvetica">Introduction</font></b></td></tr><tr><td align="right" valign="top"> | |
| | |
| </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 align="right" valign="top"> | |
| | |
| </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 align="right" valign="top"> | |
| | |
| </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 colspan="2" align="left" bgcolor="#0080c0" valign="top"><b><font color="#ffffff" face="Arial,Helvetica">Project Structural Model</font></b></td></tr><tr><td align="right" valign="top"> | |
| | |
| </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 align="right" valign="top"> | |
| | |
| </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 align="right" valign="top"> | |
| | |
| </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 align="right" valign="top"> | |
| | |
| </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 align="right" valign="top"> | |
| | |
| </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 align="right" valign="top"> | |
| | |
| </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 colspan="2" align="left" bgcolor="#0080c0" valign="top"><b><font color="#ffffff" face="Arial,Helvetica">XML Format for WorkbenchModules</font></b></td></tr><tr><td align="right" valign="top"> | |
| | |
| </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 align="right" valign="top"> | |
| | |
| </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 colspan="2" align="left" bgcolor="#0080c0" valign="top"><b><font color="#ffffff" face="Arial,Helvetica">Constraints enforced by the current solution</font></b></td></tr><tr><td align="right" valign="top"> | |
| | |
| </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 colspan="2" align="left" bgcolor="#0080c0" valign="top"><b><font color="#ffffff" face="Arial,Helvetica">Interaction Diagram for Important Components</font></b></td></tr><tr><td align="right" valign="top"> | |
| | |
| </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 align="right" valign="top"> | |
| | |
| </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 align="right" valign="top"> | |
| | |
| </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 align="right" valign="top"> | |
| | |
| </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 colspan="2" align="left" bgcolor="#0080c0" valign="top"><b><font color="#ffffff" face="Arial,Helvetica">ArtifactEdit: Working with the Module Content Metamodel</font></b></td></tr><tr><td align="right" valign="top"> | |
| | |
| </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 align="right" valign="top"> | |
| | |
| </td><td valign="top"><p> | |
| <pre> | |
| public ArtifactEditModel getModuleEditModelForRead(WorkbenchModule wbModule, Object anAccessorKey) | |
| </pre> | |
| </p></td></tr><tr><td align="right" valign="top"> | |
| | |
| </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 align="right" valign="top"> | |
| | |
| </td><td valign="top"><p> | |
| <pre> | |
| IAdapterManager manager = Platform.getAdapterManager(); | |
| manager.registerAdapters(new WebAppEditAdapterFactory(), ArtifactEditModel.class); | |
| </pre> | |
| </p></td></tr><tr><td align="right" valign="top"> | |
| | |
| </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 align="right" valign="top"> | |
| | |
| </td><td valign="top"><p>The following line would return the specific ArtifactEdit instance:</p></td></tr><tr><td align="right" valign="top"> | |
| | |
| </td><td valign="top"><p> | |
| <pre> | |
| WebAppEdit util = (WebAppEdit)moduleEditModel.getAdapter(WebAppEdit.class); | |
| </pre> | |
| </p></td></tr><tr><td align="right" valign="top"> | |
| | |
| </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 align="right" valign="top"> | |
| | |
| </td><td valign="top"><p> | |
| <pre> | |
| public WebApp getWebApp(); | |
| public int getServletVersion(); | |
| </pre> | |
| </p></td></tr><tr><td align="right" valign="top"> | |
| | |
| </td><td valign="top"><p>Additionally, API is inherited from a common superclass:</p></td></tr><tr><td align="right" valign="top"> | |
| | |
| </td><td valign="top"><p> | |
| <pre> | |
| public int getJ2EEVersion(); | |
| public createDeploymentDescriptorWithRoot(); | |
| public EObject getRootObject(); | |
| </pre> | |
| </p></td></tr><tr><td align="right" valign="top"> | |
| | |
| </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 colspan="2" align="left" bgcolor="#0080c0" valign="top"><b><font color="#ffffff" face="Arial,Helvetica">Deployable Module Builder</font></b></td></tr><tr><td align="right" valign="top"> | |
| | |
| </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 align="right" valign="top"> | |
| | |
| </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 align="right" valign="top"> | |
| | |
| </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 align="right" valign="top"> | |
| | |
| </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 align="right" valign="top"> | |
| | |
| </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 align="right" valign="top"> | |
| | |
| </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 align="right" valign="top"> | |
| | |
| </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 colspan="2" align="left" bgcolor="#0080c0" valign="top"><b><font color="#ffffff" face="Arial,Helvetica">Server Integration</font></b></td></tr><tr><td align="right" valign="top"> | |
| | |
| </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 align="right" valign="top"> | |
| | |
| </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 align="right" valign="top"> | |
| | |
| </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 align="right" valign="top"> | |
| | |
| </td><td valign="top"><p></p></td></tr><tr><td align="right" valign="top"> | |
| | |
| </td><td valign="top"><p> | |
| <i>Last updated Feb 16 2004</i> | |
| </p></td></tr></tbody></table></body></html> |