As an ArgoUML contributor I'm going to blog my activities here, so that they may draw interest by other developers or help other developers when doing tasks similar to what I've done. AND(!) the grand vision that makes an Argonaut what he is, TO THRIVE IN THE BIG DANGEROUS WORLD, TAKING THE Argo TO A GOOD SHORE ;-))

Monday, June 20, 2005

ModelerImpl and new MDA ideas


Now, getting back to the work in reverse engineering module for C++, I'm working in the part that will make the information parsed from the C++ translation unit go into the UML model. Previously I worked in the analysis of this problem. Several design solutions were proposed, but, I don't see them with a clear vision... So, instead of falling into an analysis paralysis situation, I'll start working in the problem in the pragmatic test driven development way! I'll remember my ideas that spawn from the previous analysis excercise, though, so that if I see some pattern to arise I'll easily map it to these ideas.


I'm working in yet another (see here the other two) proposal for the a future C++ module(s) development according to MDA. Now, what I'm considering is to have the C++ module developed according to its own medicine. With this I mean, have the C++ module implemented in C++! For this, and to enable the investment in the java not to be thrown away, I'm considering to have the module developed according to MDA, with two alternate, platform specific implementations and one common abstract model which would be a PIM.

Proposal for the development of a C++ implementation of the C++ module according to MDA.

Picture 3 – Proposal for the development of a C++ implementation of the C++ module according to MDA.

The above picture is very self-explainable. For persons less familiar with MDA, I would say that the PIM and PSM stereotypes stand for Platform Independent Model and Platform Specific Model, respectively. So, we'll have a common PIM of the C++ module, and two implementations. One is the current, or an evolved one already supporting some scriptable capabilities to enable easy customization (I've put Jython, but, with JSR 223 out, we could have any compliant java based dynamic language). The other is an alternate implementation, based in C++ and uses some of the C++ libraries like Boost.Python (to enable the customization of the code generation) and Boost.Spirit (a C++ mean parsing machine). The use of SWIG would make the integration between the C++ code and the rest of the java powered ArgoUML easier than using plain JNI.

So, what do you think? Is this utopic enough for you to jump along and help me prove there are no impossibles?! This will enable the C++ fans to work in the C++ module tasting their own medicine ;-)... Herrr, of course it must be the MDA way!

3295 crushed!

Michiel commited my patch proposal. I synchronized with the repository – update overwrite – and it is working fine. Now, I remember that I forgot to run the checkstyle tests on top of my code before sending the patch!!! Big mistake, when the bug was reported and the patch attached to the issue I was in the end of a big 19 h day. This was a missed opportunity to hold on the horses a bit and wait to have a fresher mind...

The issue is now marked as FIXED and I'm happy to have my initial itch gone from ArgoUML ;-))


I created the # 3295 issue which is the Stereotypes contained in packages aren't available for selection problem.


One of the things that are limiting my use of ArgoUML for modeling is its UML version support. Argo is at UML 1.3 and this has some annoyancies. One that I dislike very much is the fact that you can only apply one stereotype in a model element. In UML 1.5 I may apply several stereotypes to a model element. This, for MDA work is very important, I think...


There are more problems with stereotypes than I thought of. While testing my fix I have the following:

I had a problem with my working setup in ArgoUML. The WinCVS, after an update of the Python installation, didn't worked anymore. It crashes almost immediatly and just leaves a small core dump file (I think because I'm driving a windows box). Because of this I attempted uninstalling and installing, but, no can do! I wonder if the WinCVS crew would like to receive my trouble report?!?

So, I made a clean checkout directly in Eclipse and this worked very well. Now, the catch(!) only after a painful process of reconfiguring my all environment I discovered this nice feature of eclipse – select a project, right click, then choose "Team" / "Shared Project...", and, if the project contains some CVS directories it asks if you want to configure CVS for it! Great! So, I re-discovered the following maxima: know your tools!


I'm still fighting against the Stereotypes contained in packages aren't available for selection bug. The test case I'm developing for testing the problem is the TestExtensionMechanismsHelper.testGetAllPossibleStereotypesStereotypeAndMEContainedInSubPackage(). It tests exactly what was previously done for the TestUMLModelElementStereotypeComboBoxModel.testStereotypesContainedInPackagesAreAvailable4Selection(), but, this one puts the emphasis in being an ExtensionMechanismsHelper test. Since it doesn't use NSUML classes I put it in the org.argouml.model package. It is really a test to the org.argouml.model.ExtensionMechanismsHelper interface and not to a specific implementation, like the previously existing org.argouml.model.uml.TestExtensionMechanismsHelper test is.

