| <?xml version="1.0" encoding="UTF-8"?> |
| <html> |
| <head> |
| <meta |
| name="root" |
| content="../../../../../" /> |
| <title>modulecore api overview</title> |
| </head> |
| |
| <body> |
| <abstract> |
| The ComponentCore API allows clients to work with the Structural |
| Metamodels that define abstract modules within Eclipse projects. |
| These metamodels are exposed through the Virtual Path API layer |
| (see <a href="ComponentCore.html">ComponentCore</a>). Clients |
| should also review the <b>org.eclipse.wst.common.componentcore.resources</b> |
| package. |
| </abstract> |
| |
| <a name="top"/> |
| <p> |
| The following document includes information on these topics: |
| <ul> |
| <li><a href="#structural-metamodel">ComponentCore Metamodel (CCM)</a> |
| used to understand which files should or should not be |
| included within a module.</li> |
| <li><a href="#constraints">Constraints</a> enforced by the |
| design</li> |
| <li><a href="#module-core-examples">The API entry-point</a></li> |
| </ul> |
| </p> |
| <a name="structural-metamodel"/> |
| <h2>ComponentCore Metamodel (CCM)</h2> |
| <BR /> |
| <p> |
| The ComponentCore Metamodel (CCM) is an EMF model that allows |
| the tooling to understand most project structures. Each project |
| has a single CCM which is stored under the project root named |
| <I>.wtpmodules</I> |
| . The XML format is defined by the |
| <a href="../../../../../overview/componentCore.xsd">ComponentCore schema</a>. |
| The following diagram is a UML representation of the |
| ComponentCore Metamodel. This information is published for |
| potential contributors of editors, but the EMF model is |
| not exposed directly as API, and could change in view of |
| changes for WTP 1.1. |
| </p> |
| <img src="../../../../../overview/componentcore_model.jpg" caption="The Component Core Metamodel" /> |
| <p> |
| Each logical component contained in the project is represented by a |
| <b>WorkbenchComponent</b> element. The <b>WorkbenchComponent</b> defines |
| information about the type of component, the resources consumed by the |
| module from the project, and the referenced components. The |
| <b>WorkbenchComponent</b> is very generic, and as modeled, does |
| not necessarily correspond to only J2EE artifacts. |
| </p> |
| <p> |
| The <b>WorkbenchComponent</b> has a |
| <i>name</i> |
| , which is the name that will be used when the runtime form of the |
| component is constructed. For a web application, the |
| <i>name</i> |
| might be "MyWebApplication". |
| </p> |
| <p> |
| The <b>WorkbenchComponent</b> may be uniquely referenced by a URI. The |
| fully qualified URI to any component must begin with the component |
| protocol ("component:"), specify a subprotocol ("resource|classpath") and |
| then a path to the referenced component. A <b>WorkbenchComponent</b> with the |
| name "MyWebApplication" defined in a project named |
| "MyWebModulesProject" would be referenced by the following URI: |
| "component:/resource/MyWebModulesProject/MyWebApplication". As a future |
| extension, a component referenced on the classpath of a project (perhaps |
| a Utility Jar or an EJB Client Jar), the URI might be something like: |
| "component:/classpath/MyWebModulesProject/CustomerEJBClient.jar". |
| </p> |
| <p> |
| The <b>WorkbenchComponent</b> has a <b>ComponentType</b>. The |
| <b>ComponentType</b> defines a <i>componentTypeId</i> |
| , which indicates the specific kind of component. The Web Tools Platform |
| uses the <i>componentTypeId</i> |
| to determine how to work with the content component of the <b>WorkbenchComponent</b> |
| and prepare the component for deployment. The <b>ComponentType</b> may |
| also define the runtime-paths of special metadata resources which are |
| important to the <b>WorkbenchComponent</b>. "Metadata" refers to resources |
| which explain the content details of the specific modules. An example of |
| such a file would be the "WEB-INF/web.xml" deployment descriptor for |
| Web Applications. |
| </p> |
| <p> |
| The <b>WorkbenchComponent</b> contains a list of ComponentResources. Each |
| <b>ComponentResource</b> has "sourcePath" and a corresponding |
| "runtimePath". The "sourcePath" can reference either a file or folder, |
| but the referenced resource must be contained in the same project as the |
| <b>WorkbenchComponent</b> definition. The "runtimePath" specifies a location |
| relative to the deployed structure of the <b>WorkbenchComponent</b> where the |
| contents of the referenced resource will be represented when the module is |
| prepared for runtime. |
| </p> |
| <p> |
| The <b>WorkbenchComponent</b> contains a list of <b>ReferencedComponent</b>s. |
| Each <b>ReferencedComponent</b> provides a handle that must resolve to a |
| <b>WorkbenchComponent</b>, a runtimePath that defines where the constructed |
| component will be placed within the context of the runtime |
| <b>WorkbenchComponent</b>, and a <b>DependencyType</b> |
| that can be either "consume" or "use" to indicate how the contents of |
| that <b>ReferencedComponent</b> should be absorbed by the <b>WorkbenchComponent</b>. |
| <b>ReferencedComponent</b>s may reference <b>WorkbenchComponent</b>s in |
| other projects and on current project's classpath (Not yet implemented). |
| The <b>DependencyType</b> will determine whether the contents of |
| the <b>ReferencedComponent</b> are absorbed as-is or archived into a *.{w|j|e}ar |
| file. |
| </p> |
| <p> |
| The <b>ProjectComponents</b> object provides a root container for all |
| <b>WorkbenchComponent</b>s defined in a given project. |
| </p> |
| <p> |
| <b>ComponentCore</b> provides a facade to manage the underlying model for |
| clients. Static methods |
| <code>ModuleCore.getModuleCoreForRead()</code> |
| and |
| <code>ModuleCore.getModuleCoreForWrite()</code> |
| may be used to acquire an ModuleCore adapter, and clients are responsible |
| for invoking |
| <code>dispose()</code> |
| whenever they are finished using the model. |
| </p> |
| <a href="#top">top</a> |
| <a name="constraints"/> |
| <h2>Constraints enforced by the CCM</h2> |
| <p> |
| The following constraints are enforced by the model: |
| <ol> |
| <li> |
| <p> |
| The solution will not check dependencies for components that are |
| contained in the same project. To get the full benefits of |
| inter-component dependency checking, components 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 component to span more than |
| one project. Within that project, we will have fairly broad |
| flexibility to specify which resources map to which components. |
| Each component within a project must have its own source folder, |
| but a component may contain more than one source folder. Each |
| source folder may be contained by at most one component. Components |
| may reference dependent components 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 |
| component (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 component in a project may have its own output folder |
| structure automatically constructed for it. The output |
| structure will match the J2EE specification output structure |
| required for the component 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 reference implementation will follow this pattern, but |
| hooks will be made available to vary this behavior. |
| 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 specification |
| compliant structure. The default creation will still |
| encourage a single module per project, which conforms to the |
| correct J2EE structure. |
| </p> |
| </li> |
| <li> |
| <p> |
| Components will be described using a simple XML format, and each |
| project will contain one |
| <I>.wtpmodules</I> |
| file that will describe all of the components 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. A schema is provided to make it easier for |
| consumers that want to build their own |
| <I>.wtpmodules</I> |
| by hand to take advantage of the content assist in the XML |
| editor. |
| </p> |
| </li> |
| </ol> |
| </p> |
| <a href="#top">top</a> |
| <a name="module-core-examples"/> |
| <h2>ComponentCore API: Working with the metamodel</h2> |
| <BR /> |
| <p> |
| ComponentCore uses a handle based model much like the existing Platform |
| Resource model. The ComponentCore facade is not tied to any project, and |
| the handles that it returns may or may not exist. The complexity of |
| managing the underlying EMF model is handled under the cover for users. |
| </p> |
| <img src="../../../../../overview/componentcore_package.jpg" caption="The ComponentCore API" /> |
| <!-- |
| <p> |
| Clients should use one of |
| <code>ModuleCore.getModuleCoreForRead()</code> |
| or |
| <code>ModuleCore.getModuleCoreForWrite()</code> |
| to acquire an instance of ModuleCore. |
| <codesnippet caption="Acquiring an instance of ComponentCore for read-only access"> |
| IProject currentProject = ... |
| ModuleCore moduleCoreInstance = ModuleCore.getModuleCoreForRead(currentProject); |
| WorkbenchComponent[] modules = moduleCoreInstance.getWorkbenchComponents(); |
| ... work with modules ... |
| moduleCoreInstance.dispose(); |
| </codesnippet> |
| </p> |
| <p> |
| For clients that would like to build up their own models for a given |
| project, or modify the existing metamodel, the ModuleCore instance should |
| be acquired for write-access. |
| </p> |
| <codesnippet caption="Creating a WorkbenchComponent"> |
| ... |
| import org.eclipse.emf.common.util.URI; |
| ... |
| |
| public static void createWebAppModule(IProject aTargetProject, |
| IFolder aJavaSourceFolder, |
| IFolder aWebContentFolder, |
| IResource aWebAppDeploymentDescriptor, |
| IProgressMonitor aProgressMonitor) |
| { |
| ModuleCore moduleCoreInstance = null; |
| try { |
| moduleCoreInstance = |
| ModuleCore.getModuleCoreForWrite(aTargetProject); |
| |
| /* Create a new module that will be |
| contained by the current ModuleCore */ |
| WorkbenchComponent newModule = |
| moduleCoreInstance.createWorkbenchComponent("MyWebModule.war"); |
| |
| /* A Java source folder that contains |
| the classes for the current module */ |
| ComponentResource javaSource = |
| moduleCoreInstance.createComponentResource( |
| aJavaSourceFolder); |
| javaSource.setDeployedPath( |
| URI.createURI("/WEB-INF/classes")); |
| newModule.getResources().add(javaSource); |
| |
| /* A resource folder that contains |
| the *.jsp, *.html, .img, ... files */ |
| ComponentResource webContent = |
| moduleCoreInstance.createComponentResource( |
| aWebContentFolder); |
| webContent.setDeployedPath(URI.createURI("/")); |
| newModule.getResources().add(webContent); |
| |
| /* A resource that points to a valid web.xml |
| file that follows the J2EE Web Deployment |
| Descriptor Specification |
| */ |
| ComponentResource deploymentDescriptor = |
| moduleCoreInstance.createComponentResource( |
| aWebAppDeploymentDescriptor); |
| deploymentDescriptor.setDeployedPath( |
| URI.createURI("/WEB-INF/web.xml")); |
| newModule.getResources().add(deploymentDescriptor); |
| |
| moduleCoreInstance.saveIfNecessary(aProgressMonitor); |
| } finally { |
| if (moduleCoreInstance != null) { |
| moduleCoreInstance.dispose(); |
| } |
| } |
| } |
| </codesnippet> |
| <p> |
| For clients that would like to take an existing project an add Flexible |
| Project Support, use the ModuleCoreNature.addModuleCoreIfNecessary() API |
| to prepare the project to support flexible module structures. the |
| existing metamodel, then acquire the ModuleCore instance for modification. |
| </p> |
| <codesnippet caption="Add Flexible Project support to a new or existing project"> |
| ... |
| import org.eclipse.emf.common.util.URI; |
| ... |
| public static void makeFlexible(IProject aTargetProject) { |
| ModuleCore moduleCoreInstance = null; |
| try { |
| ModuleCoreNature.addModuleCoreNatureIfNecessary(aTargetProject); |
| moduleCoreInstance = ModuleCore.getModuleCoreForWrite(aTargetProject); |
| ... work with moduleCoreInstance and underlying model ... |
| moduleCoreInstance.saveIfNecessary(aProgressMonitor); |
| } finally { |
| if (moduleCoreInstance != null) { |
| moduleCoreInstance.dispose(); |
| } |
| } |
| } |
| </codesnippet> |
| --> |
| <a href="#top">top</a> |
| </body> |
| </html> |
| |