-
Notifications
You must be signed in to change notification settings - Fork 8
Introduction App Developers
- You develop your Java application and want to use the power of Model Driven Software Development with UML2.
- You are using the KissMDA cartridges available which are build by one or many cartrige developers.
- You create a Maven project based on KissMDA App Maven archetype: kissmda-maven-app-archetype.
- You configure the KissMDA Maven plugin to use one or many of the available cartridges.
- You model your application with your chosen UML2 tool, like MagicDraw or just plain Eclipse.
- You generate with Maven some of generated sources under target/generated-sources and extend all the codes with your own codes.
- That's it.
- Don't forget to unit test and integration test your codes.
- Important to remember:
- Your UML model is your source code, so handle it with care!
- Your UML model is the first class citizen in your project, so use execellent tools to work with them!
- Never commit generated codes and files into your versioning system! Only commit the real source codes!
- Yes, here we are: kissmda-app-test. This app uses following cartridge: kissmda-cartridges-simple-java
The simple application "kissmda-app-test" consists of just Entity, Service and Exception classes:
From these classes we just want to generate the Java interfaces. What should we do? Let's take a fast look at our Seven Steps to Heaven!
Yes, this is the first step we need to make and here is an example Maven project: kissmda-app-test. To create a new Maven app project we can use the Maven archetype: kissmda-maven-app-archetype.
We choose to use the cartridge kissmda-cartridges-simple-java, which just generates the Java interfaces out of the Entity classes.
- In our pom.xml we need to add kissmda-maven-plugin which takes the UML model and use the given cartridge and generate the source codes. Here is the pom.xml.
- We also need the build-helper-maven-plugin which takes the target directory (target/generated-sources/java) and add it into the compiler source directory, so that we can compile the generated classes.
As we see above, the class diagram is just very simple.
- We use MagicDraw to create our UML model. Here is the location of the model file: test-uml.mdzip
- We need to export the MagicDraw model into EMF UML2 file in this directory: emf. This is the file which will be read by the cartridge: test-uml.uml
- We need to know how to mark our model with Stereotypes and Tagged Values. In our example just take a look at this file: Readme of kissmda-cartridges-simple-java.
- Just use mvn generate-sources to generate the codes.
- Don't forget this: never ever put the generated files into the versioning system (Git, SVN)!
- In Maven we have "target" directory. Our generated Java source codes can be found in this standard Maven directory: target/generated-sources/java.
- We generate all the UML documentations to each class, property and method as Javadoc elements. For sake of clarity we don't show the Javadocs in the files generated below.
- We also optimize the import statements (please see: kissmda-extensions-import-packer). We omit the import statements in the example below for clarity.
- Here is our generated Java Interface code for the Person Entity:
package de.crowdcode.kissmda.testapp;
public interface Person {
Integer calculateAge();
Date[] run(byte[] content);
void changeLastAddress(Address address, Boolean isLastOne);
Collection<Company> calculateOldCompanies();
String getName();
void setName(String name);
Collection<Address> getAddresses();
void addAddress(Address address);
Company getCompany();
void setCompany(Company company);
Set<Address> getNewAddresses();
void addNewAddress(Address newAddress);
String getNickname();
Collection<Company> getHiddenCompanies();
Boolean isInRetirement();
Collection<Company> getOldCompanies();
}
- Here is our generated Java Interface code for the Address Entity:
package de.crowdcode.kissmda.testapp;
public interface Address {
Address getOldAddress();
Collection getOldAddresses();
Collection<String> getNewAddresses();
String getStreet();
void setStreet(String street);
Person getPerson();
void setPerson(Person person);
AddressType getAddressType();
void setAddressType(AddressType addressType);
SortedSet<Person> getNewPersons();
void addNewPerson(Person newPerson);
boolean isOld();
void setOld(boolean old);
AddressSimpleType getAddressSimpleType();
void setAddressSimpleType(AddressSimpleType addressSimpleType);
AddressComplexType getAddressComplexType();
void setAddressComplexType(AddressComplexType addressComplexType);
}
- Here is our generated Java Enumeration for the AddressSimpleType Enumeration:
package de.crowdcode.kissmda.testapp;
public enum AddressSimpleType {
HOME, OFFICE, UNDEFINED
}
- Here is our generated Java Enumeration for the AddressType Enumeration:
package de.crowdcode.kissmda.testapp;
public enum AddressType {
HOME(1), OFFICE(2);
Integer type;
private AddressType(Integer type) {
this.type = type;
}
public Integer getType() {
return type;
}
}
- Here is our generated Java Enumeration for the AddressComplexType Enumeration:
package de.crowdcode.kissmda.testapp;
public enum AddressComplexType {
HOME(1, "Aloha", "Lofi"), OFFICE(2, "no comment", "KissMDA");
Integer type;
String comment;
String name;
private AddressComplexType(Integer type, String comment, String name) {
this.type = type;
this.comment = comment;
this.name = name;
}
public Integer getType() {
return type;
}
public String getComment() {
return comment;
}
public String getName() {
return name;
}
}
- Here is our generated Java Interface code for the AddressService Service:
package de.crowdcode.kissmda.testapp;
public interface AddressService {
void createAddressFromPerson(Address address, Person person)
throws CreateAddressException, CreatePersonException;
}
- Here is our generated Java Interface code for the PrivateAddressService Service:
package de.crowdcode.kissmda.testapp;
public interface PrivateAddressService extends AddressService {
void createPrivateAddressFromPerson(Address privateAddress, Person person);
Company getPrivateCompanyByPerson(Person person,
PrivateCompany privateCompany) throws FinderException;
Collection<Company> getCompanies(
SortedSet<CompanyAttribute<String, Integer>> companyAttributes);
}
- Here is our generated Java Interface code for the Company Entity:
package de.crowdcode.kissmda.testapp.components;
public interface Company {
<T> void defineCompany(Collection<T> owners, T owner);
Collection<Company> calculateCompanies(Collection<Company> companies,
Collection<Person> persons);
String getName();
void setName(String name);
double getValue();
void setValue(double value);
Date getCreated();
void setCreated(Date created);
CompanyAttribute<String, Integer> getCompanyAttribute();
void setCompanyAttribute(CompanyAttribute<String, Integer> companyAttribute);
Person getVirtualPerson();
Collection<Person> getOldPersons();
void setOldPersons(Collection<Person> oldPersons);
HeadquarterOffice getHeadquarterOffice();
void setHeadquarterOffice(HeadquarterOffice headquarterOffice);
}
- Here is our generated Java Interface code for the PrivateCompany Entity:
package de.crowdcode.kissmda.testapp;
public interface PrivateCompany extends Company {
Integer calculateRevenue();
SortedSet<CompanyAttribute<String, Integer>> calculateCompanies(
Collection<CompanyAttribute> companyAttributes,
Set<CompanyAttribute<String, Integer>> companyCompleteAttributes);
String getOwner();
void setOwner(String owner);
Collection<Company> getCompanies();
void addCompany(Company company);
SortedSet<CompanyAttribute<String, Integer>> getCompanyAttributes();
void addCompanyAttribute(CompanyAttribute<String, Integer> companyAttribute);
}
- Here is our generated Java Interface code for the HeadquarterOffice Entity:
package de.crowdcode.kissmda.testapp;
public interface HeadquarterOffice {
Collection<Company> getCompanies();
void addCompany(Company company);
String getName();
void setName(String name);
}
- Here is our generated Java Interface code for the CompanyAttribute Entity:
package de.crowdcode.kissmda.testapp.components;
public interface CompanyAttribute<T, E> {
void add(T element1, E element2);
String getName();
void setName(String name);
}
- Here are our generated Exception Classes code for CreateException, CreateAddressException, CreatePersonException and FinderException:
package de.crowdcode.kissmda.testapp.exceptions;
public class CreateException extends Exception {
private static final long serialVersionUID = 1L;
public CreateException() {
}
public CreateException(Throwable cause) {
super(cause);
}
public CreateException(String message) {
super(message);
}
public CreateException(String message, Throwable cause) {
super(message, cause);
}
}
package de.crowdcode.kissmda.testapp.exceptions;
public class CreateAddressException extends de.crowdcode.kissmda.testapp.exceptions.CreateException {
private static final long serialVersionUID = 1L;
public CreateAddressException() {
}
public CreateAddressException(Throwable cause) {
super(cause);
}
public CreateAddressException(String message) {
super(message);
}
public CreateAddressException(String message, Throwable cause) {
super(message, cause);
}
}
package de.crowdcode.kissmda.testapp.exceptions;
public class CreatePersonException extends de.crowdcode.kissmda.testapp.exceptions.CreateException {
private static final long serialVersionUID = 1L;
public CreatePersonException() {
}
public CreatePersonException(Throwable cause) {
super(cause);
}
public CreatePersonException(String message) {
super(message);
}
public CreatePersonException(String message, Throwable cause) {
super(message, cause);
}
}
package de.crowdcode.kissmda.testapp.exceptions;
public class FinderException extends RuntimeException {
private static final long serialVersionUID = 1L;
public FinderException() {
}
public FinderException(Throwable cause) {
super(cause);
}
public FinderException(String message) {
super(message);
}
public FinderException(String message, Throwable cause) {
super(message, cause);
}
}
- Write the Java classes which implement the generated interfaces, just like this.
- Don't forget to write the test, just like this
Yes, this is the reality: you always have up-to-date documentation on a very high level and your generated codes look beautiful!. This means you will have a very good overview about your application at any time!