Kevin Brightwell edited this page Aug 26, 2015 · 1 revision
Clone this wiki locally

Each UCOSP participant is asked to log all their accomplishments as well as the difficulties they have getting set up to understand Umple and other experiences they have. Difficulties might include understanding how to model in Umple, using UmpleOnline, code that is difficult to figure out, and development tools that are hard to figure out, or don't seem to work properly. The more log entries added the more we can better get a grip on the usability issues with Umple, and the more we can help future new contributors come up to speed. Mention issue numbers and revision numbers in your log to help create hyperlinks.

Log entries in reverse chronological order

December 4 2014

Hey guys! So, this is probably going to be my last log post for the semester. I wrapped everything up with a fix to the manual page (I'd added the composition rules to the grammar with the express purpose of referencing them in the man page, but I hadn't incorporated them into the grammar itself i.e. they weren't being used... Dr Lethbridge asked me to just reference the existing association and inlineAssociation rules, which is where the composition syntax is specified). This is revision r4820 (on Google Code). The links in my previous log post still stand for the manual page and example I added.

So... how to conclude? Well, for starters, this has been an amazing experience. Umple was a great project and I really enjoyed working on it, and with the development team. I learned a lot working on Umple! In addition to learning the workings of the project itself and how the code all fit together, working primarily on the back-end of Umple I ended up learning a lot about the functionality of grammars and compilers. I was also introduced to coding in php and ruby, and some of the web-coding javascript for the umpleonline section of my issue.

For future UCOSP students, this is what I found most important:

  • Linux is the best!! I used the terminal to find files, locate method calls, and to change multiple files at once. Knowing how to use the grep and find utilities was really helpful to figuring out how the code was structured and how it all fit together. Also, committing using the terminal was very straight-forward. I can't imagine having used Windows to work on Umple.
  • The examples on UmpleOnline were very useful to understanding the function of Umple and how Umple code translated into other languages. When some of my tests were failing, I would also create an Umple file and compile it on the command line with my generated jar file. Then I would not need to wait for the build to run to see what was going wrong.
  • The build takes a long time (at least, on my laptop - usually between 6 and 8 minutes). Instead of doing a full build every time, I found the builds of specific components were very time-saving. Mostly, I used the first build:
    ant -Dmyenv=local -f build.umple.xml first-build

The build for the template tests:

    ant -Dmyenv=local -f build.umple.xml compile template.test

And the build for the testbed tests:

    ant -Dmyenv=local -f build.testbed.xml
  • This past summer I worked in particle simulations in C++. Starting to work on this existing project with a large code base where I was completely unfamiliar with how it fit together and which code did what was pretty intimidating at the outset. But looking at one section of the code at a time, and tracing method calls back to their source, it breaks the project into more manageable pieces. I found the same thing starting on Umple at the beginning (just on a much larger scale!). Having already approached an unfamiliar code base made diving into Umple seem much less daunting.
  • Also, I'm so glad I took Capstone in my third year - now I know I enjoy working on/with compilers and parsers! I'm considering similar topics for my undergrad thesis next year.

For anyone working on Umple in the future - have fun!! Hopefully my log is helpful (at least to avoid some of the mistakes I made).

If anyone finds any issues in the future with any of the code I wrote (implementation of compositions), please let me know so I can take a look into fixing it!

Thank you! :)

November 30 2014

At this point I'm pretty much done my work for the semester! I wrote a manual page for compositions, which has been added to the umple manual (I've just made a quick update which I'll commit tomorrow once I have internet on my Ubuntu again).

The example I wrote to show compositions on umpleonline can be found at: CompositionsExample. This example just shows the general functionality of compositions and the difference between them and regular associations.

The manual page I added for compositions can be found at: CompositionsManPage. I've just added the syntax notation (and also adding it to the grammar, since it wasn't explicitly present earlier, just as a subset of associations), and an example of what a class diagram looks like with composition - this is the change I'll commit tomorrow.

I'll write another log post once I've finished everything up.

November 24 2014

So, I made an example to include in umpleonline to show how compositions work and what they are for. I included various multiplicities, and inline compositions as well as compositions defined outside a class. I also included examples of non-composition associations to try and be clear with the distinction.

It's a simple example with Building, Floor, and Room classes (deleting a Building deletes the floors, deleting a Floor deletes the rooms). It also includes a Person, which has a Room (but deleting the person does not delete the room), and a Vehicle (same logic here). The Vehicle is composed with Wheels, however, so deleting the Vehicle deletes the wheels. I made this commit this evening... the files are still in umpleonline/test and need to be promoted, but I'll post the link to the example once it's incorporated. If there are any other examples anyone would like to see, please let me know! This commit was revision r4796 (on Google Code) (minor typo fix from r4795 (on Google Code) ).

Now I'm working on a manual page for Compositions in UmpleManual. I'm going to put this page right after Reflexive Associations in the Associations tab. I'm planning to just write up a general explanation of what compositions are and what they are for, and include several examples.

Ok so, just some details about the process for editing the umple manual. I found the Readme file very helpful (build/reference/00ReadMe). I created a file 2007Compositions.txt in this same directory, which goes right after 2006ReflexiveAssociations.txt (the 2 is for Associations tab, and these files go in order i.e. 2006 is right before 2007). To compile the package docs, the command is

   ant -Dmyenv=local -f build.umple.xml packageDocs

run in the build directory. Then, to see the changes to the umple manual locally, run

   firefox <yourumpledir>/dist/cruise.umple/reference/GettingStarted.html

Currently, I'm writing the page about compositions and creating some basic examples to go with it.

I'll update with any progress!

November 20 2014

Just a quick update... I committed the changes to umpleonline a few days ago; so the composition arrow implementation is up and running. This is revision 4767 (on Google Code). Right now I'm just working on making an example or two for the sample examples on umpleonline, to show how composition works.

If anyone has anything else they'd like to see implemented for compositions, please email me and let me know!

I'll update with any changes/progress.

November 17 2014

Turns out the UML symbol for composition is actually a filled-in diamond, rather than an empty diamond <> as I was drawing before.

