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 ;-))

Thursday, December 15, 2005

2005-12-15

The template notation spike is documented in a issuezila task (#3802).

Today I contributed my eclipse project files to ArgoUML list, in a reply to a discussion about shared eclipse projects.

Monday, December 12, 2005

Reorganization of ArgoUML eclipse projects

While working in the template notation spike I had to advance some work in the model support for parameterized classes. This implied in making some changes to the ArgoUML model sub-system interfaces and in the NetBeans MDR implementation of the model sub-system. With my previous organization of the eclipse projects this became very cumbersome. I have one eclipse project for ArgoUML, which contained everything bellow cvs/argouml and another with argouml-mdr. The later depended on the former, in order to have the model interface in the class-path - localted in cvs/argouml/src/model. To have the MDR implementation accessible I put argouml-mdr.jar and the other jars from which it depends into the main ArgoUML eclipse project. It was a way to fool eclipse's circular dependency detection. The problem was that I had to do external builds of the MDR jars everytime I made a change in the MDR implementation!

So, after bumping my head against this problem some times I decided that I could benefit from a re-organization of the ArgoUML eclipse projects. Considering the CVS organization of the ArgoUML projects I have defined the folowing eclipse projects:

  • argouml-lib – contains the ArgoUML libraries from cvs/argouml/lib
  • argouml-model-api – contains the ArgoUML model sub-system API, from cvs/argouml/src/model; depends on argouml-lib
  • argouml-mdr – contains the MDR implementation of the model sub-system, from cvs/argouml-mdr/; depends on argouml-lib and argouml-model-api
  • argouml-src_new – contains the core ArgoUML application, from cvs/argouml/src_new; depends on argouml-lib, argouml-model-api and argouml-mdr
  • argouml-tools – contains the tools used in ArgoUML, from cvs/argouml/tools
  • argouml-tests – contains the unit tests of ArgoUML, from cvs/argouml/tests; depends on argouml-lib, argouml-model-api, argouml-mdr, argouml-src_new and argouml-tools
  • argouml-cpp-module – contains the C++ module, from cvs/argouml/modules/cpp; depends on argouml-lib, argouml-model-api, argouml-mdr and argouml-src_new; the other modules within cvs/argouml/modules are loaded in projects similar to this

One thing that I needed was to filter out the NSUML implementation from argouml-src_new. Shouldn't this be removed alredy?!

I think I'll propose this organization in the argouml-dev list, as a possible way to have shared eclipse projects in CVS. I think that this way we will have a much simpler setup for newcomers.

Thursday, November 24, 2005

starting with parameterized classes and UmlUnit

2005-11-05

I think I need a spike in what concerns working with GEF. It is certainly possible to make the composition of two figures – the class rectangle and the dashed rectangle with the template parameters. But, I never worked with GEF and graphical programming isn't my game. So, just for fun, lets make this spike.

2005-11-04

1446 User stories

I'll start now with the user stories for 1446. The rules for writing are stated above.

Create parameterized class

Provide a UI action to create a parameterized class. This should be similar to what is currently used to create a normal class. After creation, the parameterizable class properties shall be editable, as usually ocurs for the rest of the model elements. The user may immediatly enter the parameterized class name.

Create template parameter

It is possible to create a parameter for a template. This should work in a similar way as creating / adding attributes to a class. By default the template parameter type is a Classifier, its name is PARAM and it has no default value.

Edit template parameter properties

The properties of a template parameter are visible and editable in similar ways as properties of other model elements.

Parameterized class constrains

Parameterized classes are constrained to have associations only with classes, being uni-directional from the template to the class. An exception is that a bound class is associated through a bind association to the template, being this directed from the bound class to the template.
NOTE: this is too restrictive for common use with programming languages that support templates and maybe we should relax the specified constrains.

Parameterized class graphical presentation

The parameterized class is represented graphically as specified in the UML spec. It is possible to add parameterized classes in class diagrams. The template parameters are editable, but, must respect the rules of the UML spec. It is possible to hide the list of parameters, but, the dashed rectangle remains visible [I'm not totally sure if the spec realy means this].

Create bound class

In the context of a parameterized class it is possible to create a bound class. The parameters must be bound to actual values according to their types. ArgoUML must enforce this either by using default values or by rejecting the creation of the bound class.

Bound class properties

The bound class is similar to a class with the added properties of the template parameters values and the bind association to the template. All the properties are visible and editable, with the exception of the bind association, the attributes and operations of the template which are read only.

Bound class presentation based on name

The UML spec allows to have a bound class with the name explicitly showing its nature, e.g., ParameterizedClassName<Param1Value, Param2Value>. With this presentation it is possible to edit the parameter values in a very simple way. So, it is not needed to have a non-explicit name.

Presentation of a bind association

The bind association may show explicitly the parameter values in brackets, as exemplified in the UML spec.

Use of template parameters within parameterized class

The parameterized class template parameters are usable within the parameterized class for parameterizing its attributes and operations. This means, for instance, that the type of an attribute may be a template parameter.

Delete parameterized class from model

It is possible to delete a parameterized class from the model. The usual model element deletion rules apply, which means, all bound classes are also deleted. A warning is shown to the user stating this, but he may silent it permanently.

Delete template parameter from model

It is possible to remove a template parameter from the model. The usual model element deletion rules apply, which means, all depending attributes, operations and operation parameters are also removed.

2005-10-27

I'm now reviewing the UML support for Parameterized Classes. I'll simply take some notes here about my findings before starting to write User Stories. First a disclaimer, I used UML 1.5 spec since I don't have 1.4 available now. When I get the chance I'll look at that to see if there are changes in this area.

UML defines the Template concept as a "parameterized model element". Strangely a restriction to this is that it "cannot be used directly in a model". Does this means that I cannot say that a Parameterized Class specializes a normal Class? No, the spec explicitly allows two exceptions: "a template may be a subclass of an ordinary class" [ufff!] and one way associations from Templates to other classes.

More strangely, the "«bind»" association is what is used in UML to create a normal class from a Template, by specifying the parameters. Guess what, the association is from the resulting class – the Bound Element to the Template, thus violating the rule expressed just above. Well, I guess this should be the third exception: one way association with stereotype bind from Bound Elements to Templates.

All model elements may be Templates, but normally, in addition to Classes, the model elements that are parameterized are Colaborations and Packages. I think that adding support for these two isn't much more effort since the semantics and notation are very similar.

While considering this I had the idea of a simple refactoring that is usualy done in programming languages that support templates and which may be supported by ArgoUML: creating a Parameterized Class from a Class. This is something interesting because UML does not allow it since the class normally has associations. So, it must be something specific to the tool.

ModelerImpl until now was just a huge Spike!

Now that I've studied a bit XP and learned about the concept of Spike, I must consider the work up to now on ModelerImpl as a huge Spike. The proof is my note when it was started after a big analysis effort that resulted just in some inconsistent ideas. The Spike, resulted in some very strong ideas:

  • ModelerImpl must delegate its reverse work to a tree of objects, each specialized in its own constructs, acting on a current context.
  • ModelerImpl must reverse to something else than the actual user model. Preferably it should do it to a new empty model that is in a subsequent step reconciled with the user model. Note that this should not preclude future optimization paths like simply checking if some file was already imported and comparing the previous taken MD5 signature with the current.
  • Importing Context smells more and more like an aspect of the way I've implemented the importing, being based on callbacks from the parser. I wonder if I was using a built AST of the code, if I would recur to this...

2005-10-26

XP Practices to be used in the development of support for parameterized classes

I've reviewed the high level information on XP (the 2nd step of the plan) in www.extremeprogramming.org and chose the following limited set of practices:

  • User Stories – I'll be the writer and creator, instead of being the result of input from a customer. The User Stories will be included each in the issue to enable gathering feedback early in the development for modifications and prioritization. It is possible that some will be grouped and handled in separate issues, with #1446 depending on those. I'll develop acceptance tests only when these are possible in a small ammount of time. The acceptance tests will be stored in ArgoUML as Unit Tests. Apart from these details I'll try to keep then as described in XP.
  • Spike Solution – Support for parameterized classes implies changes in almost all the most important ArgoUML sub-systems. Due to the fact that I'm not acquainted with many of them I'll need to make quick and dirty attempts to know if some devised solution works. These will be my Spike Solutions; I'll record then in a minimum with small notes, the time spent on this will be accounted as part of the story implementation, the planning or whatever, and in the end their results will never be incorporated in the code directly.
  • Test Driven Development (TDD) – This will be followed fully. I don't know how I'll do it for GUI (JFCUnit isn't used in ArgoUML), but, this must be done without exceptions.
  • Refactor Mercilessly – Refactoring will be followed fully. The problem is code without tests that exists in ArgoUML and that committers may feel insecure to patch with my refactorings. So, this will probably be difficult, but, I'll try to make it happen!

Its a pity to leave out Continuous Integration, Acceptance Tests and other practices, but, some reasons lead me to this:

  • I don't have commit rights to ArgoUML, so, I can't enforce the integrate often rule because someone must commit my future patches;
  • my time availability is variable and scarce, so, some times I leave unfinished parts during week time spans;
  • state of the art support for both acceptance tests and continuous integration requires infrastructure that I don't have and that possibly would take very much time to set up with others' help, since I'm being pragmatic I won't try this for now.

Last but not least, the methodology taken as a whole seams to be more appropriate to teams than it is to individuals, even if working for an open source project with a good community. I would like to see examples of XP applied to open source projects by hobbyists. Probably these would not take the whole thing, even if all team members follow XP.

That's why I will continue to use the Process Dashboard and be inspired by its functionalities and underlying process. I must read the book one of these days!

Now I remember that I know of an open source project that follows XP, its the JyDT. I wonder if Red Robin would provide some feedback on his experience... It was XP before going open source, so, I wonder how he is doing it now...

2005-10-24

I'll start now with issue #1446 – Lack of support for Parameterized Class (Template). This is a complex issue and so, I must handle it as such, by having a plan where I must define iterations for partial deliveries. I think I'll follow some of the eXtreme Programming (XP) practices in this development, such as Test Driven Development (TDD), small iterations for delivering complete user stories, Refactoring and simplicity.

Plan for Parameterized Classes support

  1. Planning the development of 1446. For this activity I'll use the Process Dashboard tool to measure the time I spend in each of the tasks and a scheme similar to what I've developed in the previous work for C++ reveng support. The main difference is that I'll use user stories to drive the development, being the iterations necessarily more formal and regular. This step must be revisited as often as possible (in the end / start of a user story development cycle should be the norm), being sub-sequent updates to the plan documented here.
    EE 25 Mh; SN – Planning

  2. Review the XP practices that I'll use in this development – TDD, Refactoring, User Stories, automated builds and possibly more if applicable. The selection of practices will follow the pragmatic objective of choosing the ones that are possible with a minimum effort. For example, I've left out the continuous integration and acceptance tests since I don't have infrastructure for this. Some of the practices will be adapted to be practical, like the definition of user stories might be defined by me. This isn't subverting the practice totally since I'm also a user of ArgoUML ;-). In the end of this task I must have a list of the chosen XP practices, with descriptions of how some of these will be applied, where I can't follow closely the practice as defined elsewhere.
    EE 8 Mh; SN – Review XP practices

  3. Review the UML support for parameterization using the UML 1.4 specification. I must check also other UML elements where parameterization is possible, so that I'm able to develop a good set of user stories that is representative of the work. My objective is just to develop an overview, so, writing one paragraph with the conclusions is enough.
    EE 4 Mh; SN – UML support for parameterization

  4. Writing the set of user stories for guiding the development of support for parameterized classes in UML. I don't know very well what will be the result of this activity, since I'm not acquainted with user stories, but, after this step I must have a decent set of them written. It is likely that the first set of user stories won't be complete or correct. Any additional writing will be done here, unless it occurs just for the correction of one user story while developing it. In that case the time spent with this is accounted in the step of the given user story.
    EE 10 Mh; SN – Writing user stories

UML Unit - Enabling Test Driven Modeling

This idea is buzzing inside my head for some months. Why not specifying test cases in UML? We may use the object representation to specify the instances involved in a test case. Then, a collaboration or sequence diagram may represent a test case. Also, test cases might be grouped in classes that have the TestCase stereotype.

In my view we can support this by defining a UML profile called UML Unit and adding mapping for code generation and reverse engineering to ArgoUML to the existing unit testing frameworks: JUnit, CppUnit, NUnit, PyUnit, etc. It would be interesting to add support to this idea to AndroMDA also, since an obvious target is to enable Test Driven Modeling (TDM) at the PIM level. I know that the Executable UML supports this for years, but, this isn't available in open source tools. So, by having a simple mapping to POJO like PSM that could even be the source code, we could have the same thing without the need to have a UML virtual machine.

The assertion and verification may be modeled as OCL statements. But, this implies code generation support for OCL statements. This is something that isn't yet supported in ArgoUML, although OCL is supported for some years.

2005-10-14

So, after verifying that issue #3552 isn't correct I'll change it to the documentation and fix the docs. Its name will be "header_incl warning in manual's C++ appendix is wrong and solving TODOs".

2005-10-10

Michiel van der Wulp commited my patch to the documentation which includes the C++ generator documentation. Daniele Tamino created two of the above issues, but, I must check the problems I had with duplicate tagged values. In the ArgoUML GUI the duplicated values are shown and reloaded correctly. Maybe this is only replicable when the tagged values are queried like when the C++ module tries to find it... No, it works correctly, so, the warning and TODO will be replaced with a hint to use multiple times the tag.

The issues are:

  • 3552 – header_incl allows to include only one header
  • 3553 – handle multple return parameters

Friday, October 14, 2005

C++ module documentation

2005-10-10

Michiel van der Wulp commited my patch to the documentation which includes the C++ generator documentation. Daniele Tamino created two of the above issues, but, I must check the problems I had with duplicate tagged values. In the ArgoUML GUI the duplicated values are shown and reloaded correctly. Maybe this is only replicable when the tagged values are queried like when the C++ module tries to find it... No, it works correctly, so, the warning and TODO will be replaced with a hint to use multiple times the tag.

The issues are:

  • 3552 – header_incl allows to include only one header
  • 3553 – handle multple return parameters

2005-09-23

I have already successfully created the appendix. DocBook is very verbose and for an unexperienced person like me it is awkward to have a slow iteraction to see what errors exist in the file – I'm generating the documentation and this takes very long because the manual is the last to be processed; it also bails on the first error, so, each error cost me a lot! I know that some nice eclipse plugin exists, but, I would like to have the functionality of verifying the syntax in Vim. I guess I must look for this...

Another option is to use a separate validator, like the NetBeans XML module, but, that seams to be a bit overkill! There must be something in the Vim plugin universe ;-) On second thought, I'll give a chance to Netbeans... Yeah, it works like a charm! Just open the argomanual.xml file and validate :-))

2005-09-16

New issues: C++ generator limitation, duplicated tags in ArgoUML and inaccuracies in the documentation readme

While working in the documentation of the C++ module I found that there exists a serious limitation in the way some tagged values are used. The problem is with tagged values for things that the modeler might want to introduce multiple times. An example is the header_incl tag which value is set to a file name that will be included in the header. Well, this is something that is typically done several times.

Although ArgoUML allows entering the same tag more than once with different values, its internals get confused and every tag disappears. I think that this qualifies as a bug and I'll try to fix it.

So, without the option to repeat the same tag several times with different values, one as the possibility to either use tag prefixes or assume some separation character in the tagged value value. I think the latest is better and will propose it in a possible fix.

TODO: create issue for ArgoUML allowing creation of duplicated tagged values.

TODO: create issue for C++ module use of some tagged values so that it allows multiple values to be specified.

TODO: submit the documentation readme corrections.

2005-09-10

I finished the test for DerivedFromAbstract.cxx translation unit and made a new test that looks for duplicates when reverse is repeated. The ModelerImpl now passes the tests defined in TestCppImport. I will now take some time off from implementing reverse engineering for C++ in ArgoUML and write the C++ module appendix of the ArgoUML user manual (issue #2857).

The ArgoUML documentation is written in the DocBook format. It takes the form of a group of XML files according to the DocBook XML. The cookbook explains very well this and I will try to follow those instructions. As stated above, the C++ module will be documented as an appendix, so, this means that I'll create a new XML file in /cvs/argouml/documentation/manual, which I'll name app_cppmod.xml. I'll try to keep the appendix simple, and mainly put in there the information for the code generation users. Latter I might ask collaboration from Daniele to review and add details regarding his new developments.

Thursday, August 18, 2005

Drop 1 updated plan - Version 5

2005-08-16

Much time went by without any news noted here. I've been working in the reverse engineering, having added a new translation unit (DerivedFromAbstract.cxx) that has more constructs to be reverse engineered to UML.

While at it, I've followed the work in the MDR implementation of the Model sub-system of ArgoUML. The developer who is more actively contributing is Ludo (Ludovic Maitre), who, among other things, proposed a GUI extensions model to enable ArgoUML to work with several UML versions. This is very interesting, as it would make ArgoUML more flexible, customizable and modular. The proposed approach to do it is documented in his post. I have sent a different proposal, MDA based, which I think would fit better to ArgoUML (see my post here).

These days ArgoUML development is more active than usual, with work progressing in several fronts. I hope that the interoperability provided by a MDR based implementation of the Model sub-system will attract even more newcomers and previous developers so that this community is boosted to a higher level!

That said, I must complete the TestCppImport.testParseFileDerivedFromAbstract() test case to start working with Daniele in a common UML profile for C++ that will be used in the module. Maybe if this is developed outside of the ArgoUML project, it might provide a great opportunity for experimentation - Maven instead of Ant - and for reuse outside of ArgoUML. The definition of this profile and its use in both the GeneratorCpp and the CppImport is very important for the documentation of the C++ module in the cookbook. It could be described as "the C++ generator uses the conventions defined in the UML profile for C++ for generating C++ specific constructs, such as pointers and references".

2005-07-03

I delivered yesterday the first version that actualy includes reverse engineering. It reverses the SimpleClass.cpp file which is in the argouml/modules/cpp/tests/org/argouml/language/cpp/reveng directory. Sure, it is just a very limited part (even less than the tip of the iceberg), but, it shows that the reverse engineering work is progressing and that the full concept works! So, now I must re-plan, introducing what I already know about the future work. This is an update to the previous version of the plan.

5th version of the plan for C++ reveng drop 1

  1. Learn how to make the ANTLR parser for debugging and build one.
    Estimated Effort (EE) = 4 Mh; Short Name (SN) – ANTLR parser 4 debugging

    2005-02-25 DONE – Although not actually a fully debug enabled parser, but, using the trace capabilities of the ANTLR generator. Note that this makes the parsing much slower and is only usable with small files!
    Actual Effort (AE) = 2:36

  2. Debug the C++ grammar and make it pass the tests.
    EE = 20 Mh (see bellow); SN – Fix the C++ grammar

    2005-03-07 PARTIAL – It parses cleanly a simple class and a code snippet with which I was attempting to reproduce the current error in parsing of quadratic.i.
    AE = 2:51

    2005-05-13 PARTIAL – I've postponed fixing the parsing of quadratic.i, since it seams to be complex to solve. Instead, I've started to fix the grammar in order to provide the parsed information to the Modeler. The test case TestCppGrammar.testGrammarCallbacks2Modeler() shows the partial fix. This problem makes the effort estimation for this to change in a dramatic way, since it introduces a huge amount of work that must be done.
    New EE = 140 Mh
    AE = 15:54 Mh

  3. Commit the result of this work and send it to Yolanda. Update the issue.
    EE 3 Mh; SN – Commit, Yolanda and issue

    2005-03-09 DONE – I committed the work in progress and updated the issue. Due to the release of a stable version of ArgoUML the work was committed in branch cpp_reveng_work_while_0_18_release. I only sent to Yolanda an e-mail of thanks. I'll send her the version that will be sent to the ANTLR list.
    AE = 1:36

  4. 2nd re-planning of C++ reveng drop 1
    EE 2 Mh; SN – 2nd re-planning of C++ reveng drop 1

    2005-03-12 DONE – Re-planned and updated the ProcessDashboard phases.
    AE = 1:39

  5. Update the model to reflect the new package and the grammar use.
    EE = 2 Mh; SN –Module model update for the C++ grammar

    2005-03-16 DONE – Updated and committed.
    AE = 2:14

  6. Make tests that show how the parsed information may be used for reveng. If some issue exist, analyze how it is done in java reveng and fix the grammar as needed. This includes creating, or improving the current, test cases, which prove how the parsed information may be used for reveng.
    EE 5 Mh; SN – Prove that parsed information is useful for reveng

    2005-03-18 DONE – a big issue exists, as documented in the above step.
    AE = 1:47 Mh

  7. Planning of C++ reveng drop 1. This task includes all the subsequent plan updates of drop 1, instead of having the planning tasks spread throughout the plan. I estimate I'll have 3 more plan updates, including the final, in the end of drop 1.
    EE 6:00 Mh; SN – Planning of C++ reveng drop 1

    2005-05-13 PARTIAL – 4th version (3rd update) of the plan.
    AE = 1:25

    2005-07-03 PARTIAL – 4th update of the plan (5th version).
    AE = 3:15

  8. Model the implementation of org.argouml.application.api.PluggableImport interface in the C++ reveng module. Generate the realization of the designed classes. If there are issues in the generation, report them in issuezilla.
    EE 5 Mh; SN – Model and generate the realization of the PluggableImport interface

    2005-05-20 PARTIAL – the model contains this and ArgoUML was used to generate the implementation skeleton. I found issues in the generation, but, didn't report them, so, this isn't finished.
    AE = 3:22

  9. Close the circle, by making the module support reveng of preprocessed C++ files.
    EE 15 Mh; SN – Module support of reveng of preprocessed C++

    2005-07-02 DONE – The module now reverses the argouml/modules/cpp/tests/org/argouml/language/cpp/reveng/SimpleClass.cpp file. I consider this a proof that the circle is closed. The work is far from finished though, so, we need to add more steps, related to what I learned while making this part of the work...
    AE = 9:45

  10. A warning popup box must be shown to the user, warning him about the limitations of the C++ reveng module. This happens when the user selects C++ in the drop down box of the "Import Sources..." dialog. (If this turns out to be difficult, the popup may be shown just before doing the import, when the CppImport.parseFile(xxx) method is called.) It provides an option for the warning to be shut down forever. Even if the user doesn't select it, the CppImport instance will remember that the warning was shown and will not repeat it as long as it "lives".The warning should be self explainable, but, may also direct the user to the manual section that describes the C++ modules functionality (see bellow related issue).
    EE 6 Mh; SN – Warning pop-up about the C++ reveng limitations

  11. Extend the C++ translation unit files used in the tests to contain a representative C++ sub-set. These files must contain a basic subset of C++ that is the one used by a person the learning C++. They aren't fancy examples of the powerful language C++ is! All should be compilable with gcc > 2.9x and VC++ 6. All are translation units.
    EE 8 Mh; SN – Extend C++ translation unit test files

  12. Support clean reveng of the test C++ translation units. This will obviously be the driver task that will require the UML profile for C++ and the Fix the C++ Grammar steps to move forward. I'll consider that as soon as this is finished, the other two will also. This step is dependent of the template support in ArgoUML issue.
    EE 30 Mh; SN – Support reveng of test C++ translation units

  13. Develop a UML profile for C++. It should be as much as needed, but, contains everything that is needed to model the elements that are contained in the C++ subset that will mark the capabilities of the module (see above). [Check my note above regarding this step.]
    EE 20 Mh; SN – Develop a UML profile for C++

  14. Send a working vanilla version of the grammar to the ANTLR list and announce its use within the ArgoUML project. Provide feedback as appropriate. Automate the adaption of the files in the module build script.
    EE 5 Mh; SN – Send grammar 2 ANTLR list

  15. Enjoy and celebrate the achievement! Go back to planning next drops.
    EE 4 Mh; SN – Plan next drops

Some of the above steps depend of two of the following issues. These, obviously must be tackled on their own.

Monday, June 20, 2005

ModelerImpl and new MDA ideas

2005-06-20

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.

2005-06-17

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 ;-))

2005-06-16

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

2005-06-14

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...

2005-06-09

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!

2005-06-06

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...

2005-06-03

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 org.argouml.uml.ui.foundation.core.UMLModelElementStereotypeComboBoxModelclass is used in org.argouml.uml.ui.foundation.core.PropPanelModelElement 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 (ru.novosoft.uml.foundation.extension_mechanisms.MStereotype)! 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 =
            ProjectManager.getManager().getCurrentProject().getModels();
        addAllUniqueModelElementsFrom(
           elements,
           paths,
           Model.getExtensionMechanismsHelper()
                .getAllPossibleStereotypes(models, elem));
        setElements(Model.getExtensionMechanismsHelper()
           .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 : http://java.sun.com/
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!

2005-06-01

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

2005-05-31

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.

2005-05-25

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.

Tuesday, May 24, 2005

PluggableImport implementation and 4th plan update of reveng drop 1 (also some new ideas)

2005-05-23

I finished reading the book The C++ Programming Language 3rd edition, by Bjarne Stroustrup, the creator of C++. This was one important step to master this language. Previously I read introductory books by Bruce Eckel, which put me on track, but, having read Stroustrup's book was needed in order to have a definite understanding of the language. One thing I may regret was not having solved the exercises. At least I should have solved a selection of three or four per chapter.

So, next steps? I think that continuing with the work in the C++ module is a nice complement to the book. After reverse engineering is working satisfactorily, working in a C++ profile, which makes the standard library available to be used in models, is something that would naturally make my knowledge improve. I could also get involved in an open source project where C++ is the language of implementation. Another possibility is to work in the Doer enterprise pattern. We'll see...

2005-05-20

htmled, the handbook editor blog and publisher

I take notes in my personal programming handbook. This handbook is digital and written in HTML. It is from the handbook notes that I create the Argonaut's life blog. It isn't something that takes much effort, but, this is the kind of repetitive task that I, as a Software Engineer, should consider for automation. Doing it manually is boring and error prone.

Previously I considered automating the edition of my handbook. My idea is to write a plugin for eclipse or a module for Netbeans, where all the things I make manually while adding content in the handbook automated. Also automated is the task of copying and adapting content from the handbook to the blog.

The handbook as a different structure from the blog, since I normally write top down and it is usually offline. The storage is as HTML files, and I try to keep these files under 100 KB. In the blog the last entry is made in the top of the page. It contains some automation that archives previous entries by month or year. Pictures and files aren't allowed and so I store them in my website. Also, I must take care to change the links I make internally and also to censor some parts of the handbook that I don't want to publish.

In a perfect solution, I would edit my handbook, creating entries and changing others within the IDE, while I work in ArgoUML or some other thing. I have support for automating some specific tasks, such as entering portuguese accentuation. It enables easy adding linking of content, distinguishing internal (within the handbook), local (within my PC) and external links. It must provide many of the basic functionalities of Web editors, but this isn't very important, since I'm comfortable with working in HTML source.

When I go online (yes, I'm not always connected!) and want to put some content in the blog, it will connect to the blog, discover what is changed and update it. The parts in my handbook I've marked as censored would not go online. A nice to have is for the plugin to warn me about some new comments and bring, as in a inbox scheme, show the headers and a small preview and allow me to see what people have been saying.

So, as with everything, I'm lazy and I should look for something that already exists, so that I may get back to my C++ module. Since I'm right now in the train, it will have to wait for some future opportunity.

CppImport: some notes on the current state of the implementation

I previously wrote that this is done. It is just partially done. There are issues which I documented in the source file as TODOs. These are easily detect by the IDE and I will remember about them, but, I shouldn't write things that aren't true, hiding future work.

Check spelling in Vim

I use Vim for many things. Most importantly to write these words. Since English isn't my mother language I have to check spelling after writing. This I do in the Mozilla Composer. This isn't very productive, so, is it possible to do it in Vim?

TODO

Another possibility would be to tweak the Mozilla Composer until it makes the editing as it should be: configurable, respectful of source code formating, support for automation, etc. The main reason I always rejected using these WYSIWYG editors since they make such a bad HTML source! Maybe its the time for me to make them the way I want!

ModelerImpl: starting-up

Now I'm going to start to put the parsed information into the model. After the grammar, this will be the hardest part of this issue. A Modeler implementation must:

  • understand very well the C++ syntax and semantics
  • 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
  • model C++ in UML according to guidelines accepted in common by the community –
  • be flexible, i.e., it should be possible to configure it according to the user's preferences

2005-05-16

Starting with PluggableImport implementation

So, going ahead with this... I already found some problems with the java generator:

  • The java generator doesn't generate the standard javadocs correctly. I will try to fix this, but, first I must report it in an issue.
  • I must find a way to use the generator with a template, or make it more customizable. If there exist the chance for this I must know about it. The manual doesn't contain description of this possibility. Alas, it doesn't have anything describing specifically the java code generation... I'm going to look in the GeneratorJava source for possible hints... At least from what I see in the generateHeader method, this is marked as a TODO. It seams I have an opportunity to do work both in the java generator and in the C++ generator, which from the readme.txtfile seams to be ahead.

Now, I have the CppImport implementation, but, the module only publicizes the GeneratorCpp class and therefore the org.argouml.application.modules.ModuleLoader doesn't find it. One question remains to be answered: is it possible to have two modules in one jar file? If so, then I may just make the needed adjustments in the manifest file of the C++ module. If not I may have to implement a facade that implements both modules and delegates according to the appropriate methods, but, this will be messy. By adding a new entry group with Name: org/argouml/language/cpp/reveng/CppImport.class to the manifest it already works. Nice :-))

OK, apart from reporting the issues above (and probably working in fixing them), this is finished. So, proceeding with the next step.

2005-05-13

I finished today a initial part of fixing the grammar – to provide information from parsing to the Modeler. Instead of proceeding right now with a complete fix I'll address another area of the drop 1 plan, start the implementation of PluggableImport.

But before I'll update the plan according to the execution evolution.

4th version of the plan for C++ reveng drop 1

This is a plan update that is less radical than the previous one, but, reflects the improved knowledge I have on the scope of the problem. I'll update the efforts, both the estimated and the actual until now.

  1. Learn how to make the ANTLR parser for debugging and build one. Estimated Effort (EE) = 4 Mh; Short Name (SN) – ANTLR parser 4 debugging

    2005-02-25 DONE – Although not actually a fully debug enabled parser, but, using the trace capabilities of the ANTLR generator. Note that this makes the parsing much slower and is only usable with small files! Actual Effort (AE) = 2:36

  2. Debug the C++ grammar and make it pass the tests. EE = 20 Mh (see bellow); SN – Fix the C++ grammar

    2005-03-07 PARTIAL – It parses cleanly a simple class and a code snippet with which I was attempting to reproduce the current error in parsing of quadratic.i. AE = 2:51

    2005-05-13 PARTIAL – I've postponed fixing the parsing of quadratic.i, since it seams to be complex to solve. Instead, I've started to fix the grammar in order to provide the parsed information to the Modeler. The test case TestCppGrammar.testGrammarCallbacks2Modeler() shows the partial fix. This problem makes the effort estimation for this to change in a dramatic way, since it introduces a huge amount of work that must be done. New EE = 140 Mh AE = 15:54 Mh

  3. Commit the result of this work and send it to Yolanda. Update the issue. EE 3 Mh; SN – Commit, Yolanda and issue

    2005-03-09 DONE – I committed the work in progress and updated the issue. Due to the release of a stable version of ArgoUML the work was committed in branch cpp_reveng_work_while_0_18_release. I only sent to Yolanda an e-mail of thanks. I'll send her the version that will be sent to the ANTLR list. AE = 1:36

  4. 2nd re-planning of C++ reveng drop 1 EE 2 Mh; SN – 2nd re-planning of C++ reveng drop 1

    2005-03-12 DONE – Re-planned and updated the ProcessDashboard phases. AE = 1:39

  5. Update the model to reflect the new package and the grammar use. EE = 2 Mh; SN –Module model update for the C++ grammar

    2005-03-16 DONE – Updated and committed. AE = 2:14

  6. Make tests that show how the parsed information may be used for reveng. If some issue exist, analyze how it is done in java reveng and fix the grammar as needed. This includes creating, or improving the current, test cases, which prove how the parsed information may be used for reveng. EE 5 Mh; SN – Prove that parsed information is useful for reveng

    2005-03-18 DONE – a big issue exists, as documented in the above step. AE = 1:47 Mh

  7. Planning of C++ reveng drop 1. This task includes all the subsequent plan updates of drop 1, instead of having the planning tasks spread throughout the plan. I estimate I'll have 3 more plan updates, including the final, in the end of drop 1. EE 6:00 Mh; SN – Planning of C++ reveng drop 1

    2005-05-13 PARTIAL – 4th version (3rd update) of the plan. AE = 1:25

  8. Model the implementation of org.argouml.application.api.PluggableImport interface in the C++ reveng module. Generate the realization of the designed classes. If there are issues in the generation, report them in issuezilla. EE 5 Mh; SN – Model and generate the realization of the PluggableImport interface

  9. Close the circle, by making the module support reveng of preprocessed C++ files. EE 15 Mh; SN – Module support of reveng of preprocessed C++

  10. Send a working vanilla version of the grammar to the ANTLR list and announce its use within the ArgoUML project. Provide feedback as appropriate. Automate the adaption of the files in the module build script. EE 5 Mh; SN – Send grammar 2 ANTLR list

  11. Enjoy and celebrate the achievement! Go back to planning next drops. EE 4 Mh; SN – Plan next drops

2005-05-10

I have some strange errors when parsing the SimpleClass::newAttr declaration. For some reason it isn't reported from the parser as was the SimpleClass::newOperation declaration...

2005-05-04

MDA based programming languages specification and development

While developing the C++ module for ArgoUML I started to think about how many repetitive and low level work I would have to make the yet-to-start Python module. How about the amount of work that would go to maintain the java and classfile modules? This is something that should be better supported within ArgoUML than to just provide a template, e.g., the dummylanguage and existing implementations. We could provide some MDA support for this kind of work, such as the possibility of specifying a PIM of the language support module, with Generator, Importer – for reverse engineering – and Synchronizer – for Round Trip Engineering (RTE) (this one is dependent of the other two being available) – as components. This Platform Independent Model (PIM) would then be transformed into the PSM that would target ANTLR based reverse engineering, a StringTemplate based code generator and a common generic GUI based synchronization. This would make life a lot easier for the development of language support modules and would also, hopefully, provide more reuse opportunities out of this development!

This idea led me to yet another bigger, which is, how about taking a Model Driven Architecture (MDA) approach to the specification and development of programming languages? This would imply having reverse engineering of programming language grammars into a UML profile for language grammars. Then we could define a MDA transformation between the Computation Independent Model (CIM) which is the MOF based grammar model for a given programming language into PIMs that would be based in a UML profile for doing something with the specified language. We could define a PIM for compilers, another for RTE of the language in the context of a Model Driven Design (MDD) tool like ArgoUML, and another for Integrated Development Environment (IDE) support of the tool. These PIMs could then be transformed into PSMs for specific targets, e.g, respectively the Jython compiler, the ArgoUML python module, and the eclipse plugin for python or Jython support within eclipse.

For this idea to work a MOF based domain language must be specified to enable the specification of programming language grammars in a MOF repository. We would also need the support for including semantics of the language constructs to the CIMs. For this we could use a ontology that would be used to enrich the CIMs. This ontology may be based on something existing or something based in the UML spec.

2005-05-03

I'm now delving deep into changing the grammar to make the needed info available to the Modeler. The header and implementation files aren't available since the parser works with the translation units therefore the modeling of source file components will be left out for now.

2005-05-02

Updated issue #2947 – support for C++ reverse engineering to include the details of the merge and about the option taken retrieve information from the parsing of files.

2005-05-01

I have created the following issues for problems I found previously:

I'm going to commit the work in progress to the branch cpp_reveng_work_while_0_18_release and, since the 0.18 release is done, merge the branch into the HEAD. After that I'll continue development in the HEAD.

2005-04-20

The interface will be defined outside of the grammar. This will provide a compile time verification between the grammar and what is expected. It will also enable future independence if the current grammar and parser design is replaced. So, lets use ArgoUML a bit to model...

2005-04-19

The successful test org.argouml.language.cpp.reveng.TestCppGrammar.testCastExpressions proves that something is wrong in the grammar, but, that this isn't obvious. I can't reproduce the error with a small example of what is failing to be parsed – the CastExpressions.cpp file. Being so, I'll proceed to the next part of the fixing the grammar task, to create a generic modeler interface that is called from the grammar.

Tuesday, April 19, 2005

fixing the grammar II

2005-04-18

I'm going to give a try with ANTLR 2.7.5 again. Maybe the error wasn't related to 2.7.5 and due to the state ArgoUML was when I attempted revenging of commons logging. When testing with 2.7.2 it was in the initial state...

Nope, it is there... Here is a piece of the stack trace:

  [argouml] Exception in org/apache/commons/logging/Log.class : null
[argouml] java.lang.NullPointerException
[argouml]     at org.argouml.uml.reveng.classfile.ClassfileParser.u4(ClassfileParser.java:490)
[argouml]     at org.argouml.uml.reveng.classfile.ClassfileParser.magic_number(ClassfileParser.java:287)
[argouml]     at org.argouml.uml.reveng.classfile.ClassfileParser.classfile(ClassfileParser.java:258)
[argouml]     at org.argouml.uml.reveng.classfile.ClassfileImport.parseFile(ClassfileImport.java:358)
[argouml]     at org.argouml.uml.reveng.classfile.ClassfileImport.processJarFile(ClassfileImport.java:276)
[argouml]     at org.argouml.uml.reveng.classfile.ClassfileImport.processFile(ClassfileImport.java:228)
[argouml]     at org.argouml.uml.reveng.classfile.ClassfileImport.startImport(ClassfileImport.java:113)
[argouml]     at org.argouml.uml.reveng.classfile.ClassfileImport.parseFile(ClassfileImport.java:95)
[argouml]     at org.argouml.uml.reveng.Import.parseFile(Import.java:431)
[argouml]     at org.argouml.uml.reveng.Import$ImportRun.run(Import.java:582)
[argouml]     at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:178)
[argouml]     at java.awt.EventQueue.dispatchEvent(EventQueue.java:454)
[argouml]     at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:201)
[argouml]     at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:151)
[argouml]     at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:141)
[argouml]     at java.awt.Dialog$1.run(Dialog.java:540)
[argouml]     at java.awt.Dialog.show(Dialog.java:561)
[argouml]     at org.argouml.uml.reveng.Import.doFile(Import.java:399)
[argouml]     at org.argouml.uml.reveng.ImportClasspathDialog.doFiles(Import.java:935)
[argouml]     at org.argouml.uml.reveng.ImportClasspathDialog.access$200(Import.java:855)
[argouml]     at org.argouml.uml.reveng.ImportClasspathDialog$OkListener.actionPerformed(Import.java:968)
[argouml]     at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1786)
[argouml]     at javax.swing.AbstractButton$ForwardActionEvents.actionPerformed(AbstractButton.java:1839)
[argouml]     at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:420)
[argouml]     at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:258)
[argouml]     at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:245)
[argouml]     at java.awt.Component.processMouseEvent(Component.java:5100)
[argouml]     at java.awt.Component.processEvent(Component.java:4897)
[argouml]     at java.awt.Container.processEvent(Container.java:1569)
[argouml]     at java.awt.Component.dispatchEventImpl(Component.java:3615)
[argouml]     at java.awt.Container.dispatchEventImpl(Container.java:1627)
[argouml]     at java.awt.Component.dispatchEvent(Component.java:3477)
[argouml]     at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:3483)
[argouml]     at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3198)
[argouml]     at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3128)
[argouml]     at java.awt.Container.dispatchEventImpl(Container.java:1613)
[argouml]     at java.awt.Window.dispatchEventImpl(Window.java:1606)
[argouml]     at java.awt.Component.dispatchEvent(Component.java:3477)
[argouml]     at java.awt.EventQueue.dispatchEvent(EventQueue.java:456)
[argouml] Exception in org/apache/commons/logging/LogConfigurationException.class : null
[argouml]     at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:201)
[argouml]     at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:151)
[argouml]     at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:145)
[argouml]     at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:137)
[argouml]     at java.awt.EventDispatchThread.run(EventDispatchThread.java:100)

