January 17, 2010

Doing away with custom UML metaclasses in TextUML

Filed under: Eclipse, UML, action language, v1.6 — rafael.chaves @ 2:45 am

The TextUML Toolkit has since release 1.2 had a metamodel extension package (inaptly named ‘meta’). This metamodel extension package defined new metaclasses not available in UML such as:

  • closure - an activity that has another activity as context
  • conversion action - an action that flows an input directly as output just changing the type
  • literal double - a literal value for double precision numeric values
  • signature - a classifier that contained parameters, the type of a closure
  • meta value specification - a value specification for meta references
  • collection literals - a value specification that aggregates other value specifications

Turns out extending the UML metamodel by definining new packages and metaclasses is a bad idea. Some reasons (yes, I am feeling ‘bullety’):

  • it is non-standard
  • other UML tools cannot read instances of your metaclasses, some won’t read your models at all if they have *any* unknown metaclasses
  • there is little documentation on how to maintain these kinds of metamodel extensions
  • since it is not the mainstream approach, we are bound to encounter more issues

Because of that, release 1.6 will rely exclusively on profiles and stereotypes for extending the UML metamodel.

What to expect

For conventional users of the Toolkit, this change might possibly go unnoticed, barring any potential bugs introduced in the process.

People using the built-in base package and the base_profile will be directly affected. The elements in these models are still provided, by they are now in the new mdd_extensions profile, or one of the new mdd_types, mdd_collections and mdd_console packages.

We apologize for any inconvenience these changes might bring, but we strongly believe they are required to make the TextUML Toolkit a better product. If you have any trouble moving to 1.6 (to be released later this month), make sure to hit the user forums or report issues.

November 29, 2009

Can TextUML be implemented the generative way (with Xtext or EMFText)?

Filed under: Eclipse, TextUML Toolkit, UML, action language — rafael.chaves @ 6:49 pm

I have been trying to figure out whether the TextUML notation for action semantics can be dealt with properly by tools such as Xtext and EMFText (class models and state machines should be fine). For example, given this structural model fragment:

class Advertisement
    attribute summary : String;
    attribute description : String;
    attribute keywords : Keyword[*];
    attribute category : Category;
    operation addKeyword(keywordName : String);
    static operation findByCategoryName(catName : String) : Advertisement[*];
end;

association AdvertisementKeyword
    role Advertisement.keywords;
    role advertisement : Advertisement;
end;

class Keyword specializes Object
    attribute name : String;
end;

class Category specializes Object
    attribute name : String;
    attribute description : String;
end;

association AdvertisementCategory
    role Advertisement.category;
    role ad : Advertisement[*];
end;

Notice the Advertisement class declares two operations. Their behaviour in TextUML could be written as:

    operation Advertisement.addKeyword;
    begin
        var newKeyword : Keyword;
        newKeyword := new Keyword;
        newKeyword.name := keywordName;
        link AdvertisementKeyword(keywords := newKeyword, advertisement := self);
    end;

    operation Advertisement.findByCategoryName;
    begin
        return Advertisement extent.select(
            (a : Advertisement) : Boolean {
                return a->AdvertisementCategory->category.name = catName;
            }
        );
    end;

Note that TextUML allows the behavior to be specified inline when declaring an operation in a class, or in separate, as above (that explains the lack of parameters, modifiers etc).

In the resulting UML model, the behaviour of Advertisement.addKeyword would roughly map to this (using a textual pseudo-notation for UML activities that is hopefully more readable than raw XMI):

