"There is a theory which states that if ever anyone discovers exactly what the Universe is for and why it is here, it will instantly disappear and be replaced by something even more bizarre and inexplicable. There is another theory which states that this has already happened"
Douglas Adams


"Get the cheese to sickbay"
B'Elanna Torres, Starship Voyager


"What did y'all order a dead guy for?"
Jayne Cobb, Firefly


"Excuse me, but I am in the middle of fifteen things, all of them annoying"
Susan Ivanova, Babylon 5


"That don't impress me much!"
Shania Twain, Come on over


"Stop the pigeon! Stop that pigeon now!"
Sheriff of Nottingham, Sherwood Forest, The Adventures of Robin Hood


place
If-Then-Else with Enabling Conditions
Home > SoftwareTools > Together > DocumentGeneration
If an enabling condition in a Together Document Generation Template evaluates to true then the document generator processes the section. If the expression evaluates to false then the section is ignored.

All the different types of section in a Together document generation template have a property called their enabling condition. For most sections this is found on the Other tab of their property dialog. The exception is static sections where it is found on the Settings tab after right-clicking on the section in the Scope pane and selecting the Properties… context menu item.

Figure 1: Enabling Condition Properties for an Element Iterator and Static Section Figure 1: Enabling Condition Properties for an Element Iterator and Static Section 
Figure 1: Enabling Condition Properties for an Element Iterator and Static Section

Enabling conditions are OCL (or legacy) expressions that evaluate to either true or false. The condition is evaluated by the document generator just before it executes the section. If the expression evaluates to true then the document generator processes the section. If the expression evaluates to false then the section is ignored.

This means that enabling conditions can be used to implement conditional logic analogous to that of the if-then-else statements found in most popular, general-purpose programming languages.

Alias or Name Using Enabling Conditions

In Together’s language-dependent modelling projects (LiveSource projects: Java Modeling, C++ Modeling, and IDL Modeling) classes and interfaces are constrained to names that comply with the rules of the underlying programming language. Therefore, classes and interfaces in these projects have a special alias property that may be used to give the element a name that is more natural for humans to read.

In a document template for such a model, when including the name of a class or interface in the generated output, we generally want to use the value in the alias property if it has one or the value of the element’s name property if not.

There are two choices. We can craft an OCL (or legacy) expression inside a formula control and this is perfectly feasible. Alternatively, we can create two static sections that are identical except that one specifies the name in a data control and the other specifies the alias property. Then we had two mutually exclusive enabling conditions to the static sections so that only one of them is ever processed depending on whether or not the alias property is populated. Figure 2 shows two static sections, one for the name property and an identical one for the alias property and Figure 3shows the two mutually exclusive enabling conditions needed to ensure only one of the static sections is processed for any given UML 2 class.

Figure 2: Two static sections for name and alias properties
Figure 2: Two static sections for name and alias properties

Figure 3: Two mutually exclusive enabling conditions Figure 3: Two mutually exclusive enabling conditions 
Figure 3: Two mutually exclusive enabling conditions

The enabling condition in Figure 3 does not handle very well the situation where an alias field’s value consists of one or more space characters. As it stands the alias field value will be used resulting in a blank space in the generated document.

We could complicate the expression to use the name property instead in these circumstances. However, a better solution would be to identify the useless value in the alias field and correct it. Therefore, rather than hiding the problem by handling the situation in the template, it would be better to define a Together model audit that flagged any alias properties with values consisting purely of space characters.

Together contains an Cheat Sheet that steps through the defining and running of a model audit. The list of Cheat Sheets is found on the Help menu on the main menu bar in Together. The model audit cheat sheet is located in the Together OCL Features section of the list.

As shown in Generating a Document Using a Template, a template can also list audit violations for an element so that any occurrence of the audit above failing can also be highlighted in the generated document to make doubly sure the problem is caught.

Expanding or Mapping Enumeration Literals

Another similar example of using enabling conditions is to expand the names of a set of values. For example, consider a use case element with a custom property called value (see Custom Properties, Stereotypes, and Profiles) that is configured to take one of three values lo, med, or hi. Mow imagine that in a generated document the values need to be shown as low priority, medium priority, and high priority with each value being displayed in a different colour.

This can be achieved by creating a static section for each of the values that the property can take and add a label control with one the longer values to each of those sections (see Figure 4).