So, to fix the C++ grammar, the first thing to do is to show what the error is:

testParseQuadratic Error unexpected token: (

line 5960:25: unexpected token: (
at org.argouml.language.cpp.reveng.CPPParser.unary_expression(Unknown Source)
at org.argouml.language.cpp.reveng.CPPParser.cast_expression(Unknown Source)
at org.argouml.language.cpp.reveng.CPPParser.pm_expression(Unknown Source)
at org.argouml.language.cpp.reveng.CPPParser.multiplicative_expression(Unknown Source)
at org.argouml.language.cpp.reveng.CPPParser.additive_expression(Unknown Source)
at org.argouml.language.cpp.reveng.CPPParser.shift_expression(Unknown Source)
at org.argouml.language.cpp.reveng.CPPParser.relational_expression(Unknown Source)
at org.argouml.language.cpp.reveng.CPPParser.equality_expression(Unknown Source)
at org.argouml.language.cpp.reveng.CPPParser.and_expression(Unknown Source)
at org.argouml.language.cpp.reveng.CPPParser.exclusive_or_expression(Unknown Source)
at org.argouml.language.cpp.reveng.CPPParser.inclusive_or_expression(Unknown Source)
at org.argouml.language.cpp.reveng.CPPParser.logical_and_expression(Unknown Source)
at org.argouml.language.cpp.reveng.CPPParser.logical_or_expression(Unknown Source)
at org.argouml.language.cpp.reveng.CPPParser.conditional_expression(Unknown Source)
at org.argouml.language.cpp.reveng.CPPParser.assignment_expression(Unknown Source)
at org.argouml.language.cpp.reveng.CPPParser.expression(Unknown Source)
at org.argouml.language.cpp.reveng.CPPParser.jump_statement(Unknown Source)
at org.argouml.language.cpp.reveng.CPPParser.statement(Unknown Source)
at org.argouml.language.cpp.reveng.CPPParser.statement_list(Unknown Source)
at org.argouml.language.cpp.reveng.CPPParser.compound_statement(Unknown Source)
at org.argouml.language.cpp.reveng.CPPParser.function_definition(Unknown Source)
at org.argouml.language.cpp.reveng.CPPParser.member_declaration(Unknown Source)
at org.argouml.language.cpp.reveng.CPPParser.class_specifier(Unknown Source)
at org.argouml.language.cpp.reveng.CPPParser.type_specifier(Unknown Source)
at org.argouml.language.cpp.reveng.CPPParser.declaration_specifiers(Unknown Source)
at org.argouml.language.cpp.reveng.CPPParser.declaration(Unknown Source)
at org.argouml.language.cpp.reveng.CPPParser.external_declaration(Unknown Source)
at org.argouml.language.cpp.reveng.CPPParser.decl_namespace(Unknown Source)
at org.argouml.language.cpp.reveng.CPPParser.external_declaration(Unknown Source)
at org.argouml.language.cpp.reveng.CPPParser.translation_unit(Unknown Source)
at org.argouml.language.cpp.reveng.TestCppGrammar.parseFile(TestCppGrammar.java:116)
at org.argouml.language.cpp.reveng.TestCppGrammar.testParseQuadratic(TestCppGrammar.java:92)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at junit.framework.TestCase.runTest(TestCase.java:166)
at junit.framework.TestCase.runBare(TestCase.java:140)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:131)
at junit.framework.TestSuite.runTest(TestSuite.java:173)
at junit.framework.TestSuite.run(TestSuite.java:168)
at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.run(JUnitTestRunner.java:231)
at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(JUnitTestRunner.java:409)
1.23

The parser complains about the line 5960, column 25 of quadratic.i. Which is (marked in red):

                {return ((char)_Narrow((_E)(_C))); }

Well, this is perfectly legal C++. So, lets try to fix it!

2005-04-14

Log4j configurations should have date

I previously solved this problem. The original text might be used to create an issue. I'll have to make a diff to apply the patch.

Fixing the C++ grammar

Upgrading to ANTLR 2.7.5 didn't fixed the problem as I expected. It also doesn't seam to have broken anything, even for the java and classfile modules. I must now make some manual tests to make sure.

The java reveng works fine with ANTLR 2.7.5, but, the classfile reveng failed when parsing the commons logging jar. I must check if the same happens with ANTLR 2.7.2... So, I must get back to the default.properties and revert the change to antlrall.jar.path to use the 2.7.2 jar. Then argouml/src_new/$ ./build.sh clean package argouml/modules/classfile/$ ant clean install argouml/src_new/$ ./build.sh run and test reverse engineering again commons-logging.jar.

And it works! So, something is going wrong when the ANTLR 2.7.5 is used... Since it didn't fixed the problem with C++ parser, I'll stick with version 2.7.2 and maybe create an issue for upgrading with the information that it breaks the classfile reveng.

2005-04-12

After discovering that I had to make some work on the grammar to enable reveng, I been off of development for some time. Now its time to get back and grab this issue!

Fixing the C++ grammar

I think that before starting to change the grammar by adding callbacks to the grammar, to support reverse engineering as the original C++ and java grammars do, I must fix the grammar. Mainly because I think the problems it has to parse the quadratic.i file are related to ArgoUML using an old version of ANTLR. So, to try to fix this I must use the current version of ANTLR to generate the parsers. I may try to replace the global ANTLR instead of adding the newer version to the C++ module.

[It would be nice, though, to try to check if ArgoUML module runtime model handles several versions of the same libraries. But, I think I should not open this new front of work!...]

Wednesday, March 30, 2005

half way to drop 1

2005-03-18

After looking a bit into the grammar I realized that it is only parsing the information! It doesn't store it in a AST for later processing. So, this means that currently there isn't parsed information! It isn't this that would make me throw away the current grammar. The main problem is parsing the information and that is being done in a very good way, as is shown in the current working tests!

Just for curiosity I'll look at the original C++ grammar by David Wigg et all... It uses the a similar scheme to the one used in the java grammar. The parser makes calls at specific places in the grammar, in order to have the information processed along with the parsing. The C++ grammar defines abstract methods which are implemented in some specialized parser class. For java reveng, the Modeller class gets called by the parser.

It is interesting to see that neither uses the AST functionalities of ANTLR. I wonder why? Maybe its because these grammars were implemented in a pre-AST time...

After looking into the grammar I now understand that I don't need to remove the pre-processor directives in quadratic.i. So, I'm going to use the original version that comes with the "official" C++ grammar.

I should consider ways to have the official C++ grammar reused instead of having a specific version that will be very difficult to integrate improvements when they are introduced in the David Wigg's grammar. A possible way, if they are interested would be to have some special tags that would be pre-processed previous to the grammar being handed over to the ANTLR for code generation. Maybe even ANTLR makes this task easy! It would be nice to have a unique grammar that would be used with C++, java and python programs! I must consider this when I send the grammar to the ANTLR list.

It is nice to see that the ANTLR project also makes a big effort to be multi-language. The examples provided in the distribution show that the type of multi-language support buit-in in one grammar is possible. In the future I must check how this is being done and try to have the C++ grammar this way!

Fixing the C++ grammar

I think I know why the quadratic.i parsing fails! The version of ANTLR being used in ArgoUML is 2.7.2, while the version that David Wigg was using when he commited the last version of the grammar was 2.7.3. Current version is 2.7.5. So, the way to go would be to at least try the ported grammar with 2.7.3 and check if that is the problem...

Some very interesting news! There exists a grammar for C pre-processor for java programs in ANTLR 2.7.5 distribution. This fits perfectly my needs! :-))

