Table of Contents
ABS means Advanced Build System, it's a component oriented toolchain.
It's not a Maven clone. it has some advanced components assembly features. ABS focus on simplicity and pragmatism, its first objectives are automatization, normalization and orchestration of computer applications build cycle. It enforces the MDA way in design activity.
ABS integrate several free java tools and offert a simple unique environment for all activities described in our component oriented methodology. All those tasks may be triggered using command line ant script or using Eclipse plugin.
ABS building environment offer a simple and pragmatic way to build component oriented MDA project. The differents available features are :
Component or project creation
Documentation generation based on UML model content (using PragMatic and Acceleo technologies)
Managing external binary and internal source dependencies
Integration with repository management system like CVS and Subversion
sources compilation
Unit tests run
Code generation
Continuous integration
Deployment management
and loads of others things ...
The ABS project is a free and collaborative project.You'll find more details on the web site : latest versions download, tutorials, bugtracker and mailing lists.
As we have seen in introduction, ABS main ambition is to industrialize software production. The first we took, was to defined a metamodel used to define all the concepts related to the project lifecycle : project, component, dependencies, deployment, ... In the following paragraphs, we will define all those concepts.
Component Oriented Development is a way of building sotfware using a modular architecture resulting in better understanding of system behaviour, easier maintenance and high level of reusability. In our context a component is :
a coherent business entity. For example : Customer, Bill, Order, ..
defined through a model
publishing business services reusable in different contexts
containing java source code, configuration files, all generated from its descriptive model. All those files defined the reference implementation. It's possible to use the same model to generated source code related to another target technology.
A binary dependency define a usage relationship between a component and an external binary library (build outside ABS). A project module (define later) may use this kind of dependency too. All component or module binaries dependencies are stored in the bindep.txt file located at the root of the component directory.
Those dependencies are mainly used during compilation and to build application package to deploy. Librairies are automaticaly downloaded in directory $ABS_HOME/binary-repository if not present on the local workstation just before compilation.
ABS knows where to look for missing librairies and where to store them after download using properties in build.properties file located in $ABS_HOME.
A source dependency define a usage relationship between two components : a A component needs a B component in order to run properly.A project module may used this kind of relationship with components. Source dependencies are stored in a srcdep.txt file located at the root of the component or module directory.
The previous example shows two dependencies declaration.Format of source dependencies are : scm_repository:target :
scm_repository : logical name of cvs or svn repository. These name is defined in file $ABS_HOME/repositories.properties cf. section TODO
: : séparateur
ltarget : component name. The second line in the example reference a component store in a svn repository and express directly dependency versionning, that is the current component needs trunk version of C component.
A project is an application, whose delivery is the final objective. it's the result of several business components assembly.It defines targent running environment named "deployment" which may have differents and specific configuration.
A deployment is a target running environment receiving war, tar.gz and jnlp files. We can define several differents deployment in the same project, for example :development, customer test, production, ... Deployments list is store in file deployment.txt located in the root directory of the project.
The previous example show 3 deployments. Very often each environment has distinct configuration properties. For example SMTP server to use is different for the development team and at the customer production site. We have to parametrize this information using a replacement token.
Example 1.4. Properties file containing SMTP server adress definition
smtp.server.name=@@stmp.server.name@@
Example 1.5. deployment/test/replace.server.properties file describing deployment parameter for value for test environment
@@smt.server.name@@=test.mail.sharengo.org
Example 1.6. deployment/preprod/replace.server.properties describing production environment
@@smt.server.name@@=mail.sharengo.org
The two previous files allows to have different smtp server for each environment. environnement.
The module concept is equivalent to a component but it is not reusable and therefore related only to one project. Very often, modules are only used to defined project dependencies. We can find very specific source code needed for migration or stuff like that. Modules list is stored in moddep.txt file located at project root directory.
This example shows a declaration for a module call "main" inside a project.
We have seen previously that ABS define tasks related to project methodology. You start by creating a project using abs new.project command and specifying a name. For each following task execution, ABS will load the project / component / module definition target of your command and will inject it in a velocity template containing a description of an Ant script to instanticiate. A script Ant is generated and run. One advantage of this approach is to completely separate project description from build tools. If you want to change the scripting langage and use something else, do it, that's easy. You have to see ABS as a logical "shell" running abstract project command in a project context. Moreover it's very configurable and use a package manager to upgrade easily developper workstation and so doing to provide new command very quickly. Developpers doesn't have to modify build script anymore.
ABS needs java version 5 or greater.
Create a directory for ABS (for example ~/abs).
Download installer (workshop-repository-manager-0.6.jar)
Start installation from install directory (~/abs), running the following commands :
java -jar workshop-repository-manager-0.6.jar http://sharengo.org/abs/0.7/abs-core java -jar workshop-repository-manager-0.6.jar http://sharengo.org/abs/0.7/mda java -jar workshop-repository-manager-0.6.jar http://sharengo.org/abs/0.7/qa java -jar workshop-repository-manager-0.6.jar http://sharengo.org/abs/0.7/doc
If you have to use a proxy, Si, vous souhaitez utiliser un proxy, you have to use the following syntax : java -jar workshop-repository-manager-0.6.jar repository-url [proxy port [user pwd] ]
Define ABS_HOME variable in your environment (ABS_HOME=~/abs)
Add directory $ABS_HOME/tc/ant/bin in your system path
Initialize toolchain
TODO vérifier que cette commande existe encore, si oui la supprimer et créer un fichier build.properties par défaut.
cd $ABS_HOME abs init
Answer the script questions (some sensible default values are provide, use it if you don't know the answer).This initialization phase will create a build.properties file in your $ABS_HOME directory. Here is a build.properties example :
binary.server.url=http://adk.open-model.org/adk-2.2/binary-components binary-repository.path=/home/jeromeb/dev/abs/binary-repository jvm.target=1.5 ci.server=build.argia.fr ci.user=XXXX ci.password=XXXX
Upload Eclipse version 3.3 (Europa) for your system : here .Start eclipse, select menu option "Help" -> "Software Updates" -> "Find and Install ..." :
Choose "Search for news features to install" and click "Next" :
Using "New Remote Site" button, add Sharen'Go update site : http://sharengo.org/update/europa, select it and click "Finish" Select Sharen'Go tools in the available features listand click "Next" :
Accept license and click "Finish"
This chapter doesn't not contains detailed informations, it presents the main useful commands. A more complete list can be obtained with the following command :
$> abs -p
Output example :
$> cd $ABS_HOME $> abs -p new.workspace Create new workspace in absolute directory new.component Add new component in production new.project Create new project in production new.scm.component Get an existing component in production new.scm.project Get an existing project in production $> cd /home/jeromeb/workspaces/ws-workspace1/projects/project1 $> abs -p abs:bug.report Report bug in tool chain abs:help Show Online Help, like man page. abs:upgrade.build Upgrade build file abs:version Show ABS version checkstyle:all Run checkstyle audit on local and dependent source code checkstyle:help Show Online Help, like man page. checkstyle:local Run checkstyle audit on local source code ci:register Register project in continuous integration server classycle:all Execution de l'analyse classycle classycle:clean Suppression des xml generes par classycle.run classycle:local Execution de l'analyse classycle clean:all remove all local and dependent builded files clean:help Show Online Help, like man page. clean:local remove all local builded files dep:add.bin Add a new dependency to a binary component dep:add.mod Add a new module to a project dep:add.src Add a new dependency to a source component dep:help Show Online Help, like man page. dep:ls.bin List all binary dependencies dep:ls.mod List all modules dep:ls.src List all source dependencies dep:mv.bin Change binary dependencies order dep:mv.mod Change module dependency order dep:mv.src Change source dependencies order dep:rm.bin Remove one binary dependency dep:rm.mod Remove module dep:rm.src Remove one source dependency deploy:build.cli build all Command Line Interface for each deployment deploy:build.client.cli build all Command Line Interface for each deployment. (just include common and client code) deploy:build.client.jnlp build all jnlp for each deployment. (just include common and client code) deploy:build.war build all Webapps Archive for each deployment deploy:help Show Online Help, like man page. deploy:new create new deployment target deploy:rm remove deployment target doc:all.design.pdf Generate SVG diagrams, DocBook documentation stored in UML model and final PDF for all design step doc:analysis.pdf Generate SVG diagrams, DocBook documentation stored in UML model and final PDF for analysis step doc:client.design.pdf Generate SVG diagrams, DocBook documentation stored in UML model and final PDF for client design step doc:common.design.pdf Generate SVG diagrams, DocBook documentation stored in UML model and final PDF for common design step doc:help Show Online Help, like man page. doc:needs.pdf Generate SVG diagrams, DocBook documentation stored in UML model and final PDF for needs step doc:server.design.pdf Generate SVG diagrams, DocBook documentation stored in UML model and final PDF for server design step eclipse:gen.classpath Generate classpath for eclipse project (all dependents components are loaded with binary jar) eclipse:gen.classpath.full.src Generate classpath for eclipse project (all dependents components are loaded with eclipse source project) eclipse:gen.project Generate required resources for eclipse project eclipse:help Show Online Help, like man page. hibernate:help Show Online Help, like man page. hibernate:schemaexport.all generate SQL source code and dependent component from Hibernate mapping description hibernate:schemaexport.local generate SQL source code from Hibernate mapping description javadoc:all generate javadoc for local and dependent generated deliverables javadoc:help Show Online Help, like man page. javadoc:local javadoc for all local java files lib:all Compile all local and dependent components lib:aspectj.all Compile all local and dependent components with AspectJ compiler in order to support OAP. lib:aspectj.local Compile local files with AspectJ compiler in order to support OAP. lib:help Show Online Help, like man page. lib:local Compile local files mda:apply.patch.local apply all patches on local generated file by others mda tasks mda:gen.hbm.local generate local hibernate mapping file from UML models mda:gen.java.local generate local java source code from UML models mda:help Show Online Help, like man page. mda:pim2pim.local Provide model-to-model transformation in order to check coherency of Plateform Independent Models netbeans:deploy.war deploy application in netbeans tomcat instance netbeans:gen.all.project Generate required resources for netbeans project netbeans:gen.local.project Generate required resources for netbeans project netbeans:help Show Online Help, like man page. netbeans:undeploy.war undeploy application in netbeans tomcat instance pmd:all Audit source files using company conventions pmd:help Show Online Help, like man page. pmd:local Audit local java files using company conventions pmd:report.all build audit source files using company conventions pmd:report.local Build audit local java files using company conventions scm:changelog.all build changelog for local files and dependent components scm:changelog.local build changelog for local files scm:co.all check out local files and dependent components scm:co.local checkout local files scm:help Show Online Help, like man page. scm:initial.import first import of component directory in scm repository scm:manual.tag.all Set to all source files and dependent component from scm repository a new tag version. (with custom tag name) scm:prepare.tree.all add empty dir to each dependent component after checkout scm:prepare.tree.local add empty dir to current component after checkout scm:tag.all Set to all source files and dependent component from scm repository a new tag version scm:tagdiff.all build changelog for local files and dependent components scm:tagdiff.local build changelog for local files scm:update.all Update source files and dependent component (preserve sticky tags) scm:update.local Update source files (preserve sticky tags) scm:update.to.tag.all Update source files and dependent component with specifieg tag scm:update.to.tag.local Update source files with specifieg tag scm:update.to.trunk.all Update source files and dependent component and reset sticky tags scm:update.to.trunk.local Update source files and reset sticky tags srcformat:all Reformat source files using company conventions srcformat:help Show Online Help, like man page. srcformat:local format local java files using company conventions test:help Show Online Help, like man page. test:java.all Run local Unit tests local and dependent components test:java.local Run local Unit tests
A workspace permits to separate working context. It defines a physical storage area for a project and all the needed components. A good practive is to keep a distinct workspace for each version of a project you work on. So we you are working on a given project phase, you have to create a workspace. Then when you'll started a new phase, you'll create a new workspace and so doing isolate phase2 from phase 1. If you want to do some modifications on the first one, you'll be able to deliver a new version with only your small modifications without any evolution of phase 2.You'll find thereafter a workspace creation command :
$> cd $ABS_HOME
$> abs new.workspace
abs:version:
[echo]
[echo] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[echo] ABS ~ Advanced Build System ~
[echo]
[echo] ~ Next Generation Build System ...
[echo] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[echo]
new.workspace:
[input] Enter workspace absolute path :
/home/jeromeb/workspaces/ws-workspace1
...
BUILD SUCCESSFUL
First, you need to position yourself in the directory related to the newly created workspace.
The "new.project" command create a new local project (local means with no equivalent in the repository).
$> cd /home/jeromeb/workspaces/ws-workspace1
$> abs new.project
abs:version:
[echo]
[echo] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[echo] ABS ~ Advanced Build System ~
[echo]
[echo] ~ Next Generation Build System ...
[echo] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[echo]
new.project:
[input] Enter project name :
project1
...
BUILD SUCCESSFULYou can also locally retrieve a project store in a repository using the command "new.scm.project" (the configuration of the various accessible repositories are kept in $ABS_HOME/repositories.properties :
$> cd /home/jeromeb/workspaces/ws-workspace1
$> abs new.scm.project
abs:version:
[echo]
[echo] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[echo] ABS ~ Advanced Build System ~
[echo]
[echo] ~ Next Generation Build System ...
[echo] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[echo]
new.scm.project:
[input] Enter project name :
project2
[input] Enter repository name :
sharengo
...
BUILD SUCCESSFULThe previous command has a variant to retrieve a project from a specific version. This command is useful mainly with cvs. If you use subversion, the previous command is sufficient because the version name is included in the project name, for example : project1/tags/1.0.
$> cd /home/jeromeb/workspaces/ws-workspace1
$> abs new.scm.project.from.tag
abs:version:
[echo]
[echo] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[echo] ABS ~ Advanced Build System ~
[echo]
[echo] ~ Next Generation Build System ...
[echo] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[echo]
new.scm.project.from.tag:
[input] Enter project name :
project3
[input] Enter tag :
version1.0
[input] Enter repository name :
sharengo
...
BUILD SUCCESSFULFirst, you have to position yourself in the directory related to the current workspace.
The command "new.component" create a new local component (local means with no equivalent in the repository).
$> cd /home/jeromeb/workspaces/ws-workspace1
$> abs new.component
abs:version:
[echo]
[echo] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[echo] ABS ~ Advanced Build System ~
[echo]
[echo] ~ Next Generation Build System ...
[echo] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[echo]
new.component:
[input] Enter component name :
component1
...
BUILD SUCCESSFULYou can retrieve an existing component stored in a repository using "new.scm.component" command.
$> cd /home/jeromeb/workspaces/ws-workspace1
$> abs new.scm.component
abs:version:
[echo]
[echo] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[echo] ABS ~ Advanced Build System ~
[echo]
[echo] ~ Next Generation Build System ...
[echo] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[echo]
new.scm.component:
[input] Enter component name :
component2
[input] Enter repository name :
sharengo
...
BUILD SUCCESSFULThe previous command has a variant in which you can specifiy the target version of the component you want to get in the repository. This command is useful mainly with cvs. If you use subversion, the previous command is sufficient because the version name is included in the component name, for example : component1/tags/1.0.
$> cd /home/jeromeb/workspaces/ws-workspace1
$> abs new.scm.component.from.tag
abs:version:
[echo]
[echo] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[echo] ABS ~ Advanced Build System ~
[echo]
[echo] ~ Next Generation Build System ...
[echo] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[echo]
new.scm.component.from.tag:
[input] Enter component name :
component3
[input] Enter tag :
version1.0
[input] Enter repository name :
sharengo
...
BUILD SUCCESSFULThe "lib.local" command is used to compile a component or a project. This operation build 3 jar archives containing all *.class files from the java source files. You can also use the command "lib.all" which apply the compilation process on all components used by the current one. The 3 resulting archives are :
COMPONENT-NAME.jar : all class files from the "common" directory
COMPONENT-NAME-client.jar : all class files from the "client" directory
COMPONENT-NAME-server.jar : all class files from the "server" directory
$> cd /home/jeromeb/workspaces/ws-workspace1 $> cd components/component1 $> abs lib:all ... BUILD SUCCESSFUL
The "deploy.new" command create a new deployment environment for the current project. It add a directory with the deployment name inside the "deployment" directory located in project root directory. It also create replace.server.properties and replace.client.properties files containing the value of the variable part of the configuration.
$> cd /home/jeromeb/workspaces/ws-workspace1/projects/project1
$> abs deploy:new
abs:version:
[echo]
[echo] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[echo] ABS ~ Advanced Build System ~
[echo]
[echo] ~ Next Generation Build System ...
[echo] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[echo]
deploy:new:
[input] Enter deployment target name :
localhost
...
BUILD SUCCESSFULThe "deploy:build.war" command build a WAR archive which can be deployed in an application server as Tomcat.
The "deploy:build.cli" command build a *.tar.gz archive containing an application environnement for command line interface program.
This 2 commands build one archive file for each deployment environment using the configuration parameter values found in replace files.
In menu : "New" -> "Project" -> in ABS node select "New Component"
The eclipse plugin interacting with your locally installed ABS, it's mandatory to specify the installation directory $ABS_HOME and the ABS workspace. If those informations are not available in ABS eclipse configuration (menu "Window" -> "Preferences ..." -> "ABS Preference"), the following wizard will be presented and will help you to configure :
In menu : "New" -> "Project" -> in ABS node select "New Project"
When a new project is created, the wizard automatically add a module named "main" and a "localhost" deployment. You'll find in "PackageExplorer" view a module "project1_main" and a deploiement "project1_localhost_server".
A design model may be created for a component or project module.
Locate yourself in server/model/conception directory and create a model named conception.uml using menu "New" -> "Other..." -> "SharenGo Unified Modeling" -> "Step 3 - New Conception Model"
This action create three files :
conception.uml : this file contains all structural model element,
conception.umldi : this file contains all diagrams description using the first one to reference element appearing in diagrams,
conception.properties : this file is used to parametrize generation strategy. The default values are sensible for current use.
In order to modelize the various components we need, we have define a logical architecture at the PIM (Platform Independant Model) level in the MDA way. The following schema shows the different layers of this architecture based on the MVC pattern.
This architecture model may be seen as a metamodel because it will instanciated in each component and module. For historical reasons, we have choosen the UML language and not a DSL (Domain Specific Language). A UML profile has been designed to incorporated the various concepts used in the architecture metamodel. This profile contains a set of stereotypes and properties described in the next section.
Stereotypes are used to add specfic semantic meaning to UML elements. The next figure shows how to apply a stereotype in Topcased modeler.
A stereotype define a set of properties which can be valued in the "Stereotype attributes" tab.
Definition. This stereotype is used to define business domain objects (which are persisted by the application).
Properties. None
Usage context.
Definition. This stereotype is used to specify transferable datas. The DTO (Data Transfert Objects) pattern is used to build a mediation layer between business processes and UI layer.
Properties. None
Usage context. Often used as an operation parameter.
Definition. This stereotype is applied on class defining Data Access Objects following the well known pattern. This kind of class manage storage and retrieval for entities.
Properties. None
Dependencies. TODO ajouter un screenshot
Definition. Used on classes defining business services ou processes
Properties. None
Usage context. A "process" class may used others processes or EntitiesManager
Definition. This stereotype is used to route user requests. It decodes transmitted datas and send them to the UI layer.
Properties. None
Usage context.
Definition. This stereotype is applied on classes orchestrating requests to business process and transmitting the results to view in order to show datas to end users.
Properties. None
Usage context. A UI class may used others UI, UI uses Process and views Une Ui peu utiliser d'autres Ui, faire appels à des Process et utiliser des View.
Definition. This stereotype is used to define user "screen".
Properties. None
Usage context. A view is used by UI.
Definition. This stereotype express that an operation is remotely usable. In a UI context, that means that an AJAX kind of use is possible (call from web browser). In a Process context the operation is published as web service.
Properties. TODO
Definition. Express the transactionnal semantic of a process operation.
Properties. None
Definition. This stereotype is applied on classes defining configuration values. For example, in order to define a smtp server name, you have to define a "smtpserver" attribute of type String in a class supporting the "Config" stereotype.
Pproperties. None
Usage context. Config classes may be used by all classes of the architecture.
We are using the Acceleo transformation model to text tool to generate source code from UML model following the logical architecture. In order to run a transformation, you to define a transformation chain. In our case, we will define a specific chain calling a generic one for a given architecture.
To create the chain "conception.launch", select menu "New" -> "Others" -> "Acceleo" -> "Module Launcher" :
Choose chain : "Java Generator for Spring / Hibernate / Velocity Architecture" :
Click "Next" and set "conception.chain" as name :
click "Next", select the surce UML model source (conception.uml).
Cliquer sur "Next", sélectionner le modèle UML source conception.uml :
Double click on the file to edit the chain if you want to modify something
Run the code source generation choosing the "Launch" option in the contextual menu of the conception.chain file.
Spring is a java library used to build technical frameworks for various architecture. It's a light container offering an environment comparable to Spring biggest strength is his use of IoC Inversion of Control) pattern described here :http://www.martinfowler.com/articles/injection.htmlby famous architect Martin Fowler. The reference documentation of the project is loacted here : http://www.springframework.org/docs/reference/
In order to use Spring in a component or module, you must add a dependency to middleware/gluon-core component. This component defines all binary dependencies needed by Spring.
First, you have to retrieve this component from the repository using the option menu New / Project ... / ABS / Create a new Component from SCM repository :
Choose the target repository and input the component name.In our case we'll use the trunk version.
Add the dependency toward this component, editing the srcdep.txt file in component or module root directory and adding the following line :
You'll find thereafter an exhaustive list of all generated files for each kind of stereotype.
For an entity class named "MyEntity1" located in the package "entitties" in a "org::sharengo::component1" model , the generated files are :
server/main/src/org/sharengo/component1/entities/MyEntity1.java : business class
server/resources/org/sharengo/component1/entities/hibernate/MyEntity.hbm.xml : hibernate mapping file
server/test/src/org/sharengo/component1/entities/impl/MyEntityHelper.java : helper class used to create business object (used in unit tests)
For a dto class named "MyDto1" located in the "dto" package in a "org::sharengo::component1" model, there is only one generated file :
/server/main/src/org/sharengo/component1/dto/MyDto1.java
For an EntitiesManager class named "MyEntity1Mgr" located in the package "entities"in a "org::sharengo::component1" model , the generated files are :
server/main/src/org/sharengo/component1/entities/IMyEntity1Mgr.java : Data Access interface
server/main/src/org/sharengo/component1/entities/impl/MyEntity1MgrImpl.java : Date Access implementation related to the previous interface
server/test/src/org/sharengo/component1/entities/impl/MyEntity1MgrTest.java : unit tests for the implementation
server/resources/META-INF/spring/org.sharengo.component1/layer-daos-hibernate.xml : Spring configuration file with entities manager declaration and related dependencies.
For a process class named "MyProcess1" located in the "process" package of a "org::sharengo::component1" model, the generated files are :
server/main/src/org/sharengo/component1/process/IMyProcess1.java : business service interface
server/main/src/org/sharengo/component1/process/impl/MyProcess1Impl.java : business service implementation
server/test/src/org/sharengo/component1/process/impl/MyProcess1Test.java : unit tests for implementation
server/resources/META-INF/spring/org.sharengo.component1/layer-services.xml : Spring configuration file with process class declaration and related dependencies. It also defines the transactional strategy for each operation supported the "Transactional" stereotype.
If some operations support the "Remote" stereotype, more files are generated :
server/main/src/org/sharengo/component1/process/IMyProcess1WebService.java : interface containing only "remote" methods declaration.
server/resources/META-INF/spring/org.sharengo.component1/layer-xfire-services.xml : Spring configuration file used to link the interface to the implementation and defining the URL access for each operations.
server/test/src/org/sharengo/component1/process/impl/MyProcess1WebServiceTest : unit tests for remote methods.Those tests reuses the process unit tests providing a process instance used through remote access using an embedded jetty server.
server/test/src/org/sharengo/component1/process/impl/MockMyProcess1WebService.java : mock object for unit tests
client/main/src/org/sharengo/component1/ws/WSClientFactory.java : factory creating IMyProcess1WebService instance from URL like http://localhost/project1/services/IMyProcess1WebService
For a controller class named "MyController1" located in a "ui" package in a "org::sharengo::component1", the generated files are :
server/main/src/org/sharengo/component1/ui/MyController1.java : router class to "UI"
server/resources/META-INF/spring/org.sharengo.component1/layer-controllers.xml : Spring configuration file containing controller implementation declaration and related dependencies.
For a ui class named "MyUi1" located in the "ui" package of a "org::sharengo::component1" model, the generated files are :
server/main/src/org/sharengo/component1/ui/IMyUi1.java : UI interface
server/main/src/org/sharengo/component1/ui/impl/MyUi1Impl.java : ui implementation
server/resources/META-INF/spring/org.sharengo.component1/layer-uis.xml : Spring configuration file containing ui implementation declaration and related dependencies.
For a view class named "MyView1" located in the "ui" packagei of a "org::sharengo::component1" model, the generated files are :
server/main/src/org/sharengo/component1/ui/impl/MyView1.java : view class
server/main/src/org/sharengo/component1/ui/ViewFactory.java : view obect factory. the view objects are stateful and cannot be injected as the others elements of the architecture.
server/main/src/org/sharengo/component1/Confi/MyConfig1.java : configuration class
server/resources/META-INF/spring/org.sharengo.component1/layer-configs.xml : Spring configuration file declaring the previous class.
server/resources/META-INF/spring/component.xml : Spring configuration files defining what are the needed "layer*" configuration files for the current component
server/resources/META-INF/spring/component-test.xml : same role as previous file but used in unit tests context and therefore modifiable
server/resources/META-INF/spring/org.sharengo.component1/applicationContext-tests.xml : Spring configuration file defining hibernate resources and others resources used in unit tests.
server/test/src/org/sharengo/component1/AbstractBusinessLayerTests.java : abstract class used by all unit tests.It"s used to initialize the components graphs.
Before running unit tests, we have to verify and adjust component parametrization in server root directory /resources/META-INF/spring :
This file is the entry point of all components and modules. It defines all the prerequisites for optimal execution of each components. It defines all technical and business layers hich must be loaded at startup time. You have to modify this file in relation with usage (component with or without ui, with or without WebServices facade, etc).
Example 4.2. component.xml example
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> <!-- Start of user code component definition --> <!-- load component Controller layer --> <import resource="classpath:META-INF/spring/org.sharengo.component1/layer-controllers.xml"/> <!-- load component Ui layer --> <import resource="classpath:META-INF/spring/org.sharengo.component1/layer-uis.xml"/> <!-- load component Process layer --> <import resource="classpath:META-INF/spring/org.sharengo.component1/layer-services.xml"/> <!-- load component EntitiesManager layer --> <import resource="classpath:META-INF/spring/org.sharengo.component1/layer-daos-hibernate.xml"/> <!-- load component Config layer --> <import resource="classpath:META-INF/spring/org.sharengo.component1/layer-configs.xml"/> <!-- load component Remote / Web Services layer --> <import resource="classpath:META-INF/spring/org.sharengo.component1/layer-xfire-services.xml"/> <!-- technical layers --> <!-- load Hibernate layer --> <import resource="classpath:META-INF/spring/layer-hibernate.xml"/> <!-- load Velocity layer --> <import resource="classpath:META-INF/spring/layer-velocity.xml"/> <!-- load XFire layer --> <import resource="classpath:META-INF/spring/layer-xfire.xml"/> <!-- End of user code component definition --> </beans>
This file load all needed components and resources needed for unit testing the current component. The default configuration is sensible and must be sufficient, but you can modify it.
Example 4.3. component-test.xml example
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> <!-- Start of user code component definition for test environment --> <!-- include all component.xml file found in classpath to startup all needed components --> <import resource="classpath*:META-INF/spring/component.xml"/> <!-- load needed resources for unit tests --> <import resource="classpath:META-INF/spring/org.sharengo.component1/applicationContext-tests.xml"/> <!-- End of user code component definition for test environment --> </beans>
It's located in directory server/resources/META-INF/spring/MODEL_NAME/ and specifiy dabases resources among others if needed. You may adjust the "Start of user code other hbm files" section in order to load mapping files from others components.
Example 4.4. applicationContext-tests.xml example
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd">
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
<property name="url" value="jdbc:hsqldb:."/>
<property name="username" value="sa"/>
<property name="password" value=""/>
</bean>
<!-- ========================= HIBERNATE CONFIGURATION ====================== -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mappingResources">
<list>
<value>org/sharengo/component1/entities/hibernate/MyEntity.hbm.xml</value>
<!-- Start of user code other hbm files-->
<!-- End of user code -->
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.generate_statistics">true</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
<prop key="hibernate.jdbc.batch_size">1</prop>
</props>
</property>
</bean>
<!-- Start of user code specific test injection-->
<!-- End of user code specific test injection -->
</beans>The server/test/src/org/sharengo/component1/entities/impl/MyEntity1MgrTest.javaclass implements a unit tests to check basics (CRUD) data access operations.The class must be modify to include new tests each time a new operation is added in the EntitiesManager class. Then you can run the unit test :
and check results :
The class server/test/src/org/sharengo/component1/process/impl/MyProcess1Test.javaimplements unit tests to check business process layer operation. You have to code a test, the tested operations and run unit test.
The ${PROJECT_NAME} variable must be replace by the project name in the example files.
The web.xml file is automatically generated by assembly of the differents components descriptors files. The deployment task "deploy:build.war" is in charge of this operation. The eclipse plugin call this task during each tomcat startup.
You have to define the variable @@hibernate.datasource@@ in ${PROJECT_NAME}/deployments/localhost/server/replace.server.properties
@@hibernate.datasource@@=jdbc/${PROJECT_NAME}Remember to add the needed JDBC driver in tomcat/common/lib directory and edit the ${PROJECT_NAME}/modules/main/server/main/conf/context.xml file to define parameters values for database access :
<Context
path="/${PROJECT_NAME}"
debug="1"
reloadable="true">
<Resource
name="@@hibernate.datasource@@"
auth="Container"
type="javax.sql.DataSource"
driverClassName="org.postgresql.Driver"
url="jdbc:postgresql://localhost:5432/${PROJECT_NAME}"
username="postgres"
password=""
maxIdle="2"
maxActive="4"
maxWait="5000"
validationQuery="select now();"
/>
</Context>Create and edit the file ${PROJECT_NAME}/modules/main/server/main/conf/applicationContext.xml in order to configure hibernate and specifying all mapping files to load :
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd">
<import resource="classpath*:META-INF/spring/component.xml"/>
<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/@@hibernate.datasource@@"/>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mappingResources">
<list>
<value>org/sharengo/${OneComponent}/entities/hibernate/${OneHibernateMappingFile}.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.generate_statistics">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.jdbc.batch_size">1</prop>
</props>
</property>
</bean>
</beans>Create the related Postgresql database :
$> createdb -U postgres -E unicode project1
Add needed dependencies to components used by the project in the srcdep.txt file of project module.
Run the Tomcat containerusing the contextual menu "Run As / Run On Server" in deployement :