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

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.

EmailFacebookLinkedInGoogle+Twitter

One thought on “Can TextUML be implemented the generative way (with Xtext or EMFText)?

  1. Sven Efftinge

    November 30, 2009 at 8:05am

    It is not your textual notation which is complex, but the mapping between your syntax and the UML meta model.
    I general one could say that if the concrete syntax is not designed with the abstract syntax in mind or vice versa, you might be forced to use a transformation with both frameworks. While in Xtext the concrete syntax is a bit looser coupled with the underlying ecore model compared to EMFtext, I’ld recommend to transform to the UML meta model separately and explicitly in both cases.

Comments are closed.