2005-03-16

The module model is now updated to show the use of the ANTLR C++ grammar and commited. I'll proceed to the next step.

2005-03-14

I've been bitten by the infamous zargo corruption bug while editing the C++ module model. Fortunately, I committed the previous version of the model in CVS, and this way I may revert to that version. The ArgoUML version I was using was 0.17.2, which is not advisable for production, as you may see in this report of mine...

Since I'm a developer for ArgoUML, I thought I could look into the log and try to figure out what was the relevant part to report the problem back to ArgoUML. Unfortunately, the log isn't configured to save the date as part of the traces... This I think qualifies as a bug and therefore is a possible fix for me to contribute.

So, I have these two identified problems in ArgoUML, which I must obviously help in being solved. I'll create issues and try to fix them.

  • log4j configurations should have time with traces – This is very simple, I just need to add "%d" to the pattern in the log4j configuration files, which are in /argouml/src_new/org/argouml/resource. For configurations that are for ConsoleAppender, the date isn't relevant, since the user will see the output in the console and don't need to distinguish between several working sessions in a log file. The main changes are in default.lcf and full.lcf.
  • ArgoUML must support by default UML foundation types

2005-03-12

The plan must be updated to be more flexible. I already know that I have a parser that is capable of parsing simple files. This is a very important first step and I don't want to loose momentum by attempting to have a perfect parser that correctly parses more complex files, like quadratic.i. So, instead of spending all effort in Fixing the C++ grammar, I'll move forward into using the information parsed for some useful thing. To enable this I'm going to make some analysis and design on how can I do this. This is still part of the Fix the C++ grammar step of the plan, although the name won't indicate this. I would call it now as a different step called analysis of how to use the parsed information.

