{"id":795,"date":"2010-12-12T19:37:00","date_gmt":"2010-12-12T19:37:00","guid":{"rendered":"http:\/\/salientsoft.co.uk\/?p=795"},"modified":"2010-12-12T19:56:14","modified_gmt":"2010-12-12T19:56:14","slug":"using-the-enterprise-architect-uml-design-tool","status":"publish","type":"post","link":"https:\/\/salientsoft.co.uk\/?p=795","title":{"rendered":"Using the Enterprise Architect UML design tool"},"content":{"rendered":"<p><strong><span style=\"text-decoration: underline;\">Updated 11\/12\/2010<\/span><\/strong><\/p>\n<p>I\u2019ve clarified some of the points re collection classes, code generation, and the Local Path feature.<\/p>\n<p>\u00a0<\/p>\n<p><strong><span style=\"text-decoration: underline;\">Original Post (7\/5\/2010, 07:30)<\/span><\/strong><\/p>\n<p>I&#8217;m trialling <strong><a title=\"http:\/\/www.sparxsystems.com.au\/\" href=\"http:\/\/www.sparxsystems.com.au\/\">Enterprise Architect<\/a><\/strong> from <strong>Sparx Systems <\/strong>at the moment, and have found the following points\/tips\/gotchas so far :-<\/p>\n<p><strong><span style=\"text-decoration: underline;\">Class Stereotypes<\/span><\/strong><\/p>\n<p>If you choose a stereotype such as entity which has its own image, this changes the appearance on the class diagram and prevents detail such asproperties and operations being listed. You can either use another stereotype (or none at all &#8211; sometimes I have not as it clutters up the simplicity of the diagram), or you can customise the appearance under <strong>settings\/uml<\/strong> to prevent the image being used.<\/p>\n<p><strong><span style=\"text-decoration: underline;\">Collection classes and generics for relationships<\/span><\/strong><\/p>\n<p>The collection class to be used can be set as a global default or per class:-<\/p>\n<ul>\n<li><strong>global default<\/strong> &#8211; visit <strong>Tools\/Options<\/strong>, pick <strong>Java <\/strong>under <strong>source code engineering<\/strong> in the left hand treeview pane. Click the Collection Classes button to configure the defaults. Note that you can enable generics by using e.g. <strong>Collection&lt;#TYPE#&gt; <\/strong>as the definition, where <strong>#TYPE#<\/strong> is replaced by the appropriate class name. This is mentioned in the help but is not easy to dig up. You can set different collection classes for <strong>Default, Ordered<\/strong>, and <strong>Qualified<\/strong>.<\/li>\n<li><strong>Per Class setting<\/strong> &#8211; open the class details (double click on the class), select the details tab, and click the Collection Classes button to configure the class in the same way as with the global defaults (including generics using #TYPE#). <strong>**Important potential Gotcha**<\/strong> &#8211; when setting this up, it is easy to get confused. If Class A contains a collection of Class B, then to enable a collection declaration to appear in the Java code for Class A, you must set the appropriate collection class settings on Class B, not Class A. Setting up class B will then cause that declaration to appear in Class A. Note that the per class settings overide any global default that you have applied.<\/li>\n<li>The trigger for generation of the collection declaration is to set the Multiplicity at the appropriate end of the (aggregation) relationship between the classes. So for example, an Application might have a 0-or-1 to many relationship with AppRole, i.e. an Application will hold a collection of AppRoles. The aggregation relationship will be drawn <em><strong>from<\/strong><\/em> the AppRole class <strong><em>to<\/em><\/strong>\u00a0 the Application class, such that the diamond arrowhead appears against the Application class, as that holds the collection. You would then double click the relationship, and under <em><strong>Source Role<\/strong><\/em> you would set a Multiplicity of 0..*, and under the <strong><em>Target Role<\/em><\/strong> you would set a multiplicity of 0..1. This will cause the collection declaration when the code is generated. Note that there are other settings on the source and target role pages for <em>Role<\/em> and <em>alias<\/em>, and <em>derived<\/em>, <em>derived union<\/em>, and <em>owned<\/em>. These do not appear to affect the code generation (at least in my simple examples).<\/li>\n<li>Note that if you select <em>ordered<\/em> on the multiplicity you get the <em>ordered<\/em> type of collection class. In my case, I used global settings of <em>Collection<\/em> for unordered, <em>List<\/em> for ordered, and left the qualified as <em>Collection<\/em>. Using this I obtained a declaration of <em>List<\/em> in the generated code when I selected <em>ordered<\/em> on the multiplicity of the 0..* end of the relationship (Source Role in the above example).<\/li>\n<\/ul>\n<p><strong><span style=\"text-decoration: underline;\">Enabling\/Disabling Destructor (Java finalize) calls<\/span><\/strong><\/p>\n<p>These can also be configured globally or on a per class basis :-<\/p>\n<ul>\n<li><strong>Global default<\/strong> &#8211; visit <strong>Tools\/Options<\/strong>, pick <strong>Object Lifetimes<\/strong> under <strong>source code engineering<\/strong>, and tick or untick <strong>generate destructor<\/strong>. Constructors can be similarly configured.<\/li>\n<li><strong>Per Class setting<\/strong> &#8211; right click on the class and select <strong>Generate Code<\/strong>. Click <strong>advanced<\/strong>, and the same page is displayed as for the global default. Constructors\/destructors are configured in the same way as above, except that the settings are per class rather than global defaults.<\/li>\n<\/ul>\n<p>When Java is the target language, enabling a destructor adds a call to <strong>finalize<\/strong> as Java is garbage collected and does not have explicit destructors. <strong>finalize<\/strong> is called by the garbage collector to notify the object of garbage collection, but the call is made at the discretion of the garbage collector. For Java you would normally want to untick the <strong>generate destructor<\/strong>\u00a0 setting.<\/p>\n<p><strong><span style=\"text-decoration: underline;\">Auto generation of package statements in Java<\/span><\/strong><\/p>\n<p>To configure this, you select a package in the project browser hierarchy as the package route, by selecting <strong>Code Engineering<\/strong> on its context menu, then picking <strong>Set as Namespace Root<\/strong>.<strong> <\/strong>Then, all packages under that root package (but not including the root package) will have their names contatenated to form the java package that is used in the code. You can use dots in the package name, so for example you could have a package heirachy of <strong>Class Model\/uk.co.salientsoft\/appname\/domain<\/strong>, where <strong>Class Model<\/strong> would be set as the root. Then, classes in the <strong>Domain<\/strong> package would have a package in the code of <strong>uk.co.salientsoft.appname.domain<\/strong> as you would expect. <strong>Note that there are some gotchas\/possible bugs around this. <\/strong>I only managed to get it to work when I actually created a class diagram at each level and added the next sub package onto the diagram. This looks tidy\/correct anyway, and is what the example does, but it is not enforced &#8211; you can have a package hierarchy in the browser without having all the intervening class diagrams with the next subpackage on, but if you do so, it appears that package statements are not then output in the java code.<\/p>\n<p><strong><span style=\"text-decoration: underline;\">Code generation \/ directories<\/span><\/strong><\/p>\n<p>When generating code, this can be done at package level by selecting <strong>Code Engineering\/Generate Source Code<\/strong> from a package context menu in the project browser. Ticking <strong>Include All Child Packages<\/strong> does just that and generates the code recursively down the package tree. You can select <strong>Auto generate files<\/strong> to cause the file directory paths to be automatically derived from the package hierarchy, ignoring any path set for the individual classes. However, I found this awkward to set up &#8211; ideally I wanted a java directory tree to match the package fields, but to do this seems to need a carefully crafted package hierarchy which may not match the way you want to work. For example, I had a package called <strong>uk.co.salientsoft<\/strong>, which ended up as a single directory name rather than being broken down into component fields. I did not want to add all the individual package levels for uk, co, and salientsoft. Also, when you <strong>Auto generate files<\/strong> the root path under which the tree is created is not saved and you have to browse for it every time &#8211; not pleasant. Therefore, in the end I elected <strong>not<\/strong> to use <strong>Auto generated files<\/strong>, but to set the correct file path on each class. Thus can be done by right clicking the class and selecting <strong>Generate Code<\/strong>, then browsing for the desired path. Clicking <strong>Save<\/strong> will save the path which is then used for code generation as above. Having done this, I finally acheived correct package statements in the code together with the correct directory hierarchy.<\/p>\n<p><strong><span style=\"text-decoration: underline;\">Using Local Paths <\/span><\/strong><\/p>\n<p>Local Paths offer a means of parameterising root directories e.g. for code generation, such that the same EAP\u00a0 file can be used by multiple users with different local code generation directories.<\/p>\n<p>On the surface it looks like a means of defining environment\/path style variables within EA, which you then use when defining code generation locations. This is somewhat of a misconception, which is unfortunately reinforced by the section of the help on Local Paths:-<\/p>\n<p style=\"padding-left: 30px;\"><em>Developer A might define a local path of:<br \/>\nJAVA_SOURCE = &#8220;C:\\Java\\Source&#8221;<\/em><\/p>\n<p style=\"padding-left: 30px;\"><em>All Classes generated and stored in the Enterprise Architect project are stored as:<br \/>\n%JAVA_SOURCE%\\&lt;xxx.java&gt;.<\/em><\/p>\n<p style=\"padding-left: 30px;\"><em>Developer B now defines a local path as:<br \/>\nJAVA_SOURCE =&#8221;D:\\Source&#8221;.<\/em><\/p>\n<p style=\"padding-left: 30px;\"><em>Now, Enterprise Architect stores all java files in these directories as:<br \/>\n%JAVA_SOURCE%\\&lt;filename&gt;<\/em><\/p>\n<p style=\"padding-left: 30px;\"><em>On each developer&#8217;s machine, the filename is expanded to the correct local version.<\/em><\/p>\n<p>In fact, whilst you do define a local path under <em><strong>Settings\/Local Paths\u2026<\/strong><\/em>\u00a0 and give the local path an ID (or variable name), you do <strong>not<\/strong> enter the ID anywhere when configuring directories for code generation \u2013 the local paths are applied behind the scenes in somewhat of a smoke and mirrors fashion.\u00a0 In fact you do the following to set it up (example is for setting Java code generation directories directly on classes) :-<\/p>\n<ul>\n<li>Select <em><strong>Code Generation\u2026 <\/strong><\/em>on the context menu for one or more classes on a class diagram. Browse for the actual desired full path for the class. You will note that at no stage is there a means to enter a variable ID in the path \u2013 you are just using the standard file browse dialog.<\/li>\n<li>Under <em><strong>Settings\/Local Paths\u2026<\/strong><\/em> create a local path of type <strong><em>Java<\/em><\/strong>, browsing to a root directory which is either the path entered for the classes or a parent directory on the same path. Save it with a suitable name.<\/li>\n<li>Clicking <strong><em>Apply Path <\/em><\/strong>will then apply the path to the code generation directories. It will return a count of the number of instances it applied (number of paths found). In my case, it initially found 0, but when I clicked <strong><em>Expand Path<\/em><\/strong> which reverses the process and removes your local path, and is supposed to revert to using normal full directories again &#8211; it said it removed 4 (the number of affected classes). When I clicked <strong><em>Apply Path<\/em><\/strong> again, it again found all 4, so I suspect the initial \u201cfound 0\u201d was a bug and it had worked &#8211; confusing, especially as it is all doing stuff behind the scenes!<\/li>\n<li>Now, to see the effect of what you have done, change your local path definition in the local path dialog for the ID you created and applied, and save the change. Now look at the code generation folders for the classes again under <strong><em>Code Generation\u2026<\/em>\u00a0<\/strong><em>\u00a0<\/em>on the context menus for the classes, and you should find that the path has changed by magic to the one you just set in the Local Path dialog! Smoke and mirrors indeed.<\/li>\n<li>Note that normally your local path definition will just be a parent directory which is shared by all your code generation subdirectories for the classes, as there will typically be a number of different subdirectories. EA correctly changes just the parent directory part of the path.<\/li>\n<li>You can then if desired define a number of local paths for Java, e.g. \u201cFreds path\u201d, \u201cBills path\u201d, and apply the desired one which will then take effect. You will not see any local path IDs appearing anywhere, they are stored in the path but applied behind the scenes.<\/li>\n<li>To switch between local paths again feels strange. You would expect that if &#8220;&#8221;Freds path\u201d is in effect and you apply \u201cBills path\u201d (which has a different definition), then the directories will\u00a0 all change. <strong><em>They do not!<\/em><\/strong> What you have to do is to define \u201cBills path\u201d initially to be <strong><em>the same definition <\/em><\/strong>as \u201cFreds path\u201d, then do an <strong><em>Expand Path<\/em> <\/strong>for \u201cFreds Path\u201d (Whereupon you will see the correct count of classes affected). Then you can do an <strong><em>Apply Path<\/em><\/strong> for \u201cBills path\u201d, which will then be applied to the same number of classes. <strong>Finally, <\/strong>you can amend \u201cBill\u2019s path\u201d, which is the one that currently has control, and all the class code generation directories will change.<\/li>\n<li>One frustration of this method is that when adding new classes when a local path is in effect, you must still browse to the correct actual directory just as you would if no local path was present \u2013 you cannot enter the local path anywhere. It will however take effect \u2018by magic\u2019. In my case, I created a new class under the local path, and it immediately \u2018took on\u2019 the local path and would change its directory when I changed the local path definition, even though I had not done an \u2018Apply Path\u2019 to pick up the new class.<\/li>\n<li>It appears therefore that new classes under the parent folder of a currently active local path pick up the effect of the local path by default.<\/li>\n<\/ul>\n<p>\u00a0<\/p>\n<p>My scenario is not the actual use case which will occur in practice, as I was doing this as a single user and making changes. In practice, if the EAP file was passed around, a different user would already have his source directories created according to his own standard. <em>Nevertheless, I find the operation of this functionality to be strange, counterintuitive, and even slightly buggy in parts.<\/em><\/p>\n<p><em>Having said that, in fairness, EA is the best UML tool I tested by far in my price range as an independent developer &#8211; $199 for the professional edition, as opposed to a 4 figure sum for other packages which I did not even bother to look at. The other features of EA are very fully functional, intuitive to use and bug free. Surprisingly, as per my other post <a href=\"http:\/\/salientsoft.co.uk\/?p=787\"><strong>here<\/strong><\/a>, all the other packages I looked at were very poor in comparison, so for my needs and price range,\u00a0 and from my testing, it is still very much a one horse race.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Updated 11\/12\/2010 I\u2019ve clarified some of the points re collection classes, code generation, and the Local Path feature. \u00a0 Original Post (7\/5\/2010, 07:30) I&#8217;m trialling Enterprise Architect from Sparx Systems at the moment, and have found the following points\/tips\/gotchas so far :- Class Stereotypes If you choose a stereotype such as entity which has its [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[92],"tags":[93,40,181,16,15,190],"_links":{"self":[{"href":"https:\/\/salientsoft.co.uk\/index.php?rest_route=\/wp\/v2\/posts\/795"}],"collection":[{"href":"https:\/\/salientsoft.co.uk\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/salientsoft.co.uk\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/salientsoft.co.uk\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/salientsoft.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=795"}],"version-history":[{"count":14,"href":"https:\/\/salientsoft.co.uk\/index.php?rest_route=\/wp\/v2\/posts\/795\/revisions"}],"predecessor-version":[{"id":797,"href":"https:\/\/salientsoft.co.uk\/index.php?rest_route=\/wp\/v2\/posts\/795\/revisions\/797"}],"wp:attachment":[{"href":"https:\/\/salientsoft.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=795"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/salientsoft.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=795"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/salientsoft.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=795"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}