activity(name: "addKeyword") {
    structuredActivityNode {
        variable(name: "newKeyword", type: #String)
        writeVariable(variable: #newKeyword, value: createObject(class: #Keyword))
        writeAttribute(
            attribute: #Keyword.name,
            target: readVariable(variable: #newKeyword),
            value: readVariable(variable: #keywordName)
        )
        createLink(
            association: #AdvertisementKeyword,
            end1: #AdvertisementKeyword.keyword,
            end1Value: readVariable(variable: #newKeyword),
            end2: #AdvertisementKeyword.advertisement,
            end2Value: readSelf()
        )
    }
}

and the behaviour Advertisement.findByCategoryName would map to this:

activity(name: "findByCategoryName") {
    structuredActivityNode {
        // implicit variable for return value
        variable(name: "@result", type: #Advertisement, upperBound: *)
        // implicit variable for parameter value
        variable(name: "catName", type: #String)
        writeVariable(
            variable: #@result,
            value: callOperation(
                operation: #Advertisement.select,
                target: readExtent(class: #Advertisement),
                filter: metaValue(#@findByCategoryName_closure1)
            )
        )
    }
}

// a closure is an activity that has a reference to a context activity
closure(name: "@findByCategoryName_closure1") {
        // implicit variable for return value
        variable(name: "@result", type: #Boolean)
        // implicit variable for parameter value
        variable(name: "a", type: #Advertisement)
        writeVariable(
            variable: #@result,
            value: callOperation(
                operation: #Object.equals,
                // variables from the context activity are available here
                target: readVariable(variable: #catName)
                args: readAttribute(attribute: #Category.name, target: readLink(
                    association: #AdvertisementCategory,
                    fedEnd: #Advertisement.ad,
                    fedEndValue: readVariable(variable: #a),
                    readEnd: #Advertisement.category
                ))
            )
        )
}

Note that UML does not have closures, this is an extension to the UML metamodel which I wrote about here before.

Some background on the metaclasses involved: ReadVariableAction, CreateObjectAction, CreateLinkAction, ReadExtentAction etc are all action metaclasses. Actions are the building blocks for modeling activity behaviour in UML.

The million dollar question is: can Xtext and EMFText handle more complex textual notations like this? Is this out of the happy path? Has anyone done something similar? I am under the impression I could use Xtext or EMFText better if I used them based on a intermediate metamodel for behavior that would be closer to the concrete syntax (to get all the IDE bells and whistles for free) and then transformed that to UML in a separate step.

If you have the answers for any of these questions (or even if you have comments and questions of your own), please chime in.

March 18, 2009

SQL queries in UML

Filed under: Eclipse, TextUML Toolkit, UML, action language, v1.2 — rafael.chaves @ 12:09 pm

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:

  1. Execute them. Imagine writing automated tests against your models, or letting your customer play with them before you actually start working on the implementation.
  2. 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?

January 18, 2009

Closures in UML? Extending the metamodel with the TextUML Toolkit

Filed under: Eclipse, Graphviz, TextUML Toolkit, UML, action language, v1.2 — rafael.chaves @ 12:02 am

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):
Closure as a UML metamodel extension

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?

November 7, 2008

Executable models with TextUML Toolkit 1.2 M1

Filed under: Eclipse, TextUML Toolkit, UML, action language, v1.2 — rafael.chaves @ 3:42 am

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.

November 2, 2008

What can UML do for you?

Filed under: Eclipse, TextUML Toolkit, UML, action language, editorial, v1.2 — rafael.chaves @ 9:50 pm

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.

October 15, 2008

OMG issues RFP: concrete syntax for UML action semantics

Filed under: Eclipse, UML, action language, editorial — rafael.chaves @ 8:53 pm

This is actually old news for many people, but recently I learned (by pure chance) that the OMG issued a RFP for a “Concrete Syntax for a UML Action Language”. Letters of intent are due on December 8th. Submissions, one year after. OMG members only need apply (Aww…). I wonder if anyone in the Eclipse Modeling project is involved in submitting a proposal. Anyone?

Soapbox: since version 1.5, UML has had support for algorithmic behavior specification, commonly called action semantics. It is still hardly used, and most people that consider they know a lot of UML have never noticed it. Some people believe that the lack of an official concrete syntax for action semantics is a barrier to adoption. You see, the OMG defined the semantics and an abstract syntax, but left concrete syntax as an exercise for tool vendors.

As I wrote here before, I don’t really see the value in the OMG godfathering one concrete syntax over all others. Of course, we are talking here about a syntax for human beings, not for tools. Tools certainly don’t need a human-readable concrete syntax, a standard binary or XML format will do. The problem is: we all have our own preferences for what makes a good syntax, and there is no single syntax that will make everybody happy, so we are bound to have multiple concrete syntaxes anyway. We all like interoperability between tools, but when it comes to sugar, we like choice.

But maybe I am wrong. Maybe an OMG-blessed C-like concrete syntax for UML is all that is missing for Executable UML to become mainstream in the software development community. Go figure, we are an amusing bunch. Personally, I don’t care that much. I have been a Java developer for around 12 years now, so I can certainly stand another C-like syntax. We are not talking about a language anyway, it is just a syntax for an existing language, and syntax, a bit like UI, is inherently disposable, if you take it away, the real stuff is still there.

One clear positive outcome of the RFP is that submitters must provide, along with the proposal for a concrete syntax, any changes to fUML* that would be required to support such action language. That will probably help closing some gaps in the UML specification that make it hard to execute if you are stuck with the standard.

There are many other interesting bits in the proposal, but I will leave a more detailed analysis to a future post.

* the Executable UML Foundation Submission says:“Foundational UML Subset (fUML) is that subset of UML required to write ‘programs’ in UML”

Copyright Abstratt Technologies - Powered by WordPress - Entries (RSS) - Comments (RSS)