For this I may check again what the java reveng does and maybe model it a bit in the C++ model... After that I'll make a new test case that explores the information contained in a parsed file. When this is done I may make the model of the C++ grammar and parser.

3rd plan for C++ reveng drop 1

  1. Learn how to make the ANTLR parser for debugging and build one. Estimated Effort (EE) = 4 Mh; Short Name (SN) – ANTLR parser 4 debugging

    2005-02-25 DONE – Although not actually a fully debug enabled parser, but, using the trace capabilities of the ANTLR generator. Note that this makes the parsing much slower and is only useable with small files! Actual Effort (AE) = 2:36

  2. Debug the C++ grammar and make it pass the tests. EE = 20 Mh; SN – Fix the C++ grammar

    2005-03-07 PARTIAL – It parses cleanly a simple class and a code snippet with which I was attempting to reproduce the current error in parsing of quadratic.i. AE = 2:51

  3. Commit the result of this work and send it to Yolanda. Update the issue. EE 3 Mh; SN – Commit, Yolanda and issue

    2005-03-09 DONE – I commited the work in progress and updated the issue. Due to the release of a stable version of ArgoUML the work was commited in branch cpp_reveng_work_while_0_18_release. I only sent to Yolanda an e-mail of thanks. I'll send her the version that will be sent to the ANTLR list. AE = 1:36

  4. 2nd re-planning of C++ reveng drop 1 EE 2 Mh; SN – 2nd re-planning of C++ reveng drop 1

    2005-03-12 DONE – Re-planned, updated the ProcessDashboard phases and documented it all here ;-). AE = 1:39

  5. Update the model to reflect the new package and the grammar use. EE = 2 Mh; SN – Module model update for the C++ grammar

    2005-03-16 DONE – Updated and commited. AE = 2:14

  6. Make tests that show how the parsed information may be used for reveng. If some issue exist, analyse how it is done in java reveng and fix the grammar as needed. This includes creating, or improving the current, test cases, which prove how the parsed information may be used for reveng. EE 5 Mh; SN – Prove that parsed information is useful for reveng

  7. Model the implementation of org.argouml.application.api.PluggableImport interface in the C++ reveng module. Generate the realization of the designed classes. If there are issues in the generation, report them in issuezilla. EE 5 Mh; SN – Model and generate the realization of the PluggableImport interface

  8. Close the circle, by making the module support reveng of preprocessed C++ files. EE 15 Mh; SN – Module support of reveng of pre-processed C++

  9. Send a working vanilla version of the grammar to the ANTLR list and announce its use within the ArgoUML project. Provide feedback as appropriate. Automate the adaption of the files in the module build script. EE 5 Mh; SN – Send grammar 2 ANTLR list

  10. Enjoy and celebrate the achievement! Go back to planning next drops. EE 4 Mh; SN – Plan next drops

