Understanding new tools and technologies can be a daunting task. AndroMDA is no exception. This tutorial serves as a gentle introduction to the power of AndroMDA. We will show you step-by-step how to set up your development environment and build your first .NET application. Instead of mechanically going through a series of steps, we will focus on ideas and concepts behind what we are doing. Armed with this knowledge you will be well positioned to take on real world challenges. Please set aside half a day of quality uninterrupted time to learn AndroMDA as there is lot to learn. Then brew a good cup of coffee and immerse yourself in the wonderful world of Model Driven Architecture.
What follows is a step-by-step guide to set up your development environment for AndroMDA. We assume that you are working on a Windows platform.
Install Visual Studio 2003 or Visual Studio 2005. Our preference, without any doubt, is Visual Studio 2005. It is a much more productive environment. So if you have any flexibility in this matter, do yourself a favor and choose this newer version! The instructions in this tutorial assume VS 2005. If you are using VS 2003, you will have to make minor adjustments to do equivalent tasks.
When installing Visual Studio 2005, use custom installation options to prevent the installation of SQL Server Express Edition. We will be installing SQL Server 2000 or 2005 in the next step. Also note that AndroMDA.NET currently supports generation of C# only, other .NET languages are not supported.
Install SQL Server 2000 or SQL Server 2005. You should be able to use other databases by configuring NHibernate appropriately. However for the purpose of this tutorial we will assume SQL Server.
Install J2SE Development Kit 5.0 (JDK 5.0) from here. This is the preferred version of the JDK for AndroMDA.NET. We also support JDK version 1.4. If you prefer this version, you can download it from here.
Make sure that the
JAVA_HOME
environment variable is pointing to
the directory where you installed the JDK. It is possible you have this
variable set already, but just to make sure here's how to check.
System
.
If you are a Windows XP user it's possible you have to open
Performance and Maintenance
before you will see
the
System
icon.
Advanced
tab and click on
Environment Variables
JAVA_HOME
variable set
and it is pointing to the directory where you installed the JDK.
If not, add/edit the variable and set it to the correct value,
e.g. C:\Program Files\Java\jdk1.5.0. You may add the variable
to the list of user variables or system variables.
Maven is a software project management and comprehension tool. Based on the concept of a project object model (POM), Maven can manage a project's build, reporting and documentation from a central piece of information. We will now install Maven and configure it to download dependencies from the AndroMDA server whenever it needs to.
C:\Program Files\Apache Software Foundation\Maven 1.0.2
)
home
directory. (If your login is
foo
this means here:
C:\Documents and Settings\foo
)
build.properties
and
add the following line in there. This line instructs Maven to
look for artifacts at the AndroMDA site in addition to the ibiblio site.
maven.repo.remote=http://www.ibiblio.org/maven,http://team.andromda.org/maven
We have seen earlier how to set environment variables such as
JAVA_HOME
, it is strongly recommended to set the
following variables before continuing. We repeat
JAVA_HOME
here just for completeness.
| Property | Value | Required? |
|---|---|---|
| JAVA_HOME |
Java installation directory, e.g.
C:\Program Files\Java\jdk1.5.0
|
Yes |
| MAVEN_HOME |
Maven installation directory, e.g.
C:\Program Files\Apache Software Foundation\Maven 1.0.2
(this may have already been set by the Maven installer)
|
Yes |
| MAVEN_OPTS |
Parameters to pass to the Java VM when running Maven. Set this
value to:
-XX:MaxPermSize=128m -Xmx512m
(required to build large maven projects such as AndroMDA itself)
|
No |
| PATH |
This makes sure the system will search for console commands in
the directories listed here. If this property already exists you
should simply add
%JAVA_HOME%\bin;%MAVEN_HOME%\bin
|
Yes |
Next we will download and install the AndroMDA C# Application plugin to the MAVEN_HOME\plugins directory. This plugin allows creation of C# starter applications that use AndroMDA. This is the only AndroMDA artifact that we will install explicitly. All other artifacts, such as AndroMDA cartridges, will be automatically downloaded by the Maven scripts generated by the plugin.
To install the C# Application plugin open a Command Prompt and Execute the following command. Make sure you get a "BUILD SUCCESSFUL" message at the end of the command output.
maven plugin:download -DgroupId=andromda -DartifactId=maven-andromdacsapp-plugin -Dversion=1.0-SNAPSHOT
Notice that you will now have
maven-andromdacsapp-plugin-1.0-SNAPSHOT.jar
installed at MAVEN_HOME\plugins
(
C:\Program Files\Apache Software Foundation\Maven 1.0.2\plugins
for this example).
Install a tool that will allow you to model your applications in UML and export these models into a format that AndroMDA can understand. AndroMDA currently supports UML 1.4 and XMI 1.2. Please follow one of the links below to install the UML tool of your choice. (As of this writing only one tool is supported. We invite UML tool vendors and open-source projects to test their tools with AndroMDA and supply installation instructions for inclusion in this section.)
Now that the development environment is ready to go, it is time to build our first AndroMDA application. We will design and implement a simple TimeTracker application that allows users to enter timecards.
The diagram below shows four key components of the TimeTracker application and their relationships. We will create a Visual Studio project for each of these components. What follows is a high-level description of each component.
TimeTrackerCore
library.
TimeTrackerCore
library. This DDL can be used to
create tables that will store the TimeTracker entities. SchemaExport also has the
capability to directly create the tables in a database.
In this section we will perform the one-time set up that is necessary to start any AndroMDA application. Subsequent sections will describe the iterative development process that follows this initial set up. So roll up your sleeves and let's get started!
We start by creating a blank Visual Studio solution and populating it with the projects that make up the TimeTracker application.
TimeTracker
as the name of the solution.
Follow the steps below to add a project called TimeTrackerCommon to our solution. As mentioned earlier, this project will generate a class library containing classes common to multiple tiers.
TimeTrackerCommon
as the name of the project.
Follow the steps below to add a project called TimeTrackerCore to our solution. This project will generate a class library containing the entities and the data access layer for the TimeTracker application.
TimeTrackerCore
as the name of the project.
Follow the steps below to add a project called TimeTrackerConsole to our solution. This project will generate a console application that allows creation and display of various entities used by TimeTracker.
TimeTrackerConsole
as the name of the project.
Follow the steps below to add a project called SchemaExport to our solution.
This project will generate a console application that allows DDL generation from
the entities defined in the
TimeTrackerCore
library.
SchemaExport
as the name of the project.
Now save the Visual Studio Solution by selecting File > Save All. Exit Visual Studio by selecting File > Exit. At this point the preliminary set up of our Visual Studio solution is complete.
Let us turn our attention to the one-time setup required for code generation from AndroMDA. This procedure will add Maven build scripts, an empty UML model and a Lib directory to the TimeTracker solution. The Maven scripts will be used to generate code from our UML model. So let's get started.
maven andromdacsapp:generate
__ __
| \/ |__ _Apache__ ___
| |\/| / _` \ V / -_) ' \ ~ intelligent projects ~
|_| |_\__,_|\_/\___|_||_| v. 1.0.2
Please enter your first and last name (e.g. Louis Coude):
Naresh Bhatia
Please enter the name of your C# application (e.g. Time Tracker):
Time Tracker
Please enter a version for your application (e.g. 1.0-SNAPSHOT):
1.0-SNAPSHOT
Would you like to create an ASP.NET web site? (enter 'yes' or 'no'):
no
build:start:
andromdacsapp:init:
andromdacsapp:generate:
[echo] +------------------------------------------------------------------+
[echo] | G E N E R A T I N G A n d r o M D A C# S O L U T I O N |
[echo] +------------------------------------------------------------------+
andromdacsapp:init:
andromdacsapp:generate-mda-project:
[mkdir] Created dir: C:\TimeTracker\mda\src\uml
[copy] Copying 1 file to C:\TimeTracker\mda\src\uml
[zip] Building zip: C:\TimeTracker\mda\src\uml\TimeTrackerModel.xml.zip
[delete] Deleting: C:\TimeTracker\mda\src\uml\TimeTrackerModel.xml
[mkdir] Created dir: C:\TimeTracker\mda\conf
[copy] Copying 1 file to C:\TimeTracker\mda
andromdacsapp:init:
andromdacsapp:generate-common-project:
andromdacsapp:generate-project:
[mkdir] Created dir: C:\TimeTracker\TimeTrackerCommon\src
[mkdir] Created dir: C:\TimeTracker\TimeTrackerCommon\target
andromdacsapp:init:
andromdacsapp:generate-core-project:
andromdacsapp:generate-project:
[mkdir] Created dir: C:\TimeTracker\TimeTrackerCore\src
[mkdir] Created dir: C:\TimeTracker\TimeTrackerCore\target
andromdacsapp:init:
andromdacsapp:generate-schema-export-project:
[copy] Copying 2 files to C:\TimeTracker\SchemaExport
andromdacsapp:init:
andromdacsapp:generate-lib-directory:
[mkdir] Created dir: C:\TimeTracker\Lib
[copy] Copying 11 files to C:\TimeTracker\Lib
[echo]
[echo] *** New C# solution generated in 'C:\\TimeTracker' ***
[echo]
BUILD SUCCESSFUL
Total time: 51 seconds
Finished at: Sat Nov 12 17:06:50 EST 2005
Examine the various folders and files created by the
andromdacsapp
plugin. You
will notice files called
project.xml
,
maven.xml
and
project.properties
at various levels in the TimeTracker solutions. These
files represent Maven projects, scripts and properties. You will also notice a
mda
folder which contains an empty UML model under
mda\src\uml
. Finally you will see a
Lib
folder containing dlls to be used by the generated code. Most dlls belong to
the NHibernate library
which is used for object persistence. In addition you will find the following dlls:
AndroMDA.NHibernateSupport.dll
: used to manage NHibernate sessions
NHibernate.Nullables2.dll
: used to store .NET 2.0 Nullable types using NHibernate
log4net.dll
: used for general purpose logging
By the way, do you remember that so far we have downloaded only one AndroMDA artifact? It was the AndroMDA C# Application plugin. Well, its time to pull in the remaining artifacts. We will do this implicitly by running the maven scripts generated above. These scripts specify all dependencies the application has on AndroMDA. So if we execute them on our blank model, all the necessary dependencies will be pulled into our Maven repository. Of course, since the model is blank, no code will be generated. However getting the dependencies now is important since we will need them very soon. Follow the steps below to download the required dependencies.
C:\TimeTracker
.
maven
. You will see messages on your screen showing
artifacts that are being downloaded. Make sure you get a
BUILD SUCCESSFUL
message when the Maven script ends.
Create a new database in your SQL Server instance using SQL Server Enterprise Manager and name it TimeTracker. You may use an existing database, just be sure to replace the name TimeTracker with the name of your database later in the tutorial.
Congratulations! You have now completed the one-time setup for TimeTracker. We are now ready to start modeling!
In this section we will implement four key entities of the TimeTracker application - Person, Timecard, TimeAllocation and Task. In addition we will implement two supporting classes - TimecardStatus and Quantity. TimecardStatus is an enumeration and Quantity is an embedded value inside the Person entity. The diagram below shows these classes and their relationships.
Note the level of detail in this diagram. Every detail has some meaning - none of the content is "fluff". For example we use stereotypes to indicate the "flavor" of each class - Entity vs. Enumeration vs. EmbeddedValue. Stereotypes tell AndroMDA the pattern of code to generate for each class. More specifically, stereotypes determine which AndroMDA templates get triggered to generate code. Similarly the various decorations you see on associations have very specific meanings. It is this level of preciseness that enables AndroMDA to generate major portions of your application - this is truly what Model Driven Architecture is! Here are some of the advantages of this approach:
Now that you are fully bought into the idea of Model Driven Architecture :-), let's get started with the TimeTracker model shown above.
As part of the setup procedure performed earlier, AndroMDA had created an empty UML model in the TimeTracker solution. We will now start populating this model. Please follow one of the links below to edit the TimeTracker model with the UML tool of your choice. (There is only one choice at the time of this writing.)
Follow the steps below to generate code.
C:\TimeTracker
.
maven -o
and boom, there you have it - code for all the
classes in your model is generated! Make sure you get a
BUILD SUCCESSFUL
message when Maven finishes execution. Note that we ran Maven with the "-o"
option this time. This option runs Maven "offline", which means there is no attempt
to fetch required dependencies from the Internet. It is assumed that they
are all available on your local hard drive. Running Maven with this option is much
faster and hence is used more often. However if Maven complains that it cannot find
some dependencies locally then it is easy enough to run it without the "-o" option
and get them from a remote repository.
Notice that code is generated in the following folders.
TimecardStatus.cs
, representing
the enumeration
TimecardStatus
.
DaoFactory.cs
which is used to get
instances of the DAOs.
Impl
suffix. These files
are intended for modification by the developer.
Note that code produced in
target
folders should never be modified by hand.
It will be deleted completely before regeneration in the next iteration. It is also
a best practice not to check this code into your source repository. Instead let your
build script generate this code on the fly. On the other hand, code generated in the
src
directory is intended for modification by the developer. AndroMDA will
never overwrite code in these directories. It is generated one-time only.
Now that you understand the code that has been generated, it is time to compile it.
In order to avoid adding each individual file to our solution we will perform a neat
trick to make our job easier. We will edit the
TimeTrackerCommon
and
TimeTrackerCore
projects so they will compile all C# files in a specified
folder. Follow the steps below to implement this trick. Note that this "feature" is not
available in VS 2003. You will have to create the src and target directory structures
yourself and add the C# files manually. Also don't forget to add the *.hbm.xml
files as embedded resources.
TimeTrackerCommon.csproj
in a text editor.
<ItemGroup> <CompileInclude="Properties\AssemblyInfo.cs"/> </ItemGroup>
target
directory:
<ItemGroup> <CompileInclude="Properties\AssemblyInfo.cs"/> <CompileInclude="target\TimeTracker\Domain\*.cs"/> </ItemGroup>
TimeTrackerCommon.csproj
.
TimeTrackerCore.csproj
in a text editor.
<ItemGroup> <CompileInclude="Properties\AssemblyInfo.cs"/> </ItemGroup>
src
and
target
directories:
<ItemGroup> <CompileInclude="Properties\AssemblyInfo.cs"/> <CompileInclude="src\TimeTracker\Domain\*.cs"/> <CompileInclude="target\TimeTracker\Domain\*.cs"/> </ItemGroup>
<ItemGroup> <EmbeddedResourceInclude="target\TimeTracker\Domain\*.hbm.xml"/> </ItemGroup>
TimeTrackerCore.csproj
.
Let's implement the convenience methods added to the 3 classes in the diagram shown earlier.
PersonImpl.cs
in the project
TimeTrackerCore
.
Implement
AddTimecard()
as follows:
public override void AddTimecard(TimeTracker.Domain.Timecard timecard)
{
Timecards.Add(timecard);
timecard.Owner = this;
}
TimecardImpl.cs
in the project
TimeTrackerCore
.
Implement
AddTimeAllocation()
as follows:
public override void AddTimeAllocation(TimeTracker.Domain.TimeAllocation timeAllocation)
{
Allocations.Add(timeAllocation);
timeAllocation.Timecard = this;
}
TaskImpl.cs
in the project
TimeTrackerCore
.
Implement
AddTimeAllocation()
as follows:
public override void AddTimeAllocation(TimeTracker.Domain.TimeAllocation timeAllocation)
{
Allocations.Add(timeAllocation);
timeAllocation.Task = this;
}
Let us now add references to the various projects to reflect their dependencies. To add a reference, simply right-click on the project in the Solution Explorer and select Add Reference. Then select the Projects tab to add a reference to an internal project or select the Browse tab to add a reference to an external DLL (for example, a DLL in the Lib directory).
TimeTrackerCore
project. Note that all the DLLs listed below are in the
Lib directory of the TimeTracker solution.
TimeTrackerConsole
project:
SchemaExport
project:
We need to do one more thing before building the application. As part of the initial setup, AndroMDA had generated the NHibernate configuration file for the SchemaExport application. This file needs to be added to the SchemaExport project. Here are the steps to do this.
nhibernate.config
will be visible in
the dialog. Select it and click Add. The file will be added to the project.
nhibernate.config
in Solution Explorer.
copy "$(ProjectDir)nhibernate.config" "$(TargetDir)"
nhibernate.config
file in Visual Studio and change any values
if necessary. For example, if the name of your database is not TimeTracker, then change
the value of the
hibernate.connection.connection_string
property
accordingly.
At this point we are ready to build the solution. Select Build > Build Solution. Visual Studio should be able to build the solution without any errors.
It is now time to create the database schema for TimeTracker entities and relations. Use the SchemaExport application generated by AndroMDA to do this. Here are the steps.
C:\TimeTracker\SchemaExport\bin\Debug
SchemaExport t t
. This will create the
TimeTracker schema in the database.
C:\TimeTracker\SchemaExport\bin\Debug>SchemaExport t t
Usage:
SchemaExport [script] [export]
script=t outputs DDL to the console
export=t exports schema to the database
Example:
SchemaExport t f
Calling CreateDatabase with script = True and export = True...
alter table TIMECARD drop constraint TIMECARD_OWNER_FKC
Unsuccessful: Cannot alter table 'TIMECARD' because this table does not exist in database 'TimeTracker'.
alter table TIME_ALLOCATION drop constraint TIME_ALLOCATION_TASK_FKC
Unsuccessful: Cannot alter table 'TIME_ALLOCATION' because this table does not exist in database 'TimeTracker'.
alter table TIME_ALLOCATION drop constraint TIME_ALLOCATION_TIMECARD_FKC
Unsuccessful: Cannot alter table 'TIME_ALLOCATION' because this table does not exist in database 'TimeTracker'.
drop table TIMECARD
Unsuccessful: Cannot drop the table 'TIMECARD', because it does not exist in the system catalog.
drop table TASK
Unsuccessful: Cannot drop the table 'TASK', because it does not exist in the system catalog.
drop table PERSON
Unsuccessful: Cannot drop the table 'PERSON', because it does not exist in the system catalog.
drop table TIME_ALLOCATION
Unsuccessful: Cannot drop the table 'TIME_ALLOCATION', because it does not exist in the system catalog.
create table TIMECARD (
ID NUMERIC(19,0) IDENTITY NOT NULL,
STATUS INT not null,
BEG_DATE DATETIME not null,
OWNER_FK NUMERIC(19,0) not null,
primary key (ID)
)
create table TASK (
ID NUMERIC(19,0) IDENTITY NOT NULL,
NAME VARCHAR(255) not null,
primary key (ID)
)
create table PERSON (
ID NUMERIC(19,0) IDENTITY NOT NULL,
NAME VARCHAR(255) not null,
RATE_VALUE FLOAT not null,
RATE_UNIT VARCHAR(255) not null,
primary key (ID)
)
create table TIME_ALLOCATION (
ID NUMERIC(19,0) IDENTITY NOT NULL,
BEG_TIME DATETIME not null,
END_TIME DATETIME not null,
TIMECARD_FK NUMERIC(19,0) not null,
TASK_FK NUMERIC(19,0) not null,
primary key (ID)
)
alter table TIMECARD add constraint TIMECARD_OWNER_FKC foreign key (OWNER_FK) references PERSON
alter table TIME_ALLOCATION add constraint TIME_ALLOCATION_TASK_FKC foreign key (TASK_FK) references TASK
alter table TIME_ALLOCATION add constraint TIME_ALLOCATION_TIMECARD_FKC foreign key (TIMECARD_FK) references TIMECARD
It is now time to test all the functionality we have implemented so far using the
TimeTrackerConsole
application. Follow the steps below to do this.
.Factory.newInstance()
to
Factory.newInstance()
(i.e. remove the "." before
Factory
).
The reason for this is that .NET 1.1 and VS 2003 do not support static
classes and hence AndroMDA generates slightly different code for VS 2003.
.Value.Add
to
.Add
(i.e. remove the ".Value" before
.Add
).
The reason for this is that .NET 1.1 and VS 2003 do not support nullable
types and hence AndroMDA generates slightly different code for VS 2003.
AddPerson()
,
AddTask()
,
AddTimecard()
and
ShowData()
.
App.config
and
nhibernate.config
from the directory
C:\TimeTracker\SchemaExport
to
C:\TimeTracker\TimeTrackerConsole
. This will configure the application
to work with NHibernate.
nhibernate.config
will be visible in
the dialog. Select it and click Add. The file will be added to the project.
nhibernate.config
in Solution Explorer.
copy "$(ProjectDir)nhibernate.config" "$(TargetDir)"
C:\TimeTracker\TimeTrackerConsole\bin\Debug
TimeTrackerConsole
. This will display menu.
C:\TimeTracker\TimeTrackerConsole\bin\Debug>TimeTrackerConsole
1. Create Database
2. Add Person
3. Add Task
4. Add Timecard
5. Update Timecard
6. Delete Timecard
7. Show Data
Please make a choice ([h]elp [q]uit): 2
Person Name: Naresh Bhatia
Naresh Bhatia added.
Please make a choice ([h]elp [q]uit): 2
Person Name: Louis Coude
Louis Coude added.
Please make a choice ([h]elp [q]uit): 3
Task Name: Research
Task 1 added: Research
Please make a choice ([h]elp [q]uit): 3
Task Name: Development
Task 2 added: Development
Please make a choice ([h]elp [q]uit): 4
Adding timecard...
Timecard 1 created with 1 allocations
Please make a choice ([h]elp [q]uit): 4
Adding timecard...
Timecard 2 created with 2 allocations
Please make a choice ([h]elp [q]uit): 4
Adding timecard...
Timecard 3 created with 2 allocations
Please make a choice ([h]elp [q]uit): 4
Adding timecard...
Timecard 4 created with 2 allocations
Please make a choice ([h]elp [q]uit): 7
People:
1: Naresh Bhatia, rate=10 USD/hour
2: Louis Coude, rate=10 USD/hour
Tasks:
1: Research
2: Development
Timecards:
1: Naresh Bhatia, Draft, 11/16/2005 5:58:29 PM
1: 11/16/2005 5:58:29 PM, 11/16/2005 6:58:29 PM, Research
2: Naresh Bhatia, Draft, 11/16/2005 5:58:31 PM
2: 11/16/2005 5:58:31 PM, 11/16/2005 6:58:31 PM, Research
3: 11/16/2005 6:58:31 PM, 11/16/2005 7:58:31 PM, Development
3: Louis Coude, Draft, 11/16/2005 5:58:32 PM
4: 11/16/2005 5:58:32 PM, 11/16/2005 6:58:32 PM, Research
5: 11/16/2005 6:58:32 PM, 11/16/2005 7:58:32 PM, Research
4: Louis Coude, Draft, 11/16/2005 5:58:33 PM
6: 11/16/2005 5:58:33 PM, 11/16/2005 6:58:33 PM, Research
7: 11/16/2005 6:58:33 PM, 11/16/2005 7:58:33 PM, Research
Please make a choice ([h]elp [q]uit): q
C:\TimeTracker\TimeTrackerConsole\bin\Debug>
In this tutorial we have shown you how to set up your development environment and build your first .NET application using AndroMDA. But this is just the beginning. You can now use AndroMDA to build your own applications. Try out the various features documented under each .NET cartridge. If you don't find a feature that you need, write yourself a template or an entire cartridge. If you think your work might be useful to other developers, don't forget to contribute it to the AndroMDA project.