18th March, 2009 - Posted by rafael.chaves - 1 Comment
I strongly believe queries are an essential part of a domain model. As such, in our quest to have (UML) models that can fully (yet abstractly) describe object models for the common enterprise applications, we cannot leave out first class support for queries.
But how do you do queries in UML? The obvious answer seems to be OCL, but that is not the approach I am taking as OCL and UML have serious interoperability/duplication issues. Instead, I took the middleweight extension approach.
First, we model a protocol for manipulating collections of objects (showing only a subset here):
class Collection specializes Basic
operation includes(object : T) : Boolean;
operation isEmpty() : Boolean;
operation size() : Integer;
operation exists(predicate : {(:T) : Boolean}) : Boolean;
operation \any(predicate : {(:T) : Boolean}) : T;
operation select(filter : {(:T) : Boolean}) : T[*];
operation collect(mapping : {(:T) : any}) : any[*];
operation forEach(predicate : {(:T)});
operation union(another : T[*]) : T[*];
(...)
end;
That protocol is available against any collection of objects, which in UML can be obtained by navigating an association, reading an attribute, invoking an operation, obtaining the extent of a class (remember Smalltalk’s allInstances), anything where the resulting value has multiplicity greater than one.
Note most of the operations in the Collection protocol take blocks/closures as arguments. Closures are used in this context to define the filtering criterion for a select, or the mapping function for a collect.
For instance, for obtaining all accounts that currently do not have sufficient funds, this method would do it:
static operation findNSFAccounts() : Account[*];
begin
return Account extent.select(
(a : Account) : Boolean {return a.balance < 0}
);
end;
Note the starting collection is the extent of the Account class. That is very similar to what is done in the context of query languages for object-oriented databases, such as OQL or JDOQL. We then filter the class extent by selecting only those accounts that have a negative balance, by passing a block to the select operation.
When mapping that behavior to SQL, we could end up with a query like this:
select _account_.* from Account _account_ where _account_.balance < 0
Another example: we want to obtain all customers with a balance above a given amount, let’s say, to send them a letter to thank them for their business. The following method specifies that logic:
static operation findBestCustomers(minBalance : Real) : Customer[*];
begin
return (Account extent.select(
(a : Account) : Boolean { return a.balance >= minBalance }
).collect(
(a : Account) : Customer { return a->AccountOwner->owner }
) as Customer);
end;
Note that we start off with the extent of Account class, filter it down to the accounts with good balance using select, and then map from that collection to a collection with the respective account owners by traversing an association using collect.
If that was going to be mapped to SQL, one possible mapping would be:
select _customer_.* from Account _account_
inner join Customer _customer_
on _account_._accountID_ = _customer_._customerID_
where _account_.balance >= ?
Much of this can be already modeled if you try it out with the TextUML Toolkit 1.2. But, you might ask, once you model that, what can you do with UML models containing queries like the ones shown here?
Since the models are complete (include structure and behavior), you can:
- Execute them. Imagine writing automated tests against your models, or letting your customer play with them before you actually start working on the implementation.
- Generate complete code. The generated code will include even your custom queries, not only those basic ones (
findAll, findByPK) code generators can usually produce for you.
If you would like to see tools that support that vision, keep watching this blog.
So, what is your opinion?
Do you see value in being able to specify queries in your models? Is this the right direction? What would you do differently?
Read More
4th February, 2009 - Posted by rafael.chaves - 1 Comment
The TextUML Toolkit 1.2 is now available, 5 months after 1.1, when it first became an open source project. If you already got RC2 (1.2.0.200902011417), it is the same build, no need to upgrade again. Otherwise, just point the Eclipse update mechanism to:
http://abstratt.com/update/
Please see the feature page for a summary of the evolution of the TextUML Toolkit in terms of features across releases.
As usual, bug reports and feature requests are dearly appreciated. And if you need help, make sure to ask on the forum.
Read More
4th February, 2009 - Posted by rafael.chaves - No Comments
2011-03-10 – UPDATE: Interested in UML/TextUML and full code generation? You can now do that online using AlphaSimple
Acceleo is a cool open-source code generation tool that has great integration with the Eclipse IDE and EMF-based metamodels. The tool has a strong emphasis on simplicity and ease of use, which, for an open source development tool, is really a breeze of fresh air.
The Acceleo website includes a repository of code generation modules, which are extensions to the tool that target generation for specific platform/languages, such as .Net (C#/NHibernate), Java (Hibernate/Struts/Spring), Python, PHP, C, Zope etc. Of course, you can also develop your own modules, using Acceleo template editors with metamodel-driven content assist, and live sample generation.
Most of the modules in the Acceleo repository take UML2 compatible models. That means you can use the TextUML Toolkit for quickly creating your UML models using the TextUML textual notation, and then use Acceleo to generate code from them.
One of the most mature code generation modules in the Acceleo repository is the UML2 to Java EE module, which can generate code for Spring, Struts and Hibernate-based Java applications from UML2 models. A step-by-step guide would be too much for this post, but if you want to explore generating Java EE code from UML models you create using the TextUML Toolkit, here are some pointers:
Get the tools. First of all, using Eclipse 3.4, install all features from the following update sites:
- TextUML Toolkit – http://abstratt.com/update/
- Acceleo code generator – http://acceleo.org/update/
- Acceleo code generation modules – http://acceleo.org/modules/update
Once the install is complete, allow Eclipse to restart for the new plug-ins to become available.
Create your UML models and profiles. Create a project for your UML models using the TextUML Toolkit. For an example of how to do that, see the TextUML Tutorial. You will need to define in your model project a profile where you declare the stereotypes that you will use to annotate your modeled classes, to drive code generation (see how here)
Create your Acceleo generator project. The Acceleo website has plenty of documentation on how to create Acceleo code generation projects. Some pointers:
Note that this module has a bug in which it is based on a profile with an invalid UML name which won’t work with the TextUML Toolkit out of the box. Instead of using the profile shipped with that module, you can then override the default profile and stereotypes using a properties file at the root of your generator project as shown here so to direct it to your own profile and stereotypes. You can also find a more structured guide for using Acceleo and the TextUML Toolkit together here. Even though that tutorial uses a customized version of the JEE module, it can still be helpful.
As usual. If you need help generating code from UML models using the TextUML Toolkit and Acceleo, feel free to ask for help here, or in the user forum.
Read More
1st February, 2009 - Posted by rafael.chaves - 1 Comment
A new RC build of the TextUML Toolkit is now available. It has one bug fix since RC1. Basically, when rendering stereotypes, the metaclasses extended by the stereotype were not being shown. Not really critical, but isolated and safe enough to be fixed now. Pending any last minute bug reports by the community, it is likely this build will be promoted to 1.2 release early this week.
Also, while testing, I noticed that the Pet Store example was triggering a known Graphviz issue with associations navigable both ends, so I updated the petstore_models project so the relationship between Title and Payment was navigable only in one direction (Title -> Payment). I recaptured the class diagram images showing on that page using the Image Viewer “Save to File” function instead of screenshot sections.
Just trigger a software update for the TextUML Toolkit to get RC2.
Read More
28th January, 2009 - Posted by rafael.chaves - 1 Comment
Yikes, it happened again. A user reported that the TextUML Toolkit 1.2 RC0 build announced earlier this week wouldn’t run on Java 5 VMs (Mac users would be the most affected). This has just been fixed (one bundle was being compiled against Java 6) and a new release candidate is now available from the update site. If you too were seeing “java.lang.UnsupportedClassVersionErrors” running RC0, just go ahead and update to RC1.
Read More
25th January, 2009 - Posted by rafael.chaves - No Comments
The third milestone build and first release candidate of the TextUML Toolkit, the IDE for textual UML modeling, is now available from the update site.
The feature page shows all the new features in this new release, but here they are:
As you can tell, most of the work in the 1.2 release cycle was towards extending the TextUML notation with support for UML.
There were also several bug fixes, one of them being the first to be addressed by an external contributor (thanks, Massimiliano!).
If no serious issues are found with this milestone build, it will be promoted to 1.2 final by the next weekend. So, if you are using a 1.1.* build, make sure you upgrade it to a 1.2 release candidate build and start smoke testing with your usual workflows, and report any bugs you find.
Read More
18th January, 2009 - Posted by rafael.chaves - 2 Comments
UML is known to be a huge language, and that has two problems: it is too complex, having way more features than most applications will ever need, and can still be insufficient, as no single language will ever cover everybody’s needs.
In the article “Customizing UML: Which Technique is Right for You?”, James Bruck and Kenn Hussey (both from the UML2 team) do a great job at covering the several options for extending (or restricting) UML (James also made a related presentation at last year’s EclipseCon, together with Christian Damus, of Eclipse OCL fame). Cutting to the chase, these are the options they identify:
- using keywords (featherweight extensions)
- using profiles, stereotypes and properties/tagged values (lightweight extensions)
- extending the metamodel by specializing the existing metaclasses (middleweight extensions)
- using package merges to select the parts of UML you need (heavyweight extensions)
Each option has its own strengths and weaknesses, as you can see in the referred article/presentation. At this time, the TextUML notation supports two of those approaches: profiles and metamodel extensions.
Adding closures to UML
Even though profiles are the most popular (and recommended) mechanism for extending UML, it is not enough in some cases/applications. That has been the case in the TextUML Toolkit, for instance, when implementing closures in the TextUML action language (yes, the Toolkit eats its own dog food).
According to the wikipedia entry, “a closure is a function that is evaluated in an environment containing one or more bound variables. When called, the function can access these variables. ”
It really makes sense to (meta) model a closure as some kind of UML activity, which is basically a piece of behavior that can be fully specified in UML. Methods, for instance, are better modeled in UML as activities. Activities are composed of activity nodes and actions, which are similar to blocks of code and instructions, respectively.
The only thing that is missing in the standard Activity metaclass is the ability for a closure to have an activity node from another activity as context, so it can access context’s local variables. So here is a possible (meta) modeling of closures in UML using the TextUML syntax:
[Standard::Metamodel]
model meta;
apply Standard;
(*
A closure is a special kind of activity that has another
activity's activity node as context. A closure might
reference variables declared in the context activity node.
*)
[Standard::Metaclass]
class Closure specializes uml::Activity
(* The activity node that provides context to this closure. *)
reference contextNode : uml::StructuredActivityNode;
end;
end.
Or, for those of you who prefer a class diagram (courtesy of the EclipseGraphviz integration):

Note a model contributing language extensions must be applied the Standard::Metamodel stereotype, and each metaclass must be assigned the stereotype Standard::Metaclass.
Of course, there is no point in being able to metamodel closures, if there is no way to refer to them. We need a kind of type that we can use to declare variables and parameters that can hold references to closures. That also means we need to be able to invoke/dereference a closure reference, and there is no support for referring to metamodel elements in the UML action language. That means we need more language extensions. But I will leave that to another post. My goal here was to show how simple it is to create a simple UML metamodel extension with the TextUML Toolkit.
What about you, have you ever needed to extend UML using a metamodel extension? What for?
Read More
23rd December, 2008 - Posted by rafael.chaves - 5 Comments
No tool is an island. That is even more important when we are talking about highly focused single-purpose tools such as the TextUML Toolkit. As you probably know, the TextUML Toolkit is a tool for UML modeling using a textual notation, but that is about it. The TextUML Toolkit itself won’t help if you need features such as code generation, reverse engineering or graphical modeling/visualization. That might look as a negative thing to some, but that is by design. I am a strong believer of separation of concerns, component-based software and using the best tool for the job, and that is reflected in the design of the Toolkit.
This post will describe how to use models created by other UML2-compatible modeling tools from models you create using the TextUML Toolkit. I plan to cover other areas of integration in future posts.
Reading models created by other UML tools using the TextUML notation
If you have the TextUML Toolkit installed, one of the editors available for UML files is the TextUML Viewer. As the name implies, it is not really an editor, i.e., you cannot edit models with it, just visualize them using the TextUML notation. But it is an useful tool for reading UML models you don’t have the source for, i.e. models created by other UML2 modeling tools.
Using models created by other tools…
There are a few different ways of using models created by other UML modeling tools from your models created in TextUML.
…by co-location
In this method, you just drop the UML model you want to use to at the root of your TextUML (i.e. MDD) project. All models at the root of the same MDD project are considered to be in the same repository and thus you can make cross-model references by either using qualified names or importing the package and using simple names.
This method is dirty simple, but it forces you to keep the foreign model at a specific location, potentially forcing you to keep multiple copies of the model.
…with project references
In this method (available starting in version 1.2), the UML model you want to use is in a different project than the one you want to refer it from. You just open the properties dialog for your TextUML (MDD) project and add the project providing the UML model you want to use to the list of referenced projects. Now models at the root of that project will also be visible from your TextUML (MDD) project, in other words, they are also seen as part of the same repository.
This method is more powerful than the previous one, as now models can be shared by reference instead of by copying. There is a limitation still: the models you use ought to be part of some project in the workspace, so you cannot refer to models stored at arbitrary locations in the file system or models that are contributed by Eclipse bundles.
…by explicitly loading them
For this method, you use the load directive to load an external model located by a URI.
This method allows you to load any model, provided its location can be represented as a resolvable URI. That is the case of any file system path, or Eclipse platform URLs. The caveat is that some URIs such as file system URIs are not portable, so they are are bound to be invalid on other machines.
The entire truth…
…is that even if you are using only the TextUML Toolkit for building UML models, these are the same mechanisms for creating models that make cross-package references (see also the TextUML Guide). For the TextUML Toolkit, all UML2-compatible models are equal, no matter how they were created.
Read More
15th December, 2008 - Posted by rafael.chaves - 1 Comment
The second milestone build towards TextUML Toolkit release 1.2 is now available from the milestone update site. Get it while it is hot.
This milestone adds support for some UML language features:
But what is really exciting is that this milestone is also the first build that includes a contribution from a new member of the TextUML Toolkit team: Massimiliano Federici provided a patch that squished bug 2127735 (revision 194). Kudos to Massimiliano, his contribution was greatly appreciated, and it seems it might just be the first of many!
Read More
2nd December, 2008 - Posted by rafael.chaves - No Comments
Yesterday I checked in support for UML primitive types in the TextUML Toolkit. As an example of the syntax, here is the UMLPrimitiveTypes model, shipped in Eclipse UML2, rendered by the TextUML Source viewer:
[Standard::ModelLibrary]
model UMLPrimitiveTypes;
apply Standard;
primitive Boolean;
primitive Integer;
primitive String;
primitive UnlimitedNatural;
end.
As you can see, primitive types are declared using the keyword ‘primitive’, and cannot specialize other types or have structural features (thus there is no ‘end’ terminating the type declaration). To be honest, I am not sure this is the intended semantics, as the UML specification does not seem to explicitly disallow that.
Here is the breakdown of the change sets (r188-191):
- automated tests (r190)
- parser and model generation (r191)
- textual renderer (r189)
- editor (r188)
To be frank, the only test case added was quite trivial:
public void testPrimitiveType() throws CoreException {
String source = "";
source += "model someModel;\n";
source += "primitive Primitive1;\n";
source += "end.";
parseAndCheck(source);
PrimitiveType found = (PrimitiveType) getRepository().findNamedElement(
"someModel::Primitive1", IRepository.PACKAGE.getPrimitiveType(), null
);
assertNotNull(found);
}
But it is a good start. It ensures parsing works, and the model generated has the intended element created under the right parent package.
Any suggestions of what UML feature to cover next? And what is your take? Can UML primitive types have structural features or specialize other types/implement interfaces?
(By the way, if you want to understand how the TextUML Toolkit is implemented, feature posts like this are a good starting point)
Read More
28th November, 2008 - Posted by rafael.chaves - 2 Comments
Just checked in a new feature in the TextUML Toolkit: support for data types (a.k.a. structs). This is an example of a data type declaration:
datatype UserName
attribute firstName : String;
attribute lastName : String;
end;
You can declare operations and specialize other classifiers as usual.
Change set
Here are the individual changes per plug-in (r177-r186):
There, nice and easy. Well, actually, I ended up doing a second commit because I forgot to ensure a data type specializes only other data types. But now that has been taken care of.
As usual, suggestions of UML features to support in the TextUML Toolkit are most welcome.
Read More
23rd November, 2008 - Posted by rafael.chaves - 3 Comments
Great discussion over @ Slashdot: Is Open Source Software a Race To Zero?
I really think the open source approach has lots of benefits, for the software itself and all parties involved. However, I would say it will probably take a decade before sound business models based on open source are really understood and start to become mainstream.
At this point in time, (as most people) I still think it is considerably harder/trickier to make money developing software as open source than it is with closed source. At least for small companies. A few reasons:
- reduced barrier to entry for new competitors as they can easily leverage the fruits of your hard work. Even more so if you choose a more liberal license such as a BSD, EPL or Apache (JBoss and MySQL use GPL, for instance).
- lower profit margins, if you decide to adopt a services-based business model instead of one based on selling product licenses, which is a common approach.
- the overhead of maintaining the open source software while developing the closed source extensions or providing the related services, the very activities that will actually make money, could be unbearable.
The TextUML Toolkit is open source (EPL) since release 1.1. The decision of making the TextUML Toolkit open source was based on the fact that I (a.k.a. Abstratt Technologies) never intended to make any money directly off of it, wanted to attract external contributions and maybe get some visibility to other future offerings. But I wouldn’t have done it if I had any plans of selling the TextUML Toolkit as a product on its own.
Well, I am interested in your thoughts. Do you know of cases of small companies making good money from developing and selling open source software (using liberal licenses such as the EPL)?
Read More
13th November, 2008 - Posted by rafael.chaves - No Comments
I would like to see the TextUML Toolkit as an Eclipse MDT subproject. Not long ago, I talked to Kenn Hussey and Ed Merks (they lead the UML2 and EMF projects, respectively) about the idea of proposing the Toolkit to the EMO and they both liked it (Ed actually suggested the idea in the first place). However, I was concerned that just one guy (yours truly) working on the project on and off in his spare time with no user community didn’t look very promising, and Kenn promptly agreed, so it was decided that it was important to get other people on board first.
With the intent of starting to gather some sort of community and hopefully contributors, I decided to release version 1.1 as EPL. In the first couple of weeks after that, I noticed a significant spike in interest (page hits, issues opened, forum activity). But then everything went back to how it was before: today, there is no evidence anybody is using the tool, and I am still the only committer in the project.
So, this is a call (or a cry) for contributors: if you like the textual approach to UML modeling proposed by the TextUML Toolkit, would like to help putting together a proposal, and have some amount of time/resources to commit to the project in the long(ish) run, I am really eager to hear from you.
Things that are in scope for the project:
- broader notation coverage of UML features
- richer IDE support: content assist, search/hyperlinking, refactoring
- better integration with graphical UML tools
If you are interested, feel free to contact me via this blog, the Toolkit forum or e-mail (rafael at abstratt.com).
Read More
11th November, 2008 - Posted by rafael.chaves - 1 Comment
Just checked in a new feature in the TextUML Toolkit: required extensions for stereotypes (honestly, I didn’t know about that feature in UML until I read this post on the Eclipse UML2 newsgroup).
The following is a stereotype extending two metaclasses (uml::Class and uml::Operation):
profile my_profile;
import uml;
stereotype foo extends Class, Operation required
end;
end.
In the example above, the extension of Operation is required, the extension of Class is not.
Change set
The change set to implement required extensions in the TextUML Toolkit (issue #2266268) was quite small (btw, kudos to the UML2 project for providing the best API for UML out there).
Here are the individual changes per plug-in (r153-r156):
Any other UML feature you would like to see exposed in the TextUML notation? Suggestions are welcome.
Read More
7th November, 2008 - Posted by rafael.chaves - 1 Comment
The first milestone build of the next TextUML Toolkit release is now available from the milestone update site. This preview build is the first to include support for modeling behavior using action semantics. I hinted at this capability here before, and I plan to cover action semantics in the TextUML notation in following posts. But most people will get the gist of the notation from the examples below:
Here is an example of a UML model of an Account class represented in TextUML:
model bank;
import base;
class Account
attribute accountNumber : String;
attribute balance : Integer;
operation withdraw(amount : Integer);
begin
self.balance := self.balance - amount;
end;
operation deposit(amount : Integer);
begin
self.balance := self.balance + amount;
end;
static operation newAccount(number : String,owner : Client): Account;
begin
var newAccount : Account;
newAccount := new Account;
newAccount.accountNumber := number;
newAccount.balance := 0;
link ClientAccount(owner := owner, accounts := newAccount);
return newAccount;
end;
end;
class Client specializes Object
attribute name : String;
static operation newClient(name : String): Client;
begin
var newClient : Client;
newClient := new Client;
newClient.name := name;
return newClient;
end;
end;
association ClientAccount
navigable role owner : Client[1];
navigable role accounts : Account[0, *];
end;
end.
And here an example of a test driver ‘program’ (note the use of a closure for looping through a collection of objects):
package test;
apply base_profile;
import bank;
import base;
class TestDriver
[entryPoint]
static operation run();
begin
var john : Client, mary : Client,
account1 : Account, account2 : Account, account3 : Account;
john := Client#newClient("John Doe");
mary := Client#newClient("Mary Doe");
Console#writeln("Created: ".concat(john.name));
account1 := Account#newAccount("1234-1", john);
account2 := Account#newAccount("1238-2", mary);
account3 := Account#newAccount("2231-7", john);
Console#writeln("account owner: ".concat(account1->ClientAccount->owner.name));
Console#writeln("account number: ".concat(account1.accountNumber));
Console#writeln("initial balance is: ".concat(account1.balance.toString()));
account1.deposit(2000);
Console#writeln("after deposit, balance is: ".concat(account1.balance.toString()));
account1.withdraw(500);
Console#writeln("after withdrawal, balance is: ".concat(account1.balance.toString()));
/* Now show information for all accounts. */
Account extent.forEach(
(a : Account) {
Console#writeln("*******");
Console#writeln("Owner: ".concat(a->ClientAccount->owner.name));
Console#writeln("Number: ".concat(a.accountNumber));
Console#writeln("Balance: ".concat(a.balance.toString()));
}
);
end;
end;
end.
And here is the output of the test driver program, produced by running it on the Libra UML runtime (not part of the TextUML Toolkit):
Created: John Doe
account owner: John Doe
account number: 1234-1
initial balance is: 0
after deposit, balance is: 2000
after withdrawal, balance is: 1500
*******
Owner: Mary Doe
Number: 1238-2
Balance: 0
*******
Owner: John Doe
Number: 1234-1
Balance: 1500
*******
Owner: John Doe
Number: 2231-7
Balance: 0
Alternatively, one could have generated 100% of the code for a target platform of choice, given that all the information necessary for that is in the model. Note that code generation is not part of the TextUML Toolkit.
Do you want to give it a try? Install M1 from the milestone update site. You can also fetch the example projects from here.
It is certainly a rough stone. I am counting on the community feedback to figure out what areas need to be smoothed first. Please provide your feedback or ask questions on the TextUML Toolkit forums.
Read More
2nd November, 2008 - Posted by rafael.chaves - 6 Comments
Do you know what UML can do for you? I mean, did you know that UML models can actually do things?
One of the least known features of UML is that you can model detailed imperative behavior. The UML “instruction set” can do things like:
- create and destroy objects
- create and destroy links (associations) between objects
- read and write attributes and local variables
- invoke operations and functions
- throw and catch exceptions
- conditional statements
- loops
That is quite amazing, isn’t? And all that while still preserving a high level of abstraction. Such capability is generally referred to as ‘action semantics’. Action semantics provides the basic framework for executability in UML and has been there for quite a while now. It was originally added to the spec, first as patch, in UML 1.5 (2003), and then more seamlessly integrated into UML 2.0 and following spec releases.
Action Semantics and TextUML
An even more well-kept secret is that the TextUML notation supports UML action semantics and thus the creation of fully executable UML models. This support is not yet shipped as part of the TextUML Toolkit, but will be in the next release. Meanwhile, if you want to give it a try or take a closer look, you will have to grab the source from the SVN repository.
I plan to go into more details in the near future, but just to wet your appetite, here is one example of an executable UML model described in the TextUML notation:
package hello;
apply base_profile;
import base;
class HelloWorld
[entryPoint]
static operation hello();
begin
Console#writeln("Hello, World");
end;
end;
end.
Cool, isn’t? If you had a UML runtime, this model could be executed even before you made a decision about what platform to target. Also, if your code generator were action semantics aware, you could trigger code generation for the target platform(s) of choice, with the key difference that you could achieve (or get very close) to full code generation, as the model now also describes behavior. No more of that monkey business of having to edit the generated code and manually fill in all those /* IMPLEMENT ME! */ methods.
Do you think this has value? Would you want to work with a tool that supported that? I am really keen on knowing your opinion.
Read More
14th October, 2008 - Posted by rafael.chaves - No Comments
I posted this earlier this week on the UML2 newsgroup, thought I would share it here too…
I published a TextUML rendition of the UML 2.1 metamodel that is shipped by Eclipse UML2 here (warning: 5.9k lines, 370Kb of text). It starts like this:
(...)
model uml;
apply Ecore;
apply Standard;
import ecore;
(* A comment is a textual annotation that can be attached to a set of elements. *)
[Standard::Metaclass]
class Comment specializes Element
(* Specifies a string that is the comment. *)
[Ecore::EAttribute(isID=false,isTransient=false,isVolatile=false,isUnsettable=true,annotations=[])]
public attribute body : String;
(* References the Element(s) being commented. *)
public attribute annotatedElement : Element[0, *];
end;
(...)
Thought it could be useful to anyone wanting to have a quick look at the UML metamodel. The TextUML renderer does not support all UML element types, so some elements might be missing/incomplete.
I think that is a nice demo of the textual browsing capabilities in the TextUML Toolkit. Of course, much more could be done in that area. If you feel like lending a hand, any help (bug reports included) will be much appreciated.
Read More
16th September, 2008 - Posted by rafael.chaves - No Comments
Shorthand notation for both composite and aggregate associations has just been checked in (r99-r100). It follows the same spirit as the existing shorthand for plain associations (a.k.a. references).
composition <end-name> : <referenced-type-name>;
or
aggregation <end-name> : <referenced-type-name>;
That will result in a new unnamed association with two member ends, one named, owned by the declaring classifier, with composite or shared aggregation type, and another unnamed, owned by the association itself.
Change set explained
When adding a new feature to the notation, the typical change set contains:
- updates to the affected grammar production rules
- implementation of the corresponding model generation handling code
- a few test cases.
In the case of the features presented in this post, the grammar change was quite simple (nicer view):
--- trunk/plugins/com.abstratt.mdd.frontend.textuml.core/textuml.scc 2008/09/16 05:47:13 99
+++ trunk/plugins/com.abstratt.mdd.frontend.textuml.core/textuml.scc 2008/09/16 05:47:20 100
@@ -341,7 +341,9 @@
attribute_decl = attribute identifier colon type_identifier optional_subsetting semicolon ;
- reference_decl = reference identifier colon type_identifier optional_subsetting semicolon ;
+ reference_decl = reference_type identifier colon type_identifier optional_subsetting semicolon ;
+
+ reference_type = {association} reference | {composition} composition | {aggregation} aggregation ;
optional_subsetting = subsets qualified_identifier | {empty} ;
In other words, where one could declare a reference, one can now declare also a composition or an aggregation (gotta love the readability of SableCC grammars…).
The corresponding model generator (a.k.a. compiler) changes were quite trivial as well, even more so if you consider I inadvertently checked in a fix to an unrelated bug around comments (just ignore the changes in lines not in the 300′s).
In terms of lines of code, the bulk of the changes were in the test class for associations, where I added three test cases. I had postponed writing tests for the reference shorthand notation, so I took this opportunity to write a test for it too.
As most test cases in the TextUML Toolkit test suite, the new test cases in AssociationTests have the following layout:
- one or more compilation units with TextUML source code are declared
- source code is compiled and the resulting errors verified (most test cases won’t expect errors)
- the resulting model is checked – were the expected elements created? Do they have the expected features?
Talking about tests
The TextUML Toolkit has a modestly sized test suite (~130 test cases) at this time. It could use dozens, probably hundreds more, but most features are covered to so some extent.
However, as important as coverage, is how much one can learn about the piece of software being tested by reading its test suite. And here is where I believe the TextUML Toolkit’s test suite shines. For example, by reading the test classes, one could (maybe more effectively than by reading the notation guide), learn how the following UML features are exposed by the TextUML notation:
Trivia: can you find out from the test suite the difference between a private and a public package import? Give it a try and let me know if I am lying… by the way, the notation guide does not cover that yet, although the UML specification, of course, does.
Read More
10th September, 2008 - Posted by rafael.chaves - 5 Comments
I often see the TextUML Toolkit being compared to tools that produce UML diagrams from textual descriptions. Examples of tools like that are ModSL, MetaUML and UMLGraph. But that doesn’t really make sense, and here is why: these tools produce diagrams from text. The TextUML Toolkit produces models from text. But what is the difference between models and diagrams?
According to Wikipedia:
- A diagram is a 2D geometric symbolic representation of information according to some visualization technique.
- A model is a pattern, plan, representation (especially in miniature), or description designed to show the main object or workings of an object, system, or concept.
Note that even though both terms are defined around the word “representation”, the term “diagram” implies graphical visualization, whereas the term “model” admits any kind of media, basically because models have no concrete form per se.
Now, please, if you are not convinced yet, read aloud 5 times: MODELS ARE NOT DIAGRAMS!
If that didn’t work, well, maybe the facts below will help:
- models, not diagrams, are the subject matter of model-driven development.
- models, not diagrams, can be validated.
- models, not diagrams, can serve as input to code generation.
- models, not diagrams, can be automatically generated from reverse engineering source code.
- models, not diagrams, can be executed.
Even though diagrams are commonly used for representing models, they are not the only way, and non rare not the most appropriate one (yes, I am talking again about the virtues of textual notations, but I won’t repeat myself).
P.S. Maybe it helps adding to the confusion the fact that the TextUML Toolkit has an optional feature that will generate class diagrams automatically from the UML models created with it. However, that is just an optional, loosely integrated feature, and it is definitely not the Toolkit’s thing. Weirdly enough, from my observation, that feature is the main reason most people become interested in the TextUML Toolkit. Well, go figure.
Read More
2nd September, 2008 - Posted by rafael.chaves - 5 Comments
TextUML Toolkit 1.1 is out! This is the first release after the TextUML Toolkit became an open source project. Besides the adoption of the Eclipse Public License, these are the new features that were added in 1.1:
- more UML features exposed by the textual notation: abstract operations and parameter direction modifiers
- more diagram layout controls (compartments, elements across packages)
- support for exporting the class diagram to a PNG or JPG image file (actually, an EclipseGraphviz feature, also available for other graphical content providers)
Also, the TextUML Toolkit is not available any longer as a standalone download. You need to install Eclipse 3.4 first (3.3 support was dropped) and then install the TextUML Toolkit using the new smart Software Updates mechanism in Ganymede. See new install instructions here.
As usual, feedback is most welcome – blog, issue tracker or forum, whatever option works best.
Read More
Older Entries
Newer Entries