Why do I spend so much time planning? Why do I measure with such care the time I spend in my hobby? Why do I document the whole stuff so meticulously?

Friday, March 11, 2005

First C++ parser commit and type bug

2005-03-08

With the upcoming 0.18 release of ArgoUML, I looked into the issues reported and fixed by Daniele Tamino, in order to verify the fixes. It is all working fine and therefore many of the issues are now verified.

I think that I will check tomorrow a way to commit my current work for reveng in a branch... DONE Sent also an e-mail of thanks to Yolanda.

2005-03-04

The quadratic.i test file can't be taken as made available from the original ANTLR C++ grammar (the one for C++ output). It contains pre-processor lines, which in the TestCppGrammar test case aren't removed before handing it to the lexer. It isn't a problem. I removed these lines with a simple python script and I'm now debugging the grammar with this modified file. It contains some problems, which I think I will handle by debugging the grammar in additional test cases with just the needed code snippets to make it fail.

2005-02-25

The parser must really be built for debug to enable debugging! This parser isn't just my class, it is the antlr.Parser class! So, I'm going to use just the ANTLR generation options for tracing: -traceParser and -traceLexer. It is working, but, I'm going to start with the SimpleClass.cpp test first because the quadratic.i example from the ANTLR C++ grammar is way too complicated to start with.

