Version 2

    JBossTools is moving into standardizing default project structures as WTP projects.  The deployment structure of these projects are primarily manipulated via the Virtual Component Framework at the bottom, and a Module Factory and associated classes at the top. Differences between our implementations of some of these classes and WTP's examples stem mainly from my efforts to streamline and clean up these classes, making the virtual component draw cleanly from its references, and the module delegate to similarly act as a simple overlay to the VCF.





    The Virtual Component Framework (VCF) draws primarily from it's descriptor file .settings/org.eclipse.wst.common.component. The primary pieces of this framework are a project's "component", the mapped in "folders", and finally references. A component is the primary representation of a project in the VCF. It's root folder can be accessed, as can its references. The root folder will automatically fold any and all resources mapped in the component's xml file, however it will *not* combine in any references. This means any and all <wb-resource> elements will fold in automatically. This logic is in the VirtualFolder class, a core class, and reads the component.xml file to accomplish this.


    Next are references. References are *not* automatically mapped in, and it is the job of the Module Factory (and associated classes) to properly take these references and combine them into thet list of deployable artifacts.  "References" must refer to other virtual components. These virtual components would then expose *their* root folder, and set of files. References can be one of two types: "USES" or "CONSUMES".



    Deployment Factories using VCF


    Deployable modules can be asked for two things.The first is a full complete list of member artifacts, and the second is child modules. A full list of member artifacts is not the same as asking the virtual component for it's members. Often, a virtual component's references will also need to be exposed as members, and these items would need to be combined with the VCF's list.  Also, as WTP does, sometimes a file which is mapped in directly via the VCF might want to declare itself to be a child module and exposed that way instead. In that case, that file needs to be removed from the current list of members.


    While there's no official javadoc demanding any behaviour, past usage from WTP seems to indicate that a "used" referenced component should be exposed as a child module and not combined with the current component's resources. So for example, an ear project which "uses" a web project should expose the web project as a child, and in the final deployment have a path such as SomeEar.ear/SomeWar.war/each/resource.file.


    "Consumed" references, however, *should* be combined with the current module's resources as if this consumed resource was actually already placed inside the project. The name of consumed references should not be appended or used at all when consuming these resources. Here, for example, if one utility project "Util1" consumes another "Util2", then all classes and other resources from Util2 should appear as if they were in Util1 all along. So, the class org.example.consumed.Roar should be exposed as Util1.jar/org/example/consumed/Roar.class. You'll notice Util2.jar is not mentioned at all.


    Deployment Factory Strategy


    WTP's Deployment factories have very complicated members() implementations which try to draw from too many places. Perhaps worse, these locations are not persisted in the project's component.xml and seem to be added as if by magic Our efforts here are to replace "automatically added" pieces of WTP content with persistable and understandable individual units of work, specifically consumed references. New consumed-type references which have been added to JBTools are listed below.


    These new reference types are translated by the "ReferenceResolver" API project.  A handle / uri is converted into an IVirtualReference for each of these. In the current implementation, each new reference type also has an associated component type, and its own reference resolver.



    Persisted WTP References


    WTP currently has 3 types of references that are presisted in the component.xml. One is a project reference (a reference to a child project), one is a reference to a jar (either in the workspace or out), and the last is a reference to a variable entry.


    Project References


    A project reference is persisted in the component.xml in the following way. It's handle uri begins with "module:/resource/".


    <dependent-module archiveName="SomeUtil.jar" deploy-path="/" handle="module:/resource/SomeUtil/SomeUtil">


    Jar References


    Jar references are persisted in the component.xml in the following way. It's handle uri begins with "module:/classpath/lib"


    <dependent-module archiveName="blah1.jar" deploy-path="/" handle="module:/classpath/lib//home/rob/tmp/blah1.jar">


    Variable References


    Variable references are persisted in the component.xml in the following way. It's handle uri begins with "module:/classpath/var".


    <dependent-module archiveName="some2.jar" deploy-path="/" handle="module:/classpath/var/MEJAR">


    Custom References


    There are several types of references which are magically added in WTP's module factories / module delegates. I have tried to replicate them as persistable units here.

    Output Folders


    WTP deployment factories purposely ignore files ending in .java from the VCF model and then later attempt to dereference these source folders into class folders and include those. Adding a reference to an OutputFoldersVirtualComponent will automatically map in the output folders of all source folders in the project. The constructor for this virtual component allows you to pass in any project. To add this reference to a component, you would first instantiate an OutputFoldersVirtualComponent via its constructor, and then use a utility method in to add the reference.  What URI this will have when persisted is determined 100% by the OutputFoldersReferenceResolver, which turns this reference into a uri. The current implementation will return a prefix-id as the first segment, with an optional second segment listing the project who's output folders should be mapped in.


    The output-folders references are persisted in the component.xml in the following way. It's handle uri begins with "module:/"


    <dependent-module deploy-path="/" handle="module:/[optional Project Name]">


    Exported Class Folders


    Classpath entries which reference class folders in other projects are resolved by this type. In order to be resolved, the classpath entry must be exported *and* have an attribute set on it's classpath entry (org.eclipse.jst.component.dependency). If this seems like duplication to you, thats because it is. If it seems like the user will now need to keep two models in sync himself, he will. And if you don't like this, too bad. Unfortunately this is how it's done in WTP, and for parity, thats how it's done here. Not all exported classpath folders are automatically bundled. Only such entries which also have this flag are bundled. So... where is the UI to modify this flag? Unfortunately we still need to add an "edit reference" button and allow the wizard to present possible changes. For now, the user would need to remove the reference, and create it again. The wizard page in charge of adding this reference allows you to add or remove this flag from certain entries.


    The exported class folders references are persisted in the component.xml in the following way. It's handle uri begins with



    <dependent-module deploy-path="/" handle="module:/">


    The flag on these classpath entries is also persisted in the .classpath file. An example of this attribute is shown here:


        <classpathentry exported="true" kind="lib" path="/SomeUtil/build">
                <attribute name="org.eclipse.jst.component.dependency" value="/"/>