This is very simple to implement in GraphViz (just using diamond instead of ediamond for the arrowhead). However, the problem was a little more difficult to tackle in the editable class diagram. The functionality for rendering that I found for the editable diagrams was for drawing lines, and not for colouring in areas of the screen. I thought about creating an image of a filled diamond and placing this on the screen, like the class icon currently - however, the arrowhead has to be able to rotate to automatically adjust when the user moves the classes around. The fix I ended up coming up with is a bit of a hack - keeping the same code structure as previously, I still draw the empty diamond. I made more vertices, one on the midpoint of each line segment (so now there are 8 vertices). Then, I joined each vertex to every other vertex with a line (drawing the complete graph K8, in the shape of a diamond). Because there are so many lines, this fills the diamond. I made comments marking the code to fill the diamond, so in the future if/when anyone wants to implement the empty-diamond symbol, the code is all there.

I also wrote a test for my GraphViz composition drawings.

I'll commit my changes probably tomorrow - I'm just waiting on the all-clear from Karin to make sure I don't cause her any problems since we're editing the same files.

After this, I think I will create an example for the umpleonline sample examples, to show the functionality of composition. I'll update with any progress!

November 15 2014

Today I figured out how to get the association in the state diagram to register if it was a left or right composition, as opposed to the regular association. I had been focusing my previous efforts on the umple_association.js file in the umpleonline/scripts directory, since it is in this file that the isLeftNavigable and isRightNavigable are set, in the "constructor". I changed this file to update the isLeftComposition and isRightComposition also:

UmpleAssociationFactory.create = function(data)
  var umpleAssociation = new UmpleAssociation();
  umpleAssociation.id = data.id;
  umpleAssociation.isLeftNavigable = (data.isLeftNavigable == "true" || data.isLeftNavigable == true) ? true : false;
  umpleAssociation.isRightNavigable = (data.isRightNavigable == "true" || data.isRightNavigable == true) ? true : false;
  // I added the next 2 lines
  umpleAssociation.isLeftComposition = (data.isLeftComposition == "true" || data.isLeftComposition == true) ? true : false;
  umpleAssociation.isRightComposition = (data.isRightComposition == "true" || data.isRightComposition == true) ? true : false;
  umpleAssociation.color = data.isTraced;
  return umpleAssociation;

I also set these values to default to false in the "default constructor":

function UmpleAssociation()
  this.isLeftNavigable = true;
  this.isRightNavigable = true;
  // added these to specify compositions...
  this.isLeftComposition = false;
  this.isRightComposition = false;

I decided to first work on the Editable Class (as opposed to the GraphViz class, in terms of diagram types). I changed the draw function in umple_association.js so as to add an option for drawableComposition. My implementation is very similar to that for the directed association - where in a directed association, only one end of the arrow is drawn, I just continue and draw the other 2 sides to form more of a rhombus <> for compositions.

My problem was that the isLeftComposition and isRightComposition booleans were not being correctly set in the umple_association. I eventually traced this problem back to the Json templates - the JsonGenerator contains a section of code describing jsonForAssociations, which serves essentially as a template for what data from the umple association from the code gets stored in the umple_association.js and which is then translated to the class diagram. So, I edited the JsonGenerator (in Generator_CodeJson.ump) to now include data for left and right compositions:

   jsonForAssociations += StringFormatter.format("{\"offsetOnePosition\": {\"x\": {2}, \"y\": {3}, \"width\": 0, \"height\": 0}, \"offsetTwoPosition\": {\"x\": {4}, \"y\": {5}, \"width\": 0, \"height\": 0}, \"id\": \"{6}\", \"classOneId\": \"{0}\", \"classTwoId\": \"{1}\", \"multiplicityOne\": \"{7}\", \"multiplicityTwo\": \"{8}\", \"name\": \"{9}\", \"roleOne\": \"{10}\", \"roleTwo\": \"{11}\", \"isLeftNavigable\":\"{12}\", \"isRightNavigable\":\"{13}\", \"isLeftComposition\":\"{14}\", \"isRightComposition\":\"{15}\", \"isSymmetricReflexive\":\"{16}\", \"isTraced\":\"{17}\"}", c1.getName(), c2.getName(), x1, y1, x2, y2,associationId, multOne, multTwo, name, roleOne, roleTwo, aAssoc.getIsLeftNavigable(), aAssoc.getIsRightNavigable(), aAssoc.getIsLeftComposition(), aAssoc.getIsRightComposition(), "false", traceColor);

Now, the code for specifying the drawing of compositions works, since the composition is specified to the class drawing the class diagram.

I am currently running my arrow drawing past Dr Lethbridge to make sure it is ok before making any commits. I am generally a back-end programmer and the finer points of aesthetics are not really my strong point!