Now, all tests are running and it should be OK to make the changes to the model according to what I was trying to do in the C++ module, in the first place. I'm modeling some ideas about the architectural organization for future C++ module development. Some ideas, like the MDA specification of programming languages, are much wider than the C++ module, but, could be a bit utopic...


Stereotypes contained in packages aren't available for selection

I found a new bug in ArgoUML! If you create a stereotype in a package, it won't be available for selection and assigning it to a model element. This occurs in ArgoUML 0.18.1. I'm going to try to reproduce with HEAD and maybe fix it!

I have an example of the problem. Loading it with Argo HEAD... Yeah, it is still present. So, lets see if this is fixable...

Alright, I have a suspect! The is used in and should be responsible for the drop down combo box contents for the stereotypes. It does use an org.argouml.model.ExtensionMechanismsHelper. Now, the only implementor is the org.argouml.model.uml.ExtensionMechanismsHelperImpl. Let us check if this guy has some tests... Nope! So, no test driven debugging available here.

Let's check if the user UMLModelElementStereotypeComboBoxModel has tests... Jackpot! It is the TestUMLModelElementStereotypeComboBoxModel Now I have something to start with... Lets write a unit test to reproduce the problem.

Upsss, found a dependency from a NSUML class (! This must also go away! DONE

Alright, after some time I already have a failing test, it is testStereotypesContainedInPackagesAreAvailable4Selection(). Now, lets debug and check what is going wrong...

The function where all interesting action is happening is UMLModelElementStereotypeComboBoxModel.buildModelList(). This is triggered by the UMLComboBoxModel2.targetSet(TargetEvent e) function, which I call in my test. Now, the model list building has the error I'm trying to fix and something I might call hand crafted code obfuscation! It contains code which looks suspiciously useless, but, rather complicated... I've marked it with background red color.

    protected void buildModelList() {
        Object elem = /*(MModelElement)*/ getTarget();
        Set paths = new HashSet();
        Set elements = new TreeSet(new Comparator() {
            public int compare(Object o1, Object o2) {
                try {
                    String name1 = o1 instanceof String
                        ? (String) o1 : Model.getFacade().getName(o1);
                    String name2 = o2 instanceof String
                        ? (String) o2 : Model.getFacade().getName(o2);
                    name1 = (name1 != null ? name1 : "");
                    name2 = (name2 != null ? name2 : "");

                    return name1.compareTo(name2);
                } catch (Exception e) {
                    throw new ClassCastException(e.getMessage());
        Collection models =
                .getAllPossibleStereotypes(models, elem));
           .getAllPossibleStereotypes(models, elem));

Then it calls the method ExtensionMechanismsHelper.getAllPossibleStereotypes(models, elem) which seams to be the origin of the bug. So, I'll remove the useless code (if it proves as such) and make another test on the failing function that should retrieve all stereotypes applicable to the model element within the specified models.

Argo is a processor hog

Hell! Today I can't work with Argo! It is dragging! After some changes in a middle sized project - the C++ module model, argouml/modules/cpp/doc/ArgoUML.zargo - it started to toggle high processor cycles. When I found the previous bug and wanted to save the model and close ArgoUML 0.18.1, it went full load on the processor and I had to kill it the dirty way. So, yesterday I did two things, update the JRE to 1.5.0_02, and downloaded ArgoUML 0.18.1 so that I would work in the model with the stable version(!). Clearly something went wrong! Here is the System Information:

Java Version  : 1.5.0_02
Java Vendor  : Sun Microsystems Inc.
Java Vendor URL :
Java Home Directory : C:\Programas\Java\jre1.5.0_02
Java Classpath  : C:\luis\programas\ArgoUML\0.18.1\argouml.jar
Operation System : Windows XP, Version 5.1
Architecture  : x86
User Name  : luis
User Home Directory : C:\Documents and Settings\luis
Current Directory : C:\luis\programas\ArgoUML\0.18.1
JVM Total Memory : 7729152
JVM Free Memory : 3209392

I'll try to work a bit with a new model to see if the same thing happens...

Nothing, no peek processor loads! Well, at least I have my example for the other problem. The final test, lets try to save the example... No problem!


I previously considered about spell checking in Vim and I've found about the vimspell plugin for Vim. The plugin isn't working with my Vim version (6.3). There are some errors in the plugin installation, maybe related to this script not being up-to-date with Vim... All the other plugins for spell checking don't seam to be better. So I'm giving up on this for now :-(

As a better replacement for my current spell checking approach, I use aspell directly with the command:

aspell -c file.html


ModelerImpl: the Java's Modeller design and recall of discussion with Andreas Rueckert

Andreas Rueckert is the author of the ArgoUML reverse engineering for java and classfile. I previously discussed with him my plans for the C++ reveng work. He warned that reusing the java Modeller would not work since it is specific for the java semantics. This Modeller was originally made by Marcus Andersson, in the context of his java reveng project.

It refers to the JSR 26, which should be the Java language mapping to UML. [I'm currently traveling by train and offline, so, I can't confirm this.] The current state of the Modeller is very little configurability. This isn't totally bad, since the user might post-process the reversed model with some MDA tool to get a more abstract model. This would be interesting if you are working with an enterprise application, where, e.g., you want some group of files to be associated with an EJB. I will browse a bit in the original javare project, to see if it is still going.

It is stopped, since it achieved its goal of providing a reveng implementation according to the JSR 26 spec for ArgoUML. Now, maintenance continues in the ArgoUML project.

The java Modeller uses the notion of Context to store information about the parsing context. It is designed as a class hierarchy of contexts, with a ClassifierContext and a PackageContext. These context classes are tied to ArgoUML reveng, being dependent of org.argouml.model package. The Modeller stores a stack of parsing states (ParseState) which have context information. I think that even if I can't reuse directly the classes, I might reuse the idea, implementing it in a more general and decoupled way and them make it available for reuse to other reveng modules.


I previously started analyzing the requirements of ModelerImpl, but, left it incomplete. Now I'm going to continue with this here.

ModelerImpl: analysis of responsibilities

A Modeler implementation must:

  • Understand very well the C++ syntax and semantics.

    The syntax is in its method names and arguments, although without the clear order in which calls might be made. This could be improved by adding a clear contract to the interface, but, for now I'll leave it as it is and just state that complete syntax information should be looked up in the grammar.

    The semantics is something that will be built within, as part of the implementation. I would say that knowing about semantics is, for instance, to know that a method of some class which has the virtual modifier is polymorphical and that if some derived class (direct or indirect) has the same method (name and args) even if it does not have the virtual keyword, it is polymorphical. This knowledge is important since this semantics has representation in UML and therefore it should be created in the model.

  • Keep the state of the parsing in a way that when it is called about some parsed construct it models it according to the context.

  • Understand very well UML and the specific ArgoUML representation of it (this is available in the org.argouml.model package).

  • Model C++ in UML according to guidelines accepted in common by the community.

    Maybe there exist already some UML profile, maybe even a standard one defined by OMG... I googled a bit on "UML profile for C++" and couldn't find one, apart from the UML tool vendors. Objecteering has defined one, but, this certainly comes associated with some copyright. It is also proprietary, due to their notion of a UML profile as a MDA component. I prefer to see a UML profile as a model that one may import into our model. ArgoUML should have a UML profile for C++!

  • Be flexible, i.e., it should be possible to configure it according to the user's preferences.

    One could have default configurations on the module that might be overridden by the user's preferences. Things that should be possible to configure are: model pure virtual class as interface or as abstract class, array or STL container modeled as DataTypes or as association with multiplicity, model references and pointers as associations or as DataTypes, etc.

    More, it would be interesting to configure the reverse engineering to use different options for different packages and / or classes. This would be kept persistently in the model, so that in a future import the user would not need to specify it again.

This seams to be too much responsibility to put on top of just one class! I could start already developing and deal with a functionally overloaded and crowded class when it gives problems, but, I think I may start decomposing the problem into smaller parts, just looking at the above list of responsibilities.

Clearly the understanding about C++ syntax and semantics should be close to the Modeler implementation, since its interface is already loaded with these details. Now, about keeping state of the parsing, maybe this should be abstracted from the part of the code that actually makes the translation, since, in a future evolution I might add AST functionality to the grammar, therefore, the Modeler might be capable of navigating back and forth as it models the parsed code. So, maybe I should have something like a component that records the parsed information and is able to provide the context on demand of the actual modeler. I see this as a need when the modeler has full data to model an attribute of a class, and it has to add details regarding the containment and visibility of the attribute.

Now a use case, what if parsing of a given translation unit fails? Should the Modeler undo the import? I think I would like that in this case the parsing just warns about not being able to parse and to issue a clear message about the place where it is failing, with no changes being made to the model. Better it should be configurable! In this case, I think this responsibility should be moved to the CppImport class.

No comments:

Reader Shared items