Inter-Project relations
1. Overview
2. Distribution
3. Exported Project Definition
4. Remote Project Access
In addition to inner-project relations between components, the methodology of Invicta covers the relationship between separate projects. In the following sections, we assume that project B depends on project A and uses its products. This methodology is based on the following concepts:
- No direct source access
- Project B will not access the source tree of project A. This should be enforced even if both A and B are developed by the same developers or software company.
- It is similar to a class that may not access private members or methods of a different class.
- Project A may change its internal structure and files without affecting projects like B that depend on it.
- Project distribution
- Because project B may not access directly project A, a distribution of project A should be created.
- This distribution is a well-structured tree of files that project A exposes to its users. It should contain mainly the products of the various components of the project (JAR files for example).
- The distribution is similar to a released package of a downloaded open-source software.
- Exported project definition
- In order to enable project B to access the distribution of project A, an exported project definition is used.
- The exported project definition describes the products of the distribution of project A.
- The exported project definition is similar to a public interface (or an API) that hides (or describes) the actual implementation, which is the project distribution.
As explained above, the distribution is a well-structured tree of files that project A exposes to its users (project B for example). The type definitions of Invicta define a 'dist' ANT target for each component. In built-in types (JAR, WAR, etc.) this target copies the products of the component into a distribution directory. In default, the products are organized in the distribution directory in a tree according to the components' tree of the project.
Other files than products may also be copied to the distribution directory. For example: documentation files, source files and the exported project definition file.
The example below shows a distribution tree of a project that is defined by the following project definition file:
Project definition of A:
<invictaProject>
<projectSettings name="A" dir="." version="1.0">
<property name="dist.dir" value="dist/A"/>
<property name="dist.product.dir" value="lib"/>
</projectSettings>
<component name="A" type="Project">
<property name="dist.list" value="exportedProjDef.xml"/>
</component>
<component name="A.utils" type="JAR">
<product file="AUtils.jar" type="jar"/>
</component>
<component name="A.core" type="JAR">
<product file="ACore.jar" type="jar"/>
</component>
<component name="A.core.test" type="Test">
<product file="ACoreTest.jar" type="jar"/>
<depend name="A.core"/>
</component>
</invictaProject>
Distribution tree of A:
A/
exportedProjDef.xml
lib/
utils/
AUtils.jar
core/
ACore.jar
test/
ACoreTest.jar
3. Exported Project Definition
As previously mentioned, project B may access project A by using an exported project definition of A. This project definition is a standard Invicta project definition file.
This file should have a single component that represents project A. The products of all components of project A are flatten to be products of the single component. Components of project B that depends on products of project A, only need to add a 'depend' line of the single component that represents project A, while specifying the specific products to depend on.
This file may be written manually for external projects (for example, projects that were downloaded from the Internet), or may be auto-generated for projects that use Invicta. Invicta includes a dumper named 'exportProjectDefinition'. This dumper automatically creates the exported project definition file of a distributed project.
In order to use this dumper, the following Invicta properties should be set:
invicta.dumpers.exportedProjectDefinition.enabled=trueinvicta.dumpers.exportedProjectDefinition.file=exportedProjDef.xml
The following is an example of an exported project definition file of project A:
<invictaProject>
<component name="A" type="Libraries" dir="${project.A.home}">
<product name="global" static="true" export="false"/>
<product name="utils" static="true" export="false"
file="/lib/utils/AUtils.jar" type="jar"/><product name="core" static="true" export="false"
file="/lib/core/ACore.jar" type="jar"/>
<product name="core.test" static="true" export="false"
file="/lib/core/test/ACoreTest.jar" type="jar"
depends="core"/></component>
</invictaProject>
Project B that depends on project A, should specify the location (path to a directory) of project A. This location is needed for finding the exported project definition, the actual products of project A as defined in the definition files and possibly also extensions to Invicta (for example: custom types of project A).
In default, the exported project definition requires a project property to specify the distribution location. The name this property is 'project.<project_name>.home', for example: A.home. The default value of this property may be set in the projectSettings element of the project definition of project B. Invicta scripts (both invicta.build.xml of the template project and the geneated build.xml) may use the following pre-defined properties for specifying locations of remote projects: remote.dir, remote.dir2 and remote.dir3. The default values of the remote directories may be set both in the project definition file of project B or in the script that initially runs Invicta (invicta.build.xml).
This method of defining the remote project directories as standard Invicta project properties allows each developer of project B to customize the actual remote location in ANT run-time. This may be done by editing the 'custom.properties' file or by specifying ANT run-time properties using the '-D' flag.
The following example is part of the project definition of B that specifies the default location of A:
<invictaProject>
<projectSettings name="B" dir="." version="1.0">
<property name="A.home" value="/projects/dist/A"/>
<property name="remote.dir" value="${project.A.home}"/>
...
A similar definition may be specified in the 'invicta.build.xml' file of project B:
...
<target name="local.init">
<property name="project.A.home" value="/projects/dist/A"/>
<property name="project.remote.dir" value="${project.A.home}"/>
...
Project B should add the exported project definition file of A to its definition location list by editing 'invicta.properties':
...
invicta.definition.locations=${local.env.dir}/projDef, ${remote.dir}/exportedProjDef.xml
Developers of project B may customize the location of project A. This may be done by editing 'custom.properties':
...
project.A.home=/home/mydir/A