Now I am working on the GraphViz drawing of the compositions - I think I have this working, as well. I currently have the composition drawing an "ediamond" for the arrow ends (which basically looks like <> like in the editable class diagram). The code I added to the GvClassDiagramGenerator (in Generator_CodeGvClassDiagram.ump) is as follows:

   if (uAssoc.getIsRightComposition()) {
    arrows = "dir=\"forward\", arrowhead=\"ediamond\"";
    visualArrow = "-<@>";
   else if (uAssoc.getIsLeftComposition()) {
        arrows = "dir=\"back\", arrowtail=\"ediamond\"";
    visualArrow = "<@>-";
   else {
        // Original code present for specifying arrow types goes here!

This seems to work, but I have to write a template test for the GraphViz for compositions to make sure. I also have to figure out if there is a testing method in place for the editable class diagram option in order to test my other drawing.

Anyway, I'll keep working on this, and update with any progress!

Just a quick note as to why it took so long to find the json code (i.e. to figure out why the composition booleans were not being set properly in the javascript)... I really rely on grep when I'm looking for code snippets in order to better understand the code structure. When I started working on umpleonline, there was this whole new mass of code I had never worked with, so I was unfamiliar with how everything fit together and used grep extensively to find function calls and declarations and such things.

To try to figure out how and where I should set the composition booleans, I tried to emulate the implementation for the isNavigable booleans, and ran grep -rn "isLeftNavigable" * to see where this variable was referenced or initialized.

My problem was that I was only considering code from the umpleonline directory onwards. Running a recursive grep on the whole trunk of umple takes a long time and there is more output, which makes it harder to look through. My error was in thinking the umpleonline code was all contained in this directory. The Json generator code ended up being in cruise.umple/src.

Hopefully this helps make sure no one else makes a similar mistake!

November 14 2014

For the past few days I have been working on figuring out the setup of the UmpleOnline code in order to implement the changes I need to allow for user specification of compositions via the UI, and representation of compositions on the class diagram. At this point, I have created a new option in the "Draw" submenu as "Composition" - this is a clickable button, but it doesn't have the functionality implemented quite yet. Right now I am working on getting the class diagram to have a different arrow if the relation is a composition rather than just a regular association (as specified in the umple code). The functionality is present, but the problem I'm having is that I can't get the association to know that it is a composition in the diagram itself. I am tracing setting of the isLeftNavigable and isRightNavigable variables, since isLeftComposition and isRightComposition should be set similarly, depending on the arrow used in the code. The actual code generation in UmpleOnline is working (and in fact is working right now, with no changes made to the build) - it is just the UI section which needs the option added.

One thing to note: I had to create a composition arrow diagram (the same as the association arrow) for the Draw menu. These arrows are on a transparent background. Sadly, the only image editor I have on my laptop is Microsoft Paint (on my Windows partition), so I had to ask a friend to create the transparent background for me. Thanks, Mike! :)

Right now I'm focusing on getting the association in the class diagram to set the isLeftComposition and isRightComposition variables when the association is a composition. My next step after that will be to get the Composition option in the Draw menu to work.

I'll update with any progress!

November 9 2014

Today I set up a local web server on my Ubuntu partition so I could have a local testing environment for UmpleOnline. I followed the instructions as explained in SettingUpLocalUmpleOnlineWebServer which were very helpful.

I installed version 2.4.7 of Apache. I originally had a problem where apache didn't install properly and the /etc/apache2 directory was missing. To fix this, I removed and reinstalled:

   sudo apt-get purge apache2
   sudo apt-get install apache2 

Then it installed properly and the /etc/apache2 directory was present. Since I had an apache2.conf file and not an httpd.conf file, I followed this section of the instructions as specified in SettingUpLocalUmpleOnlineWebServer. Everything worked as detailed in these instructions, except for the code to be added to the umpleonline.conf file created in sites-enabled directory. The code specified to be added was:

<VirtualHost cruise.local:80>
   DocumentRoot "YOURPATH/umpleonline"
   ServerName cruise.local
   ErrorDocument 404 /404.shtml

<Directory "YOURPATH/umpleonline">
    Options Indexes MultiViews Includes FollowSymLinks
    AllowOverride None
    Order allow,deny
    Allow from all

I was getting a 403 Forbidden error, where the server said it did not have permission to access /. Looking up this error, I discovered that as of Apache 2.4 (and my version is 2.4.7), the new Require directive should be used. So, I added the line:


<Directory "YOURPATH/umpleonline">
    Options Indexes MultiViews Includes FollowSymLinks
    AllowOverride None
    Order allow,deny
    Allow from all
    Require all granted                # added this line for Apache 2.4

Then everything worked, and now I have a local version of umpleonline! I also updated the instructions in SettingUpLocalUmpleOnlineWebServer.

Now I'll be taking a look into how to add options to UmpleOnline.

November 7 2014

Delete code generation for compositions is all done in ruby! I made a commit today with these changes and the related tests. I ran into a small problem with this commit, as I had ruby 2.0.0 installed on my laptop, however the build server had an older version of ruby which my tests did not compile on. So, I did not notice this problem, since everything compiled in my testing environment, but on committing it ended up breaking the build. I did a quick hack so the build wouldn't fail on the server anymore (I commented out the entire contents of the composition test file, composition_multiplicitydelete_code_test.rb in the testbed_ruby/test directory). Then, once Dr Lethbridge had updated the version of ruby on the server, he uncommented out the tests, and it is now working. This is revision 4727 (on Google Code) (my initial commit with the changes to the code generation was revision 4725 (on Google Code)).

So now, the delete code generation for compositions is working for all the languages I have to implement in! Dr Lethbridge has another team working on the C++ side of Umple.

The next step for me is to implement the option of compositions as a type of association on UmpleOnline. This will involve creating a symbol (i.e. an arrow to represent composition visually) and a new keyword in the menu, among other things. My first step will be figuring out the basic functionality of the UmpleOnline code and how it is structured and fits together. This will be totally new for me, since all my work to date has been on the back end of Umple, in the code generation (with the compiler and the parser). I also need to figure out how to have a local testing environment for UmpleOnline so I can test out the changes I make.

November 3 2014

Just a quick update: I have the composition tests for -@ all done in ruby. The code generation is working! Now I just have to write the corresponding composition tests for @-. The fix to the bug I was having yesterday involved issue 646 (on Google Code) - there is no set method for multiplicities 0..1 to many. So now, the code inserted here to fix this problem is the same as that included in the set method. For instance, for the 0..1 to m multiplicity:

class X {}
class Y0_1__m {
   0..1 y0_1__m -<@> 3 X xVar;

.... then, in the generated ruby code, in class Y0_1__m, the delete method is

def delete
    @deleted = true
    while @xVar.any? do
      @xVar.shift  # this deletes the first value in the array

Then, this is the same functionality as if the X class had a generated set method such as set_y_0_1__m.

November 2 2014

I've been working on the delete code generation for compositions in ruby, and it seems to be coming along pretty well! At this point, I think I have the generation itself working for most cases, and am writing the tests. I am currently working on a small bug for the delete cases where the non-composition end is optional many, but I ran into similar issues with both java and php originally, so it shouldn't take too long to fix. Although I haven't worked with ruby in the past, it is very similar to python, which I have coded in before. So, in this respect, I have less of a learning curve than when I started with the php.

The only problem I ran into was the filename generation. For the ruby generated files, the names are all lower-case, and it automatically replaces camel-casing with underscores. This caused a problem for me since when I wrote the classes for left and right composition, I differentiated them with underscores. So, for instance,

class X {}
class Z {}

class Y1_1 {
   1 y -<@> 1 X x;

class Y_1_1 {
   1 y <@>- 1 Z z;

These are the tests for 1-1 multiplicity for left and right composition as I had them originally. The same problem was present for all the multiplicities. However, when the ruby files were generated, both class Y1_1 and class Y_1_1 were saved in file y_1_1.rb. The second class to be processed, class Y_1_1 overwrote what was already in the file, so class Y1_1 was effectively deleted. To solve this problem, I added an 'r' to distinguish the classes so the files generated would have different names. So now, the above code has been replaced by

class X {}
class Z {}

class Y1_1 {
   1 y -<@> 1 X x;

class YR_1_1 {
   1 y <@>- 1 Z z;

Now the files generated have different names and no overwriting occurs.

Anyway, I'll keep working on the delete code tests and update with any progress!

October 30 2014

Today I finished implementing the delete code generation for compositions in php! This was fairly similar to the implementation in java, the main differences arising from some semantic differences between the languages themselves. For one thing, the way in which php classifies equality in the delete code is only by the content of the class, and not the memory address of the object like in java. So, for instance,

class X { }
class Y {
   2 y <@>- * X x;

.... // then, in some php code...
$y1 = new Y();
$y2 = new Y();

$x = new X(array($y1, $y2));

Since $y1 and $y2 were considered equal in php, and since class X requires 2 Y's, this resulted in a compiler error, since php considered this to be duplicate arguments. None of my Y classes (in the composition tests) had any datafields other than the association, so I added an integer variable v which I then set differently for each instance of Y so as to differentiate between them. So, for instance, changing the above code, now it would be

class X { }
class Y {
   int v = 1;
   2 y <@>- * X x;

.... // then, in some php code...
$y1 = new Y();
$y2 = new Y();

$x = new X(array($y1, $y2));

The other problem I ran into was issue 649 (on Google Code). This was an error in the previous version of php code generation for the getMany methods (as described in my earlier log post). The fix was simple (I just changed the method signature of one to include a _index). However, all the template code for php was checking for the previous implementation, so I had to change all the template code. Also, there were various tests in the testbed_php which relied on the old syntax, so I had to change all those as well.

I made a commit today with all these changes! It's revision 4678 (on Google Code). I know it looks like a monster commit, since I changed so many files, but actually most of them are changes to the pre-existing test files where I added _index. The tests for the delete code I implemented are in testbed_php and are named the same as the corresponding tests in java. Let me know if there are any problems! I'll get to replicating this in ruby now, and I'll update with any progress.

October 28 2014

For the past few days I've been working on implementing the delete code generation for compositions in php. For the most part, the implementation is the same as in java, which I had got working last week. Although I have not worked very much with php in the past, the syntax differences between this and other languages I am more familiar with were pretty straight forward and have not been causing me too many problems so far.

At this point, I think the code generation is working properly, and am just writing all the tests. These tests are the same as the ones I wrote for java - one per set of multiplicities in either direction of composition i.e. both @- and -@.

While working with the tests, I discovered a few small problems in the pre-existing php generation. For one thing, although I did not think so at the time, the problem with name conflicts in the set method for SetNToOptionalOne (i.e. multiplicity 0..1 - n) which I had set as issue 645 (on Google Code) was actually present in php. This was an easy fix since it was the exact same code as in java (replace associationNew with parameterOne in the association_SetNToOptionalOne jet file to avoid the name conflict). The other problem I ran into was in the case where one end of the multiplicity was many (mandatory or not). Here, since the datafield is stored as an array, there are 2 get methods: one for the whole array, and one for a value at a specified index. For example, given the following:

class X {}
class Y {
 3 ym_1 -- 1 X x;

the generated code in class Y contains the following (in php):

  public function getYm_1($index)
    $aYm_1 = $this->ym_1[$index];
    return $aYm_1;

  public function getYm_1()
    $newYm_1 = $this->ym_1;
    return $newYm_1;

this results in an error, since php function signatures are only dependent on their names and not on the parameters. This is classified as a redeclaration and does not compile. I submitted this as issue 649 (on Google Code).

I think I've fixed this now... I changed the getMany jet file (for associations) to generate getYm_1_index($index) and getYm_1() so the names are different. However, this resulted in compiler errors in other php tests where the original naming convention was used, so I had to fix all those.

Right now, I'm working on getting the rest of the composition tests to compile and work properly in php (I'm almost done the -@ and just have a few more to go before starting on the @-). Then, I'll repeat this process in ruby!

I'll keep updating on the progress!

October 23 2014

So I made a commit with all the delete code generation changes! This is revision 4651 (on Google Code). Just a quick note... I had to redo all my changes in my original working branch since it was so behind in revisions (as I mentioned in my log post when I made my first commit). Originally, when I implemented another boolean in the AssociationVariable class I had it as

class AssociationVariable
  isA UmpleVariable;
  Multiplicity multiplicity;
  immutable Boolean isNavigable;
  Boolean isComposition;


This resulted in a change in the constructor for the AssociationVariable; I then had to change every reference to this constructor to initialize this new variable. When I redid the code, Alexi had just come across a similar situation, and discovered that the constructor argument list is unchanged if a default value is provided for the datafield. So, now the code looks like:

class AssociationVariable
  isA UmpleVariable;
  Multiplicity multiplicity;
  immutable Boolean isNavigable;
  Boolean isComposition = false;

and no references to this constructor had to be changed. Then, when it is a composition (in the UmpleInternalParser) I just call setIsComposition(true) on the AssociationVariable. This method took much less time. Thanks, Alexi! :)

October 22 2014

Just a quick update... today I finished the tests for @- composition! I will commit tomorrow as soon as I get internet on my Ubuntu again. Mostly the changes were in the delete jet files (and, by extension, the JavaClassGenerator), and the tests I wrote, which are in the testbed. I also added a boolean to the AssociationVariable class to specify whether or not the end of an association is a composition or not. So, the delete code is properly generated for all the cases I tested! I think I wrote a test for every combination of multiplicities (but please let me know if I missed any!).

The only problem I ran into during all of this was the generation of code from the jet templates. I have a working version of umple set up to work with eclipse; every time I want to change the jet templates, I have to compile the umple project in eclipse, and then copy the relevant java files (JavaClassGenerator.java) to my command-line copy of umple. Then, I have to run a full build. In total, each change requires around 8 to 10 minutes of compile time. I don't know if this would be possible, but it would be much more convenient to have a jet template build option via the command line. Just a thought!

Anyway, I'll keep updating with progress! I think my next step (once I get this committed) is going to be looking into how to implement this in php and ruby. Then, I have to look at how to make the composition option available on UmpleOnline (i.e. implement an arrow and other such details).

October 18 2014

So, I finally figured out what was causing the parsing error for @- with left variable names!

My original idea was that there was an accidental difference in implementation between @- and -@, but actually, the implementation was the same. So, I tried replacing the symbol for left composition @- with other symbols, to see how this affected the parsing error. Although there was no change in implementation, with the following symbols the error did not occur:

  • <<<-, <@-, @-, @>-, <@@-, @@>-, <@<-, >@>- And, the error was replicated with the following symbols:
  • <>-, <@@>-

From these results, it looked like the parsing error occurs when there was <(characters)*> on the left side of the - (but, recall, only when there is a left variable). What was happening was that the parser would not stop parsing the variable name when this syntax was used, and it would not recognize when the composition symbol began. So, this resulted in a malformedStatement1 (or a topLevelException if it was a non-inline association).

The error was occurring in the inlineAssociationEnd and associationEnd. These have the following grammar:

inlineAssociationEnd : [[multiplicity]] [~roleName]? [[isSorted]]?
associationEnd : [[multiplicity]] [=gpIdentifier:%]? [type] [~roleName]? [[isSorted]]?

It was on adding a roleName (i.e. a variable name) that the parsing error occurred. By looking at the grammar, the ~ is a premodifier which means the roleName has a restriction on the characters it is allowed. Specifically, (in GrammarParsing_Code.ump, in the GrammarAnalyzer class)

... // looking at the premodifiers
else if("~".equals(premodifier))
        regex = "[a-zA-Z_]([a-zA-Z0-9_]|-[a-zA-Z0-9_])*([ \\t]*<(([^\\{\\}\\(\\);\\n\\[\\]>]|\\[\\])*)>+)?";

So, here, the cause of the parsing error is clear: <(characters not ();\n[]>)*> is allowed syntax for a roleName.

To fix the problem, I added @ to the list of characters not allowed between <> in roleNames. This means that @ is no longer parsed as part of the roleName. And, I don't think this restricts the generality of roleName in terms of potential variable names (as far as I know). Now, this statement looks like:

else if("~".equals(premodifier))
        regex = "[a-zA-Z_]([a-zA-Z0-9_]|-[a-zA-Z0-9_])*([ \\t]*<(([^\\{\\}\\(\\);\\n\\[\\]>@]|\\[\\])*)>+)?";

I also had to add a brief modification in the setupTerminal method to include this constraint.

The plan is to commit this change tomorrow (once I have internet on my Ubuntu again), and I small test I wrote for it. Then, I can write the tests for @- to go with those for -@. They should be pretty similar, so hopefully this won't take too long.

I'll update on the progress!

October 15 2014

Today I committed a fix for issue 645 (on Google Code). As I was explaining yesterday, it involved minor changes to the association_SetNToOptionalOne jet file (which translated to changes in the JavaClassGenerator). There was also a change in the OptionalOneToN template. I wrote a small test to make sure this was working properly, in the testbed. The new test, TestHarnessAssociation0_1_mMultiplicity.ump, contains the following code:

class A 

class B 
   0..1 b -- 3 A a;

Previously, this resulted in java code which did not compile, due to the name conflict in the setMany function. Since umple files in the testbed are compiled to java, and this java is then compiled automatically, if the build does not fail, then the java has compiled. So, this means that the fix worked.

This fix is revision 4612 (on Google Code).

Tomorrow I'll continue looking into the parsing error which occurs with variable names with @- composition. I think I will try to fix this before patching the tests for -@. An initial look at this showed that there are no glaring differences between how -@ (and other associations, --, ->, <-) are treated as compared to @-.

As a side note: today was my first commit, and I ran into various problems along the way. I'll just make note of them so hopefully others can avoid these later!

  • I made a lot of changes on one version of the code, and did not update to an up-to-date version often enough. This lead to my working copy and my committing copy having different versions of the code for some files, so I ran into some errors patching. I had to replicate my changes from the old version to the new, which took some time. In the future, I will try to make more smaller patches instead of one large patch if possible (this is still a problem, waiting on a large patch for issue 183 (on Google Code)!).
  • Jet files are not compiled on the command line and must be run through eclipse. I originally made a commit (r4610 (on Google Code)) with only the jet file, and had to redo my commit later with all the affected generated files. Although generated java files are not generally included in patches, they are included in commits (as per commit instructions) so the code in the online repository is correct and will properly build on download.
  • I messed up the version of umple I was trying to commit on, and had to revert all the files. For future reference, to revert all files to the last revision updated to (in the trunk):
svn revert -R .

October 14 2014

So, today I fixed issue 645 (on Google Code)! Turns out the problem was in the association_SetNToOptionalOne jet file. In this specific multiplicity instance, in the setMany method (taking in an array), the for loop was as follows:

for (<%=gen.translate("type",av)%> <%=gen.translate("associationNew",av)%> : <%=gen.translate("parameterMany",av)%>) {

while, in other multiplicities (for example, MNToOptionalOne), the setMany method has the following for loop:

for (<%=gen.translate("type",av)%> <%=gen.translate("parameterOne",av)%> : <%=gen.translate("parameterMany",av)%>) {

By replacing all instances referring to associationNew with parameterOne, this solves the name conflict. Now, for the sample code included in my previous log post, the for loop

for (X aCheckX: newCheckX) { // no name conflict!!

is generated for this multiplicity!

I also had to change one of the test template files (OptionalOneToN_One.txt) to match the new syntax (in this template, the name error was present). This change means no tests fail in template.test during the build.

I also looked at php and ruby to see if the error was present in these languages, but, although the for loop naming (using associationNew) is the same the syntax error is not present here, due to an 's' at the end of the name of the incoming array (method parameter) - so, there is no name conflict.

I will commit a patch for this issue tomorrow once I have internet access on my linux partition!

The other thing is, in regards to issue 646 (on Google Code) (no set method generated for the multiplicity 0..1 - m..n) I have found a quick work-around to allow me to write the tests for composition. So, I am done the tests (for java) for all of the multiplicities for -@.

Tomorrow, I hope to commit patches with these updates. Then, I will focus on fixing the parsing error I get with variable names for @- (see last log post), so I can do the same for @- composition.

October 11 2014

I am almost done writing the java tests for composition. In writing these tests, I have discovered various problems.

First, it turns out there was a problem with my approach of generating delete code for cases where the multiplicity on one end was many (i.e. anything other than 1 or 0..1). In fact, the code generated was fine, but the delete code was generated for the case delete_ManyFromOne, which has the following loop:

   for (int i = varList.size(); i > 0; i --) {
      varType var = varList.get(i - 1);

This code is fine for the actual case of delete_ManyFromOne, because in this case, the delete function in varType removes var from the varList. However, when the multiplicity is not one on the other end, the code generation is different and this does not occurs in the same way. So, this resulted in compositions deleting properly, but not removing the variables from the list. The list still contained elements. To solve this problem, I created a new delete jet file, delete_ManyFromX_comp.jet, which has the following delete code:

   while (varList.size() > 0) {
      varType var = varList.get(varList.size() - 1);

This solves the problem. If the delete code in varType does remove var from varList, then varList.remove(var); does not do anything (i.e. this does not break the code).

I also ran into some odd code generation problems. These were pre-existing and are actually present for all associations (i.e. not just compositions).

Taking the following code:

class X {}

class Y {
   0..1 y_1 -- 3X checkX

In the generated code, in the Y class, the set method (setCheckX(X... newCheck) ) contains the following code:

ArrayList<X> checkNewCheckX = newArrayList<X>();
for (X newCheckX: newCheckX) {

This is an error! The proper code should be:

ArrayList<X> checkNewCheckX = newArrayList<X>();
for (X newCheckX: checkNewCheckX ) {

With the current code there is a name conflict and the java does not compile.

This does not occur, as far as I've noticed, with any other multiplicities. I discovered it while writing tests for composition - I originally thought the error was only for composition, but in fact it occurs for all associations. I have reported this as issue 645 (on Google Code).

Then, another error I ran into resulted from the following code:

class A {}

class B {
   0..1 b -- 2..3 A a;

When the java is generated, there is no set or add method in class A. Since there is no argument of type B in the constructor of A, there is no way to initialize variable b in class A with the generated code.

I also discovered this writing tests for composition. It seems to occur for all associations. I have reported this as issue 646 (on Google Code).

Finally, I have run into a very strange syntax error with compositions. I have not reported this as an issue, since it is directly related to issue 183 (on Google Code). So, initializing compositions works fine. It is properly parsed and the code is generated properly. But, for right compositions:

class X {}

class Y {
   1 y <@>- 1 X x;

results in a warning 1007 (code not recognized and treated as extra code). The weird part is, and the reason I didn't notice it before, is because this syntax is fine for left compositions, and also, the following is not an error:

class X {}

class Y {
   1 <@>- 1 X x;

where the only change is removing the variable name on the Y end. The same phenomenon is seen for associations separate from the class. The other reason this is so weird is that the grammar and parsing for left and right compositions is basically identical, and yet this is not a syntax error for left composition. Neither is it an error for any of the other types of association (directed or not), so this error is not due to any pre-existing problems.

Anyway, I'll keep updating on my progress!

October 10 2014

Currently, I am writing the java tests to make sure the generated delete code is working for all combinations of compositions. There are many tests, since the functionality has to be checked for each pair of multiplicities (where the multiplicities are as follows):

  • 1
  • 0..1
  • n (for n > 1)
  • 0..n
  • m..n (for m > 0, n > m)
  • * For each pair of these multiplicities, there is a left-composition test and a right-composition test.

My current implementation for the java tests is to create an instance of an object and set the objects it is composed with. Then, I delete the object and make sure the object(s) it was composed with is/are deleted too. Right now I am planning to use AssertEquals(objectThatShouldBeDeleted, null) for the single-multiplicity (i.e. where the multiplicity is 1). For the cases where the multiplicity is greater than one, my idea was to make an array of objects, and look through it with a for loop, having a boolean to see if they are all null. Then, I can use AssertEquals(boolAreTheyAllNull, true) to check if they have been properly deleted.

I'll keep updating on how it's going!

October 7 2014

Just a short log post on my current progress... I am writing tests to make sure the implemented code for compositions (i.e. the delete code) is properly generated in all cases. I am writing classes with compositions in the testbed/src folder (in TestHarnessCompositionsLeft.ump and TestHarnessCompositionsRight.ump). Then, in testbed/test/cruise/associations I am implementing a java file that checks each of these cases. I will initialize objects and call the delete, and ensure the composed objects are deleted properly. At this point, I have finished the umple code and am working on the java to check the generated classes.

October 2 2014

After various logic errors on my part, I figured out how to generate the right delete code for compositions (i.e. the associated object(s) are deleted regardless of the multiplicity of the object(s) on the composition (@) end). I added the following code to the delete_All.jet file. Recall that I added isComposition boolean to the AssocationVariable class.

if (relatedAssociation.getIsComposition()) {
        if ((relatedAssociation.isOnlyOne() || relatedAssociation.isOptionalOne()) && av.isOnlyOne()) {
            %><%@ include file="delete_OneFromOne.jet" %><%
        else if ((relatedAssociation.isOnlyOne() || relatedAssociation.isOptionalOne()) && av.isOptionalOne()) {
            %><%@ include file="delete_OptionalOneFromOne.jet" %><%
        else if ((relatedAssociation.isOnlyOne() || relatedAssociation.isOptionalOne()) && av.isMany()) {
            %><%@ include file="delete_ManyFromOne.jet" %><%

        else if (relatedAssociation.isMany() && av.isOnlyOne()) {
            %><%@ include file="delete_OneFromOne.jet" %><%
        else if (relatedAssociation.isMany() && av.isOptionalOne()) {
            %><%@ include file="delete_OptionalOneFromOne.jet" %><%
        else if (relatedAssociation.isMany() && av.isMany()) {
            %><%@ include file="delete_ManyFromOne.jet" %><%
        else {


Then, the previous code for including delete files is included in an else clause.

Now, I am trying to figure out if any other methods (i.e. not just the delete method) need to be changed for compositions. Also, I am trying to figure out how to write tests to make sure the changes I implemented generate the right delete code in all cases.

Once I write test cases I will submit a patch.

September 30 2014

I have changed my mind about altering the multiplicity methods in the AssociationVariable class, and instead I want to change the delete_All jet file to have an if statement for compositions. After talking to Dr Lethbridge, I have come up with the following table for the delete files that should be included: Given the following scenario:

class X {}
class Y {}
association {
  1 Y -<@> ??? X; // the ??? represents the multiplicity on the X end
                  // this will be specified in the table below

or any equivalent association. | ??? | Composition | |:--------|:----------------| | 1 | delete_OneFromOne.jet | | 0..1 | delete_OneFromOne.jet | | n (n>1) | delete_ManyFromOne.jet | | 0..n | delete_ManyFromOne.jet | | m..n | delete_ManyFromOne.jet | | * | delete_ManyFromOne.jet | | n..* | delete_ManyFromOne.jet |

Then, the same idea would apply for when the Y-end multiplicity is not 1 (i.e. delete_???FromMany.jet, etc).

I will try implementing this and see if it works. Will update with progress.

September 29 2014

This log post is a little late, sorry! Since the code sprint I have been continuing work on issue 183 (on Google Code), which is my ProjectUG. I have implemented the functionality for parsing and storing compositions properly, and am now trying to figure out the cases for deletion (i.e. which cases should be called depending on the type of composition).

To work on this, I also had to implement a boolean in the AssociationVariable class (which represents one side of the association, with a reference to the other side of the association). Similar to the immutable Boolean isNavigable, I have added immutable Boolean isComposition. Because this changed the auto-generated constructor, I had to make changes to various test files and some of the parser files (every time this constructor was called), similarly to what happened when I added booleans to the Association class. In the AssociationVariable class, the methods are defined which are then used in the delete_All jet file to determine which delete method is to be called (depending on the multiplicity). I now need to change these methods so that the appropriate option is returned (so the correct delete code is generated) for the different kinds of compositions. I am trying to figure out the logistics of this now (i.e. the details of which options should be called if it is a composition for the various possible combinations of multiplicities).

Tomorrow I will come up with a working hypothesis of which options correspond to which delete methods for the compositions, and I will write a log post about it. According to my present idea, I shouldn't have to change the delete_All jet file (or any of the other jet files); the changes should be sufficient in the AssociationVariable class.

Once I get this working properly I will write test cases and submit a patch.

September 21 2014

Code Sprint day 3

I added booleans for isRightComposition and isLeftComposition in the Association class (I asked about making a separate class for Composition that extends Association, or something along those lines, but that solution was turned down in favour of this one). I have some checks, so the association cannot be both left and right compositions, and also so that if it is a right or left composition, then it must be navigable both left and right. I also wrote various tests to make sure this was all working and the checks were functioning as intended, and that the booleans were being set correctly. It turned out that adding these booleans changed the auto-generated constructor to include them as arguments, so I had to go and change every call to the Association constructor (mostly in AssociationTests.java) to add in the new arguments. I also had to make sure all the old tests were still passing, with the new functionality.

I got this working and submitted a patch right before the code sprint ended. Unfortunately, I edited these files in vi (on Ubuntu) and whoever had last edited them had been using a Windows editor, and this resulted in some problems in committing the patch because of end-of-line syntax differences between the editors. Dr Lethbridge managed to fix it, though, and committed the changes. This is revision r4508 (on Google Code).

As a general note, the code sprint was a great experience!! We had an amazing time and met a lot of really cool people! The Mozilla office was awesome, too, and everyone was really friendly and helpful. After coding this weekend, I feel I have a much better grasp on Umple in general and am looking forward to continuing work on my current problem (after I catch up on all the homework for my other classes...).


September 20 2014

Code Sprint day 2

I spent the morning fixing issue 632 (on Google Code)! While working on issue 625 (on Google Code) I discovered that the JavaClassGenerator was correctly finding which classes had main methods, so I just took this code and replaced the method in the CodeCompiler (in Compiler.ump), getMainClasses(), with the functional code from the JavaClassGenerator. So, I fixed issue 632 (on Google Code) and now eclipse compile-and-run option works. If there is more than one class with a main method compiled at once (with this option), then the user is prompted which main class they would like to run.

Although now the eclipse development is working, I still find the command line useful. I do all my project compiling in the terminal, and I still think grep and find are much more useful than the eclipse find options. I mainly use eclipse to edit/create files, and for the syntax highlighting.

Now that I have fixed issue 625 (on Google Code) and issue 632 (on Google Code), I have been assigned issue 183 (on Google Code) for my ProjectUG. Dr Lethbridge has gone over the general idea and some first steps with me, so I now have an idea of where to start.

  1. change the grammar so it parses the symbols of @- and -@ for composition, but keep it so it is parsed as regular -- aggregation
  2. add functionality to the existing Association class so it can tell whether or not it is a composition
  3. once the difference is actually parsed, then compositions must be treated differently, in regards to the delete method
  4. the composition must be an option on UmpleOnline, and a new keyword may be in order
  5. also, for UmpleOnline, the composition arrow has to be rendered
  6. aggregation is different...

This is a general outline of my work cut out for the semester in terms of my ProjectUG.

Later today I changed the grammar to include @- and -@ as valid symbols, and I updated the parser so it would read these in and treat them as regular association, denoted --. I wrote some tests to make sure this was working as I had intended it to, after learning how tests work in Umple. Tomorrow I will try to get a difference in treatment between regular association and composition.

September 19 2014

Code Sprint day 1

Today I ended up fixing issue 625 (on Google Code)! The difference in code generation in eclipse was actually due to a reset problem of a public static variable in the JavaClassGenerator. This is "mainMainClass" on compiling (the first compiled file with a main method) and it is the file where the UmpleExceptionHandler is added. Regardless of how many files have main methods, there is only one "mainMainClass", and all other files who need to reference the UmpleExceptionHandler reference the static inner class in the mainMainClass. The problem in eclipse was that even in a project where there is only one class with a main method, the instances of UmpleExceptionHandler (in the main method) reference the entire path to the class itself. Then, since it is not considered the mainMainClass, it ends the class in a }, but then also adds the UmpleExceptionHandler, resulting in an extra } and errors with the inner class. This raises the question of how a class can be both the mainMainClass and not the mainMainClass at the same time. The reason for this was that the mainMainClass not being reset to null in eclipse before something new is compiled. For instance, the first time after eclipse that something is compiled with a main method, there were no errors. But then, if that file was recompiled, the error crops up again (reference to itself and extra } ). To fix this, I reset the JavaClassGenerator.mainMainClass to null in the run() method in UmpleAction (cruise.umple.eclipse/src/cruise/umple/ui/eclipse/UmpleAction.java). I submitted a patch and Dr Lethbridge committed it this morning. The new revision (r4491 (on Google Code)) includes this fix.

In terms of my plans for the semester, I would like to work on issue 183 (on Google Code) for my ProjectUG. This is getting into the syntax of umple and implementing a new functionality (the idea of compositions). This is building off the existing idea of aggregation, but now the idea of forced deletion must be enforced for cases other than just the 1-something dependency. To start off, I am going to look through the existing code and try to figure out the functionality of aggregation and how the deletion works currently.

First, however, I have discovered another minor bug in eclipse (the compile-and-run option does not run anything, even when one or more of the files compiled have a main method). This was not linked to the patch I submitted for issue 625 (on Google Code) (this problem was present with the last revision of the code as well). I have reported this as issue 632 (on Google Code).

September 16 2014

For the past few days I have been working on issue 625 (on Google Code). I have been trying to find the root of why code generation is different in eclipse and on the command line. As an experiment, I took the original umple.jar and replaced the (included) files with those from the eclipse plugin cruise.umple.eclipse_1.20.2.4305.jar. I was trying to reproduce the code generated in eclipse by compiling umple on the command line, but the code generated was unchanged from with the original umple.jar. My working hypothesis is that the difference in code generation has to do with the structure of the code in the eclipse-generated project rather than in difference in the code itself.

Also, I tried recompiling the eclipse project from the command line, and the build failed with errors of "duplicate class" (for example, the following):

[javac] /home/ellen/Umple/cruise.umple/src-gen-umple/cruise/umple/compiler/Association.java:19: error: duplicate class: cruise.umple.compiler.Association
[javac] public class Association
[javac]        ^

This is the result of there being 2 files generated with the same name (from the Umple directory):


Looking at another directory where I only compiled the umple source code on the command line, there is only one instance of the Association class (from the Umple directory):


This extra file (cruise.umple/src/cruise/umple/compiler/Association.java) is generated because of the package structure in the eclipse project (this matches to file cruise.umple.compiler.Association -- in eclipse, the code is in packages in a src folder).

I am currently looking at how the class name and location in the directory structure affects the code generation (specifically, looking at the UncaughtExceptionHandler). I am also trying to set up a directory structure so that this error is duplicated on compiling on the command line.

As a side note, I am finding the Linux terminal very useful in understanding the code structure. I have been extensively using grep and find in order to locate method calls in the code, or find the path to a specific file. For those using Unix/Linux, these are the commands I find myself using the most:

This searches recursively for 'stringToSearchFor' in all the files from the current directory onwards. The -n prints the line number the string is found at.

grep -rn "stringToSearchFor" *

This searches for all occurrences of a file with the name 'fileName', recursively from the current directory onwards.

find . -name "fileName"

September 14 2014

After the last hangout with the team, various things have come up:

  • Since umple code and java code do not belong in the same directory (java code generated from umple should be placed in a separate directory, src-gen-umple), I am no longer worrying about auto-generating package statements for the java based on the package containing the umple code.
  • After tracing the difference in code generation (between eclipse and the command line) to the UncaughtExceptionHandler, which only manifests itself when the umple file in question has a main method, Dr Lethbridge told me one of his grad students had worked on this code and could potentially find a quick fix (issue 625 (on Google Code)). So I started to look for other issues to work on
  • I was interested in issue 477 (on Google Code) and got assigned to it.

In order to work on issue 477 (on Google Code) (which was about command line compiling not producing an error message if an umple file referred to a non-existant file in a use statement), I tried to reproduce the issue described. However, after running various tests on both the command line and in eclipse, I was unable to reproduce the problem - an error message (error 1510) was displayed in every case. So, it seems as if someone fixed it and did not report it. This issue was marked 'verified' and closed.

I am now looking for another issue to work on, and am looking into issue 183 (on Google Code) as potentially for my ProjectUG. I am also continuing work on issue 625 (on Google Code).

September 12 2014

For the past few days I have been looking into issue 625 (on Google Code) (which I've been assigned). In terms of the package statements, I figured out how umple determines what package the generated java files are in - for the java files to have a package statement, the umple code needs a namespace. For example, for the following umple code:

namespace testing;

class X {
   int x;

X.java is generated with the package statement 'package testing;'. However, this package is generated as a subdirectory of the current package (so, for example, if the umple code was in package test, the generated java code would be in package test.testing). However, the package statement in X.java would still only be 'package testing;', which still results in the java code not compiling. On another note, I think this package statement should be generated automatically on compiling if in eclipse, without any additional syntax from the user - but this definitely up for debate.

The other problem I'm working on is the difference in code generation between eclipse and the command line, particularly in terms of the UmpleExceptionHandler. In terms of this, I still don't know why there is a difference between code generation. I reproduced the same error (i.e. an extra curly brace before the UmpleExceptionHandler is declared) with the following code:

class X {
   int x;
   public static void main(String[] args) {
      System.out.println("Greetings, world!!");

This generates X.java with the extra } before the static inner class of UmpleExceptionHandler in eclipse (so it doesn't compile), but it works on the command line.

I'm still looking into how to solve these problems; I'm also working through the structure of the code to understand how the code works together and try to understand how the code generation works at a fundamental level. I'm also looking to see if there's a way to tell if the code is being compiled in eclipse or on the command line during generation.

September 9th 2014

Well, I successfully installed the Eclipse plugin for Umple and have been playing around with some of the classes.

After looking through the list of issues, I decided to take a look into issue 451 (on Google Code) (errors in Interface generation) and have been looking through the related files with Alexi.

On making my own Umple project in Eclipse, I noticed that if the .ump file being compiled was in a specified package (i.e. not the default package) the package name was not added to the generated java files. This resulted in the java files not compiling due to missing package statements. I have submitted this as issue 625 (on Google Code) and will continue working on it, along with the interface generation errors!

I also ran into an error on compiling Master.ump (in eclipse). Once compiled, the generated java file DocumenterMain.java had a compiler error resulting from an extra terminating } (on line 72). Alexi had run into this problem earlier and he explains this problem in his log also. We were looking at it today, and it looks like the UmpleExceptionHandler (a static class) should be an inner class to DocumenterMain, but that this class is ended (with the offending curly brace) before the static class is declared. Removing the } fixes the compiler error, but if the Master.ump is recompiled the error returns. We're trying to figure out why this extra } is generated.

September 6th 2014

I've just finished setting up the Umple development environment on my Linux partition (Ubuntu 14.04). I followed the DevelopmentSetUp instructions (which were very clear!), and also had to install svn, php, ruby, and rake.

The only problem I ran into was that the ant command resulted in the following error: "Could not load definitions from resource net/sf/antcontrib/antcontrib.properties". This was solved by downloading ant-contrib-1.0b3.jar and placing it in the lib directory in ant (/usr/share/ant/lib).

I have also played with the UmpleOnline tool and messed around with some of the generated code. This weekend I'd like to get Umple working with Eclipse and familiarize myself with svn (I've only used git before). I'll also check out the patch process and have a look at the issues list to find something to work on.