31st October, 2011 - Posted by rafael.chaves - 3 Comments
Can you tell this code was fully generated from a UML model?
This is all live in AlphaSimple – every time you hit those URLs the code is being regenerated on the fly. If you are curious, the UML model is available in full in the TextUML’s textual notation, as well as in the conventional graphical notation. For looking at the entire project, including the code generation templates, check out the corresponding AlphaSimple project.
Preconditions
Operation preconditions impose rules on the target object state or the invocation parameters. For instance, for making a deposit, the amount must be a positive value:
operation deposit(amount : Double);
precondition (amount) { return amount > 0 }
begin
...
end;
which in Java could materialize like this:
public void deposit(Double amount) {
assert amount > 0;
...
}
Not related to preconditions, another case assertions can be automatically generated is if a property is required (lowerBound > 0):
public void setNumber(String number) {
assert number != null;
...
}
Imperative behavior
In order to achieve 100% code generation, models must specify not only structural aspects, but also behavior (i.e. they must be executable). For example, the massAdjust class operation in the model is defined like this:
static operation massAdjust(rate : Double);
begin
Account extent.forEach((a : Account) {
a.deposit(a.balance*rate)
});
end;
which in Java results in code like this:
public static void massAdjust(Double rate) {
for (Account a : Account.allInstances()) {
a.deposit(a.getBalance() * rate);
};
}
Derived properties
Another important need for full code generation is proper support for derived properties (a.k.a. calculated fields). For example, see the Account.inGoodStanding derived attribute below:
derived attribute inGoodStanding : Boolean := () : Boolean {
return self.balance >= 0
};
which results in the following Java code:
public Boolean isInGoodStanding() {
return this.getBalance() >= 0;
}
Set processing with higher-order functions
Any information management application will require a lot of manipulation of sets of objects. Such sets originate from class extents (akin to “#allInstances” for you Smalltalk heads) or association traversals. For that, TextUML supports the higher-order functions select (filter), collect (map) and reduce (fold), in addition to forEach already shown earlier. For example, the following method returns the best customers, or customers with account balances above a threshold:
static operation bestCustomers(threshold : Double) : Person[*];
begin
return
(Account extent
.select((a:Account) : Boolean { return a.balance >= threshold })
.collect((a:Account) : Person { return a->owner }) as Person);
end;
which even though Java does not yet support higher-order functions, results in the following code:
public static Set<Person> bestCustomers(Double threshold) {
Set<Person> result = new HashSet<Person>();
for (Account a : Account.allInstances()) {
if (a.getBalance() >= threshold) {
Person mapped = a.getOwner();
result.add(mapped);
}
}
return result;
}
which demonstrates the power of select and collect. For an example of reduce, look no further than the Person.totalWorth attribute:
derived attribute totalWorth : Double := () : Double {
return (self<-PersonAccounts->accounts.reduce(
(a : Account, partial : Double) : Double { return partial + a.balance }, 0
) as Double);
};
which (hopefully unsurprisingly) maps to the following Java code:
public Double getTotalWorth() {
Double partial;
partial = 0;
for (Account a : this.getAccounts()) {
partial = partial + a.getBalance();
}
return partial;
}
Would you hire AlphaSimple?
Would you hire a developer if they wrote Java code like AlphaSimple produces? For one thing, you can’t complain about the guy not being consistent.
Do you think the code AlphaSimple produces needs improvement? Where?
Want to try by yourself?
There are still some bugs in the code generation that we need to fix, but overall the “POJO” target platform is working quite well. If you would like to try by yourself, create an account in AlphaSimple and to make things easier, clone a public project that has code generation enabled (like the “AlphaSimple” project).
Read More
28th September, 2011 - Posted by rafael.chaves - 9 Comments
I prepared the following slides for my Eclipse DemoCamp presentation on AlphaSimple but ended up not having time to cover them. The goal was not to try to convert the audience, but to make them understand where we are coming from, and why AlphaSimple is the way it is.
And here they are again for the sake of searchability:
I – Enterprise Software is much harder than it should be, lack of separation of concerns is to blame.
II – Domain and architectural/implementation concerns are completely different beasts and should be addressed separately and differently.
III – What makes a language good for implementation makes it suboptimal for modeling, and vice-versa.
IV – Domain concerns can and should be fully addressed during modeling, implementation should be a trivial mapping.
V – A model that fully addresses domain concerns will expose gaps in requirements much earlier.
VI – A model that fully addresses domain concerns allows the solution to be validated much earlier.
VII – No modeling language is more understandable to end-users than a running application (or prototype).
VIII – A single architecture can potentially serve applications of completely unrelated domains.
IX – A same application can potentially be implemented according to many different architectures.
X – Implementation decisions are based on known guidelines applied consistently throughout the application, and beg for automation.
XI – The target platform should not dictate the development tools, and vice-versa.
I truly believe in those principles, and feel frustrated when I realize how far the software industry is from abiding by them.
So, what do you think? Do you agree these are important principles and values? Would you call B.S. on any of them? What are your principles and values that drive your vision of what software development should look like?
Read More
29th August, 2011 - Posted by rafael.chaves - 6 Comments
Executable models, as the name implies, are models that are complete and precise enough to be executed. One of the key benefits is that you can evaluate your model very early in the development life cycle. That allows you to ensure the model is generally correct and satisfies the requirements even before you have committed to a particular implementation platform.
One way to perform early validation is to automatically generate a prototype that non-technical stakeholders can play with and (manually) confirm the proposed model does indeed satisfy their needs (like this).
Another less obvious way to benefit from executable models since day one is automated testing.
The requirements
For instance, let’s consider an application that needs to deal with money sums:
- REQ1: a money sum is associated with a currency
- REQ2: you can add or subtract two money sums
- REQ3: you can convert a money sum to another currency given an exchange rate
- REQ4: you cannot combine money sums with different currencies
The solution
A possible solution for the requirements above could look like this (in TextUML):
package money;
class MixedCurrency
end;
class Money
attribute amount : Double;
attribute currency : String;
static operation make(amount : Double, currency : String) : Money;
begin
var m : Money;
m := new Money;
m.amount := amount;
m.currency := currency;
return m;
end;
operation add(another : Money) : Money;
precondition (another) raises MixedCurrency { return self.currency = another.currency }
begin
return Money#make(self.amount + another.amount, self.currency);
end;
operation subtract(another : Money) : Money;
precondition (another) raises MixedCurrency { return self.currency = another.currency }
begin
return Money#make(self.amount - another.amount, self.currency);
end;
operation convert(anotherCurrency : String, exchangeRate : Double) : Money;
begin
return Money#make(self.amount * exchangeRate, anotherCurrency);
end;
end;
end.
Now, did we get it right? I think so, but don’t take my word for it.
The proof
Let’s start from the beginning, and ensure we satisfy REQ1 (a money sum is a pair <amount, currency>:
[Test]
operation testBasic();
begin
var m1 : Money;
m1 := Money#make(12, "CHF");
Assert#assertEquals(12, m1.amount);
Assert#assertEquals("CHF", m1.currency);
end;
It can’t get any simpler. This test shows that you create a money object providing an amount and a currency.
Now let’s get to REQ2, which is more elaborate – you can add and subtract two money sums:
[Test]
operation testSimpleAddAndSubtract();
begin
var m1 : Money, m2 : Money, m3 : Money, m4 : Money;
m1 := Money#make(12, "CHF");
m2 := Money#make(14, "CHF");
m3 := m1.add(m2);
Assert#assertEquals(26, m3.amount);
Assert#assertEquals("CHF", m3.currency);
/* if m1 + m2 = m3, then m3 - m2 = m1 */
m4 := m3.subtract(m2);
Assert#assertEquals(m1.amount, m4.amount);
Assert#assertEquals(m1.currency, m4.currency);
end;
We add two values, check the result, them subtract one of them from the result and expect the get the other.
REQ3 is simple as well, and specifies how amounts can be converted across currencies:
[Test]
operation testConversion();
begin
var m1 : Money, result : Money;
m1 := Money#make(3, "CHF");
result := m1.convert("USD", 2.5);
Assert#assertEquals(7.5, result.amount);
Assert#assertEquals("USD", result.currency);
end;
We ensure conversion generates a Money object with the right amount and the expected currency.
Finally, REQ4 is not a feature, but a constraint (currencies cannot be mixed), so we need to test for rule violations:
[Test]
operation testMixedCurrency();
begin
try
Money#make(12, "CHF").add(Money#make(14, "USD"));
/* fail, should never get here */
Assert#fail("should have failed");
catch (expected : MixedCurrency)
/* success */
end;
end;
We expect the operation to fail due to a violation of a business rule. The business rule is identified by an object of a proper exception type.
There you go. Because we are using executable models, even before we decided what implementation platform we want to target, we already have a solution in which we have a high level of confidence that it addresses the domain-centric functional requirements for the application to be developed.
Can you say “Test-driven modeling”?
Imagine you could encode all non-technical functional requirements for the system in the form of acceptance tests. The tests will run against your models whenever a change (to model or test) occurs. Following the Test-Driven Development approach, you alternate between encoding the next requirement as a test case and enhancing the model to address the latest test added.
Whenever requirements change, you change the corresponding test and you can easily tell how the model must be modified to satisfy the new requirements. If you want to know why some aspect of the solution is the way it is, you change the model and see the affected tests fail. There is your requirement traceability right there.
See it by yourself
Would you like to give the mix of executable modeling and test-driven development a try? Sign up to AlphaSimple now, then open the public project repository and clone the “Test Infected” project (or just view it here).
P.S.: does this example model look familiar? It should – it was borrowed from “Test Infected: Programmers Love Writing Tests“, the classical introduction to unit testing, courtesy of Beck, Gamma et al.
Read More
1st August, 2011 - Posted by rafael.chaves - 5 Comments
We would like to support automated testing of templates in AlphaSimple projects. I have been “test-infected” for most of my career, and the idea of writing code generation templates that are verified manually screams “unsustainable” to me. We need a cheap and easily repeatable way of ensuring code generation templates produce what they intend to produce.
Back-of-a-napkin design for code generation testing:
- by convention, for each test case, declare two transformations: one will hardcode the expected results, and another will trigger the transformation to test with some set of parameters (typically, an element of a model). We can pair transformations based on their names: “expected_foo” and “actual_foo” for a test case named “foo”
- if the results are identical, the test passes; otherwise, the test fails (optionally, use a warning for the cases where the only differences are around layout, i.e., non significant chars like spaces/newlines – optionally, because people generating Python code will care about layout)
- just as we do for model test failures, report template test failures as build errors
- run template tests after model tests, and only if those pass
- (cherry on top) report text differences in a sane way (some libraries out there can do text diff’ng)
Does that make sense? Any suggestions/comments (simpler is better)? Have you done or seen anything similar?
Read More
30th July, 2011 - Posted by rafael.chaves - 15 Comments
Is the purpose of an analysis model understanding the problem or proposing a solution? I have discussed this a few times with different people. This is how I used to see it:
- Analysis deals with understanding the problem domain and requirements in detail
- Design deals with actually addressing those (functional and non-functional) requirements
- A detailed design model can be automatically transformed into a working implementation
- An analysis model can’t, as in the general case, it is not possible to automatically derive a solution based on the statement of a problem.
Rumbaugh, Blaha et al in “Object-oriented modeling and design” (one of the first OO modeling books) state the purpose of analysis in OO is to model the real-world system so it can be understood; and the outcome of analysis is understanding the problem in preparation for design.
Jacobson, Booch and Rumbaugh (again, now with the other “two amigos”) in “The unified software development process” state that “an analysis model yields a more precise specification of the requirements than we have in the results from requirements capture” and “before one starts to design and implement, one should have a precise and detailed understanding of the requirements”.
Ok, so I thought I was in good company there. However, while reading the excellent “Model-based development: applications“, to my great surprise, H. S. Lahman clearly states that contrary to structured development, where the focus of analysis is problem analysis, in the object-oriented paradigm, problem analysis is done during requirements elicitation, and the goal of object-oriented analysis is to specify the solution in terms of the problem space, addressing functional requirements only, in a way that is independent of the actual computing environment. Also, Lahman states that the OOA model is the same as the platform-independent model (PIM) in MDA lingo, so it can actually be automatically translated into running code.
That is the first time I have seen this position defended by an expert. I am not familiar with the Shlaer-Mellor method, but I won’t be surprised if it has a similar view of analysis, given that Lahman’s method is derived from Shlaer-Mellor. Incidentally, Mellor/Balcer’s “Executable UML: a foundation for model-driven architecture” is not the least concerned with the software lifecycle, briefly mentions use cases as a way of textually gathering requirements, and focuses heavily on solution modeling.
My suspicion is that for the Shlaer-Mellor/Executable UML camp, since models are fully executable, one can start solving the problem (in a way that is removed from the actual concrete implementation) since the very beginning, so there is nothing to be gained by strictly separating problem from a high-level, problem-space focused solution. Of course, other aspects of the solution, concerned with non-functional requirements or somehow tied with the target computing environment, are still left to be addressed during design.
And now I see how that all makes sense – I struggled myself with how to name what you are doing when you model a solution in AlphaSimple. We have been calling it design based on the more traditional view of analysis vs. design – since AlphaSimple models specify a (highly abstract) solution, it couldn’t be analysis. But now I think I understand: for approaches based on executable modeling, the divide between understanding the problem and specifying a high-level solution is so narrow and so cheap to cross, that both activities can and should be brought closer together, and the result of analysis in approaches based on executable modeling is indeed a model that is ready to be translated automatically into a running application (and can be quickly validated by the customer).
But for everybody else (which is the vast majority of software development practitioners – executable modeling is still not well known and seldom practiced) that is just not true, and the classical interpretation still applies: there is value in thoroughly understanding the requirements before building a solution, given that the turnaround between problem comprehension, solution building and validation is so damn expensive.
For those of you thinking that this smells of BigDesignUpFront, and that is not an issue with agile or iterative approaches in general – I disagree. At least as far as typical iterative approaches go, where iterations need to comprise all/several phases of the software development life cycle so they can finally deliver results that can be validated by non-technical stakeholders. As such they are still very wasteful (the use of the word agile feels like a bad joke to me).
Approaches based on executable modeling, on the other hand, greatly shrink the chasm between problem analysis and conceptual solution modeling and user acceptance, allowing for much more efficient and seamless collaboration between the problem domain expert and the solution expert. Iterations become so action packed that they are hardly discernible. Instead of iterations taking weeks to allow for customer feedback, and a project taking months to fully cover all functional requirements, you may get a fully specified solution after locking a customer and a modeler in a boardroom for just a day, or maybe a week for bigger projects.
So, long story short, to answer the question posed at the beginning of this post, the answer is both, but only if you are following an approach based on executable modeling.
What is your view? Do you agree with that? Are you an executable modeling believer or skeptic?
UPDATE: make sure to check the thread on Google+ as well.
Read More
21st May, 2011 - Posted by rafael.chaves - 1 Comment
This coming Thursday I will be doing a presentation entitled “Code generation – going all the way” to the Vancouver Island Java User Group.
The plan is to take the audience from the most basic ideas around generating code from models, visiting approaches increasingly more sophisticated, analyzing their pros and cons, all the way to full code generation based on executable models.
In the process, we will be taking a cursory look at some code generation tools in the market, culminating with a preview of the upcoming release of AlphaSimple, our online modeling tool, which will support executable modeling and full code generation.
What:
May 2011 VIJUG Meeting – Code generation: going all the way (official announcement)
Where:
Vancouver Island Technology Park, Conference Center Room – 4464 Markham Street, Victoria, BC
When:
Thursday, 26th May 2011, 18:00-20:00
If you are in Victoria and think developing business applications got just way too complicated and labor-intensive, and that there must be a saner way to build and evolve them (no matter what platforms you use), come to this presentation and learn how executable models and full code generation can fix that.
Read More
15th May, 2011 - Posted by rafael.chaves - 2 Comments
Smalltalk, Ruby, Groovy and other languages allow one to implement loops using closures. But so does TextUML/UML. Given the primary use case of TextUML/UML is to generate code, one thorny question is how to generate code from a UML model using closures for implementing loops through collections into a language, like Java or C, just as one would normally write loops over collections in those closure-free languages.
Here are some examples of how to translate from closure-based loops (in TextUML, but the specific syntax shouldn’t matter) to ordinary loops (in Java, but again, syntax specifics shouldn’t matter):
forEach
In TextUML
self->units.forEach((u : Unit) {
link ProjectUnits(project := clone, units := u.clone()) }
);
In Java
for (Unit u : this.getUnits()) {
clone.addUnits(u.clone());
}
select
In TextUML
return Project extent.select((p : Project) : Boolean { return p.shared });
In Java
Set<Project> result = new HashSet<Project>();
for (Project p : Project.allInstances()) {
if (p.isShared()) {
result.add(p);
}
}
return result;
collect
In TextUML
return Project extent.collect((p : Project) : User { return p->owner });
In Java
Set<User> result = new HashSet<User>();
for (Project p : Project.allInstances()) {
User owner = p.getOwner();
result.add(owner);
}
return result;
count
In TextUML
return Project extent.count((p : Project) : Boolean { return p.shared });
In Java
int count = 0;
for (Project p : Project.allInstances()) {
if (p.isShared()) {
count++;
}
}
return count;
In AlphaSimple, we got much of what is needed above in place. There are though some additional challenges posed by the need of chaining those collection primitives, and the need for mapping the data flow that chains them together to an unchained form, using local variables in the target language. These last two aspects have been keeping me awake at night. If you feel like throwing a light (with strategies, references) on how to address that, by all means go for it, it is pretty dark in here right now… 
Read More
18th April, 2011 - Posted by rafael.chaves - 5 Comments
Not clear on what AlphaSimple is about? Isn’t the value we aim to provide clear?
Does this 7-slide pitch deck (including title) help you understand it?
If not, please let us know. Or if it is clear, but you don’t think it would work, please help us understand why. Or even if you think it is right on the money, some reassurance is always welcome.
Note that the web site hasn’t yet changed to reflect the more recent focus on code generation that the slide deck hints at (in addition to the existing focus on requirements and solution design validation). That is on our to-do list. Expect significant changes (messaging and service features) this Spring.
This is the inaugural post on the “business of software” category. Expect many more in the future as we work on turning AlphaSimple into a product that fulfills our mission: to bring model-driven development to the masses, and stopping hordes of developers from writing so much code. Stay tuned.
Read More
6th March, 2011 - Posted by rafael.chaves - No Comments
This just in: you can now generate code for AlphaSimple projects from within your Maven-based project build! That gives you a convenient way of getting the code generated by AlphaSimple into your (and your teammates’) development environment, or in your automated builds.
How do you do that? Let’s see.
Step 0: create your model(s) and template(s)
You must have an existing project in AlphaSimple. This was the subject of a previous post. Read it first if you don’t know how to create models and templates in AlphaSimple. Make sure your project is shared.
Feeling lazy?
Okay… just copy and paste the pom definition from this file into your pom.xml. You can skip down to step 3, and it will work out of the box (generating code from a pre-existing shared project).
Step 1: Enable the Abstratt repository
<project ...>
...
<pluginRepositories>
...
<pluginRepository>
<id>abstratt</id>
<name>Abstratt Technologies Maven repository</name>
<url>http://abstratt.com/maven/</url>
</pluginRepository>
...
</pluginRepositories>
...
<project>
This is required because the AlphaSimple Maven plug-in is not available from Maven Central or other public repository (yet).
Step 2: Include the AlphaSimple Maven plugin in your pom.xml
<project ...>
...
<build>
...
<plugins>
...
<plugin>
<groupId>com.abstratt</groupId>
<artifactId>com.abstratt.alphasimple.mojo</artifactId>
<version>1.0-SNAPSHOT</version>
<configuration>
<uri>http://alphasimple.com/mdd/generator/rafael-276/simple</uri>
<targetRoot>${project.build.directory}/generated-src/main/java</targetRoot>
</configuration>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>
...
</plugins>
...
</build>
...
</project>
Which in summary is executing the generate goal of the AlphaSimple plugin during the generate-sources phase of the Maven lifecycle.
In the example above, the plug-in is configured to execute the generator at http://alphasimple.com/mdd/generator/rafael-276/simple, for the AlphaSimple sample project (see this post for how to obtain a similar URI for your own project).
Also, files will be generated at the specified location (which in the example above will map to target/generated-src/main/java). In order for them to be seen by the Java compiler, that location must be configured as a source directory, for instance, by specifying a non-standard source location in your module:
<project ...>
...
<build>
...
<sourceDirectory>${project.build.directory}/generated-src/main/java</sourceDirectory>
...
</build>
...
</project>
Step 3: run Maven
mvn clean generate-sources
will get you something like this:
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building AlphaSimple Code Generation example 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.3:clean (default-clean) @ com.alphasimple.examples.pojo ---
[INFO] Deleting file set: C:\dev\com.alphasimple.examples.pojo\target (included: [**], excluded: [])
[INFO]
[INFO] --- com.abstratt.alphasimple.mojo:1.0-SNAPSHOT:generate (default) @ com.alphasimple.examples.pojo ---
[INFO] Generating at C:\dev\com.alphasimple.examples.pojo\target\generated-src\main\java\alphasimple\Project.java
[INFO] Generating at C:\dev\com.alphasimple.examples.pojo\target\generated-src\main\java\alphasimple\Session.java
[INFO] Generating at C:\dev\com.alphasimple.examples.pojo\target\generated-src\main\java\alphasimple\Unit.java
[INFO] Generating at C:\dev\com.alphasimple.examples.pojo\target\generated-src\main\java\alphasimple\User.java
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.486s
[INFO] Finished at: Sun Mar 06 16:48:36 PST 2011
[INFO] Final Memory: 2M/58M
[INFO] ------------------------------------------------------------------------
The generate-sources phase or any other phase that follows (such as compile, package, install etc see lifecycle reference) will cause the code to be regenerated. As you make changes to your models or templates in AlphaSimple, further runs of the generate goal will take those changes into account.
In the case of generating Java code, you will want to include at least the compile phase so you can tell whether the generated code is valid (if you get an error about generics not allowed in source level 3, see this).
What just happened?
The AlphaSimple Maven plugin does not know how to generate code, nor has dependencies on other Maven artifacts that do. All it does is to hit the code generation endpoint in the AlphaSimple REST API, and request code to be generated for the chosen target platform. It then just extracts that ZIP stream into the chosen location in the file system.
Conclusion
Once you create your models and templates in AlphaSimple (see previous post), it is very easy to include the generated code in your Maven-based projects. All you need to do is to include an execution of the AlphaSimple plug-in and point it to the generator of your choice. It is that easy. But don’t take our word for it, try it yourself and give us your opinion!
Read More
23rd February, 2011 - Posted by rafael.chaves - No Comments
We just released a new build of AlphaSimple with basic support for customized code generation using templates, more specifically, using StringTemplate templates. Let’s take a quick tour:
Create a model in AlphaSimple
Create your model in AlphaSimple. If you need help with the notation, check the tutorial. You can just start with the default contents you get when creating a new project:
package NewProject;
class NewProject
/* attributes */
attribute text : String;
attribute check : Boolean;
attribute number : Integer[0,1];
attribute date : Date[0,1];
/* relationships */
/* actions */
operation toggle();
begin
self.check := not self.check;
end;
/* queries */
end;
end.
Remember to save your file.
Create a template
AlphaSimple supports StringTemplate as template language (check out this 5-minute introduction). In order to define a template in your AlphaSimple project, create a file with the .stg extension (in StringTemplate lingo, it is a template group file). You can use the example below, which for every class in a model, creates a text file that shows its name, and the names of its attributes and operations:
group simple;
outputPath(class) ::= <<
<! The 'outputPath' template is optional and determines the path of the file generated (the default is the class name) !>
<class.name>.txt
>>
contents(class) ::= <<
<! The 'contents' template is mandatory and is the entry point for generating the contents of the file from a class. !>
Class: <class.name>
Attributes: <class.ownedAttributes:{attr|<attr.name>};separator=", ">
Operations: <class.ownedOperations:{op|<op.name>};separator=", ">
>>
Again, remember to save this file.
Declare your custom template
To enable custom templates, you need to create an AlphaSimple configuration file (mdd.properties). It is a configuration file that drives the compiler and code generation in AlphaSimple. Your file can be as simple as this:
# the template implementation we use
mdd.target.engine=stringtemplate
# the templates supported (always mdd.target.<name>.template=<template file name>
mdd.target.simple.template=simple.stg
Both entries are mandatory. Ensure the line declaring the template matches the name you chose when creating the template file. Save this file.
Test your template
In order to test your custom template, if you have been using a guest account, you will need to sign up first (it’s free). Your project contents will be preserved.
First, publish your project (see button in the editor). Then, from your list of projects (“My Projects”), share your project (open lock button). For any future modifications to model, template or configuration file, you will need to publish your changes again. This will not be required in the future.
We are almost there. Since there is no UI for triggering custom generation yet, you will need to use the REST API, which is quite easy. Find out the numeric id of your project (from any link pointing to it). Then hit a URI with this shape:
http://alphasimple.com/mdd/publisher/<username>-<project-id>/
For instance, for project 515, belonging to user simple, the URI would be:
http://alphasimple.com/mdd/publisher/simple-515/
which returns:
<workspace packageCount='1' timestamp='1298449947000'>
<model name='NewProject.uml'
uri='http://alphasimple.com/mdd/publisher/simple-515/NewProject.uml?secret='
graph='http://alphasimple.com/mdd/diagram/simple-515/NewProject.uml?secret='/>
<properties name='mdd.properties' uri='http://alphasimple.com/mdd/publisher/simple-515/mdd.properties?secret='/>
<source name='NewProject' uri='http://alphasimple.com/mdd/publisher/simple-515/NewProject?secret='/>
<source name='simple.stg' uri='http://alphasimple.com/mdd/publisher/simple-515/simple.stg?secret='/>
<generator platform="jpa" uri="http://alphasimple.com/mdd/generator/simple-515/jpa?secret="/>
<generator platform="pojo" uri="http://alphasimple.com/mdd/generator/simple-515/pojo?secret="/>
<generator platform="simple" uri="http://alphasimple.com/mdd/generator/simple-515/simple?secret="/>
<renderer uri="http://alphasimple.com/animator/index.jsp?repository=simple-515#"/>
</workspace>
which gives you access to all the objects that AlphaSimple project has: source files (model and template), the configuration file, the generated UML model and corresponding class diagram, and, what we are mostly interested here, all generators available. Note that it includes not only a generator for the custom template, but some other built-in generators as well. But lets ignore those for now, and open the generator URI for our custom template (named “simple”). Voila, this is what you should see:
Class: NewProject
Attributes: text, check, number, date
Operations: toggle
Conclusion
We hope this very simple example gave you an idea of how you can generate code from UML models using AlphaSimple and StringTemplate (even if it doesn’t really generate actual code). In the example template, we only navigate from a class to its operations and attributes, and access their names, but your template has virtually any information from the underlying UML model available to generate from.
If you would like to see more interesting models and actual code generation templates, browse the shared project area. For now, there is currently just one project with an elaborate template. Clone it and model (and generate) away. If you have any feedback, just post a comment here or check the AlphaSimple contact page.
Read More
6th February, 2011 - Posted by rafael.chaves - 10 Comments
Last November I did a lecture on Model-driven Development with Executable UML models to a class of Software Engineering undergrad students at UVic. Here are the slides:
I think it gives a good summary of my views on model driven development (with Executable UML or not):
- even though problem domains are typically not very complex, enterprise software is complex due to the abundance of secondary crosscutting concerns (persistence, concurrency, security, transactions etc)
- there are two dominant dimensions in enterprise software: business domain concerns and technological concerns
- they are completely different in nature (change rate, abstraction level) and require different approaches (tools, skills, reuse)
- MDD is a strategy that handles well that divide: models address business domain concerns, PIM->PSM transformation addresses technological concerns
- brainstorming, communication, documentation and understanding (rev. engineering) are not primary goals of MDD – to produce running code in a productive and rational way is
- models in MDD must be well-formed, precise, complete, executable, technology independent
- graphical representations are not suitable for executable modeling (textual notations are much better)
- diagrams != models, text != code (that would look good on a t-shirt!)
I guess those who know me won’t have seen anything new above (these ideas make the very foundations of the TextUML Toolkit and AlphaSimple).
Do you agree with those positions?
Read More
5th February, 2011 - Posted by rafael.chaves - No Comments
One thing that may be confusing for someone trying AlphaSimple for the first time is the fact that for any given project (for non-guest users), there is always two working areas: a test area, and a published area:

- the test area is rebuilt from scratch every time you save your project. When you hit the “Test” button, the prototype you are running is generated based on the test model area. It reflects your latest changes (at the time you hit Test). The URL for the prototype based off of the test area has a “run” segment (http://alphasimple.com/project/run/<id>).
- the published area is only refreshed when you hit Publish. In order to run the prototype off of the published area, you hit “View Published”. Any changes you make to your model will *not* affect the published model/prototype. The URL for the prototype based off of the published area has a “published” segment (http://alphasimple.com/project/published/<id>).
Imagine the published area as a snapshot of your work that you would want others (business analysts, customers, other modelers) to see, while the test area is what you use for your own testing on an ongoing basis as you develop your model. Guest (non-registered) users just quickly trying AlphaSimple anonymously have only the test area.
Shared projects
A mostly orthogonal concept is shared projects. A project that is shared appears in the Shared Projects page in AlphaSimple, and anyone can run the prototype, browse your model (including a graphical view), and even copy your project and make it their own. Any registered user can share their projects. In fact, there is currently a limit of 3 non-shared projects. As you can guess, we want to encourage users to share their models.
You may be asking: “what is the relationship between shared projects and working areas?”. It is simple: what you see when looking at a shared project is the published state of that project. So for a shared project of yours, if you want to affect what is seen on the shared projects page, you need to publish your model (in addition to sharing the project). Actually, there is a bug in that if you don’t ever publish a shared project, trying to run or view it from the Shared Projects page will fail (we should be automatically publishing the model when a project is first shared, or hide shared projects until they are effectively published).
Does all this make sense? Let us know if it doesn’t, either by commenting here or by starting a thread on the community forum.
Read More
25th January, 2011 - Posted by rafael.chaves - 3 Comments
For those of you who didn’t know, AlphaSimple, our web-based modeling tool, is strongly based on Eclipse technologies:
- the server runs Equinox with the web server (Jetty) running as an OSGi bundle
- we use UML2 for building models (during model compilation), or for traversing them for execution, code generation, diagram rendering etc
UML2 is quite a piece of software. It implements the huge UML spec more thoroughly than any other alternative library (open source or not). Much of what I learned about UML in the last 5 years I learned by dealing with the UML2 API. Kenn Hussey and James Bruck have done a great job on the front of compliance.
On the not-so-great side, development seems to have stopped. IBM, which founded (and funded) the project, apparently pulled the plug last year. The current UML version supported is 2.2 whereas UML 2.4 is coming out soon. The newsgroup has no one that actually knows the code answering questions (I try, but I am far from familiar with the internals of UML2). This is not only an impediment to adoption, but may scare existing adopters away.
But even ignoring those strategic issues, there are technical problems as well: the one we faced with UML2 is thread-safety, which currently makes it unusable for long-running/highly concurrent applications. For a server-side application like AlphaSimple, that is a showstopper. Case at hand: even if we create, load and dispose UML2 resources in a single thread, internally UML2 uses a singleton object that caches cross-references between elements – for all models, and across all threads. That introduces unnecessary contention between threads that are doing fundamentally unrelated work, but worse, this cache is not fully thread-safe (see bugs 335135 and 332057), and I suspect can’t be made thread-safe by design.
Q: how does one deal with showstoppers? A: with drastic measures.
In the case of AlphaSimple, where we explicitly unload all UML2/EMF resources in the same thread we loaded them (instead of relying on garbage collection), there really is no place for a singleton complex data structure that is intensively used for anything model-related. So our drastic measure (which I am not proud of) was to patch UML2 so the cache adapter is thread specific (by replacing CacheAdapter.INSTANCE with CacheAdapter.getInstance() and returning a thread-specific “singleton”). Luckily the changes required were quite small:
org.eclipse.uml2.uml/src/org/eclipse/uml2/uml/internal/impl/ElementImpl.java
retrieving revision 1.43
diff -r1.43 ElementImpl.java
818c818,819
< return CacheAdapter.INSTANCE;
---
> //RC - hack to avoid thread safety issues with CacheAdapter
> return CacheAdapter.getInstance();
org.eclipse.uml2.uml/src/org/eclipse/uml2/uml/util/UMLUtil.java
retrieving revision 1.88
diff -r1.88 UMLUtil.java
197,198c197,198
<
< CacheAdapter.INSTANCE.adapt(stereotypeApplication);
---
> //RC - hack to avoid thread safety issues with CacheAdapter
> CacheAdapter.getInstance().adapt(stereotypeApplication);
org.eclipse.uml2/plugins/org.eclipse.uml2.common/src/org/eclipse/uml2/common/util/CacheAdapter.java
retrieving revision 1.26
diff -r1.26 CacheAdapter.java
119,120d118
< public static final CacheAdapter INSTANCE = createCacheAdapter();
<
537a536,546
> //RC - hack to avoid thread safety issues with CacheAdapter
> private static final ThreadLocal<CacheAdapter> INSTANCE = new ThreadLocal<CacheAdapter>() {
> protected CacheAdapter initialValue() {
> return createCacheAdapter();
> }
> };
>
> public static CacheAdapter getInstance() {
> return INSTANCE.get();
> }
>
This is not a real fix in the sense that it may not work for all applications – for instance, applications that read/create models across different threads. So now we need to manage this patch instead of just getting UML2 from the target platform. But comparing to having a server that keeps failing, we are quite happy with that.
If you can see an issue with this workaround, or if you think I am wrong by believing UML2 cannot be made thread-safe without radical modifications, speak up.
Read More
5th January, 2011 - Posted by rafael.chaves - No Comments
As recently announced, shared models in AlphaSimple now sport UML class diagrams thanks to Graphviz support in the Google Charts API .
What I didn’t mention is that you can customize how diagrams are rendered by specifying query parameters on the image URL. For instance, compare the basic diagram from the previous post with the customized diagram below (click on it to see the URL). Can you spot the differences?

Here are all supported options:
- showAssociationEndOwnership (boolean)
- showStructuralFeatureVisibility (boolean)
- showAssociationEndMultiplicity (boolean)
- showAssociationName (boolean)
- showAssociationEndName (boolean)
- showClassifierCompartmentForPackage (Current, Immediate, Any)
- showClassifierStereotypes (boolean)
- showElementsInOtherPackage (Never, Immediate, Always)
- showEmptyClassifierCompartments (NotEmpty, Never, Always)
- showFeatureStereotypes (boolean)
- showParameterDirection (boolean)
- showPrimitives (boolean)
- showRelationshipStereotypes (boolean)
Give it a try (don’t forget you need to share your projects, and republish for changes to become visible to others). Are there more control options you would like to see?
Read More
2nd January, 2011 - Posted by AlphaSimple Team - 5 Comments
As briefly mentioned in a previous post, you can now render UML class diagrams using AlphaSimple. This is how you do it:
- sign up for AlphaSimple (it’s free)
- create a project
- create your models using the TextUML notation (tutorial, reference). Make sure you use no extension or use .tuml as file extension.
- once your project is valid, publish it
- back to your project list (“My Projects”), share the project by clicking the open lock button. Note that when you do that you make your project available for any users to see and copy.
- now on the shared project list (“Shared Projects”), find and open your project – you will see a “Model Diagram” tab – there is your diagram! If you want to share your diagram with others, you can copy the image location and pass that URL around.
Here is an example of diagram produced for project “Lesson #5 – All together now“:

How does it work?
If you are interested in understanding what is involved here:
- AlphaSimple uses the TextUML compiler from our open source TextUML Toolkit project translating TextUML source files into UML models (using the Eclipse UML2 format).
- AlphaSimple also uses the TextUML Toolkit component (based on the EclipseGraphviz project) for generating Graphviz dot diagrams from UML models.
- For rendering the actual diagram from the dot description, instead of directly using Graphviz, AlphaSimple uses Google’s Chart API support for rendering dot diagrams.
This is all very new, so there may be some rough spots. If you have any issues, or have suggestions, send them our way.
Read More
17th December, 2010 - Posted by AlphaSimple Team - 1 Comment
This week we deployed two cool new features in AlphaSimple.
The first feature is editor tabs:

With editor tabs, you get the entire browser window width for your source files, which in the past would have required you to collapse the file list (and lose context of what other files exist in the project).
The second feature is rendering of class diagrams:

Rendering of models as class diagrams provides yet another view into your model, in addition to the textual notation and the prototype. This feature needs more work but we wanted to get it out quick even if not fully baked to get some early feedback.
We hope you like it. Either way, we are eager to hear your opinion.
Read More
27th August, 2010 - Posted by AlphaSimple Team - 1 Comment
Earlier this week we deployed a great new feature: project browsing mode. You can now open any of the shared projects, and view prototype and model side-by-side:

It is now much easier to learn how a model relates to the prototype. If you are logged in, and you like a project, you can clone it and start working on your own version right away. Try now!
Read More
23rd August, 2010 - Posted by AlphaSimple Team - No Comments
AlphaSimple just got a REST API. For any shared projects, you can get the project model (which includes access to source and XMI files) with a URI in the form “http://alphasimple.com/mdd/publisher/{userid}-{projectid}/”. For example, for:
http://alphasimple.com/mdd/publisher/rafael-26/
you get: (more…)
Read More
14th August, 2010 - Posted by AlphaSimple Team - No Comments
During the beta period registered users have access to the full service for free. The advantage of signing up is that your files are stored on the site and you can always come back and continue from where you’ve left off.
Sign up now and let us know what you think.
Read More
12th August, 2010 - Posted by AlphaSimple Team - No Comments
We have turned syntax highlighting back on. It looks a lot nicer to prototype. Also, you can use Ctrl+S for saving, and the file list can be collapsed.
There are also some improvements for IE although we still recommend using Firefox, Chrome or Safari.
Go ahead, try it out and tell us what you think!
Read More
Older Entries