Figure 4: Static sections with mutually exclusive enabling conditions
Figure 4: Static sections with mutually exclusive enabling conditions

In addition, an enabling condition is needs to be specified for each static section that returns true if the property is holding the short value that matches the longer value in the label control of that section. Figure 5 shows the enabling condition for section with the High Priority label control. The enabling conditions for the other two sections are similar except they obviously check for ‘med’ and ‘lo’ instead of ‘hi’.

Figure 5: Enabling condition for the ‘High Priority’ value
Figure 5: Enabling condition for the ‘High Priority’ value

The result is that only one of the static sections is executed for a use case and it is the one whose label control text corresponds to what is in the use case’s value property

Only Including Diagrams When Asked

Another straight forward example of an enabling condition is checking whether diagram images should or should not be included in the generated documents.

Whenever a image control is used to include the image of a diagram in the generated documents it should be guarded by an enabling condition that checks the value of the Include diagrams option specified in The Generate Documentation Using Template dialog.

Figure 6 shows the OCL expression needed to check the document generator option. It uses the special OCL function getDGOption() that takes the name of the option and returns either ‘yes’ or ‘no’ or the empty string if the name supplied does not match one of the document generator options.

Figure 6: Checking if diagrams should be included
Figure 6: Checking if diagrams should be included

Guarding against infinite loops in recursive calls

A more sophisticated example of an enabling condition is a guard against infinite loops when using a recursive call of a template. The section Recursive calls and Infinite Loops on page 51 describes how to pass a parameter to a template being called recursively.

To ensure the recursion does not go on infinitely, an enabling condition can be added to the Call to Template section to check the value of the parameter is within the expected bounds.

Figure 7: A template that calls itself
Figure 7: A template that calls itself

Figure 8: Passing and checking a parameter controlling depth of recursion Figure 8: Passing and checking a parameter controlling depth of recursion
Figure 8: Passing and checking a parameter controlling depth of recursion

Figure 8: shows a simple template that illustrates guarding against infinite recursion. The template uses the special OCL function getParam()to display the value of the level parameter that has been passed to the template (it has a default value of ‘1’). The template then calls itself.

Figure 7 shows how the section’s properties dialog is used to set the new value of the level parameter passed to the next call of the template. This is simply the same as the previous call with an extra ‘1’ character appended to the end of the string.

Figure 8 also shows the enabling condition on the Call to Template section that prevents infinite recursion and stack overflow. The enabling condition is evaluated before the call to the template is executed. As long as the enabling condition returns true the template is allowed to call itself again. When the level parameter equals the specified value the enabling condition returns false and the next call to the template is prevented from being processed, effectively executed halting the recursion.

Although OCL expressions enable considerably more sophisticated expressions to be used to manage the recursion, string concatenation illustrates the principles involved very simply.

The Disabled Property

As well as an enabling condition property, every type of section also has a disabled property. This is located below the enabling condition (see Figure 9).

Unlike the enabling condition, this cannot be used to implement if-then-else style logic. Any sections that have the disabled property checkbox ticked are simply ignored when the template is being processed.

At first glance the disabled property does not sound very useful. In practise, it can be very useful indeed.

Firstly, the property can be used to turn off functionality that is no longer needed without actually deleting the content. When it is suspected that the functionality or something similar may be needed again at some point in the future, using the disabled property instead of deleting large chunks of template can save time reinstating it.

Secondly, when the document generator stops with an error and it is unclear which section is causing the problem, enabling and disabling sections in a systematic manner to identify the errant one through a process of elimination is a tedious but effective technique.

Finally, combining the disabled property with extra static sections can provide trace output when debugging a complex template. Simply add static sections with label, data, or formula controls indicating the point in the template that the processer has reached, together with any model or generator data values needed for diagnostic purposes. Then set the format of the output so that it is easily distinguishable from the main generated content (brightly coloured text for example). Now when the template is run, the trace information is embedded in the generated content.

Figure 9: Trace info as extra static sections
Figure 9: Trace info as extra static sections

Once the template is working as correctly, instead of deleting the extra sections, switch them off by ticking their disabled property. Now the static sections can be switched back on again easily if required. Also, the label controls in these sections can be useful as documentation for those browsing the template.