The grammar works! :-)) It parsed SimpleClass.cpp as soon as I fixed it (removed the boolean)! I must test with quadratic.i, since previously the Ant target was failing because I wasn't copying the files to the build dir 8-!

New Bug: C++ generator is generating code with java types.

I've noticed a new bug in the C++ generator. ArgoUML enables selection of some built-in types according to the java language. One of these is the boolean, which is generated as boolean instead of bool. I bet this is happening for other types as well...

What should be happening is that ArgoUML enables selection of the standard UML types:

  • Boolean – it does enable the java.lang.Boolean, but, this still is java specific.
  • Integer – same as for Boolean, i.e., java.lang.Integer
  • ... all the types are java!!! No UML types?!

I must create an issue for this... Actually two, one for the global ArgoUML to enable UML types by default and another for the C++ module to give warnings when java specific types are used and to translate these types to C++ types. It should also enable the use of specific C++ types, adding them, just as java does. This might be done with a XMI file made available to users for importing or by some option, which make available the use of either UML types, java types, C++ types or some other...

Another possible addition is to have a critic that warns users about the possibility of using java types in non-java specific models. Maybe having a model nature as a tag would be a nice thing that would disable such critic to be turned on. This model nature could later be extended so that only generic rules and specific language rules to be turned on. This might be applied also to packages etc.

Reader Shared items

Followers