Umple Combined User Manual
http://www.umple.org
This version is one large page and is intended to allow searching through the entire manual, or easy printing to pdf for offline reading. For most purposes you will want to work with the individual manual pages at http://manual.umple.org

Getting Started

Umple is a technology for Model-Oriented Programming.

Umple allows you to do the following things:

  1. Create UML models textually. It can often be faster to create UML class diagrams and state machines using Umple's textual format that looks just like programming-language code. Editing, comparing and many other tasks can often be faster using this textual form. Umple has tools that allow you to edit the model textually (and see changes appear in a UML diagram) or to edit a UML diagram (and see changes appear in the textual code)

  2. Add UML modeling constructs directly into your programs, when you are programming in Java, PHP, C++ or Ruby. For example, when programming in Java, you can directly add a UML state machine into your code. This can save you a lot of coding. The Umple compiler acts as a pre-processor, first compiling the state machine to Java, and then compiling the Java into an executable program.

  3. Generate high quality code from UML models. The Umple compiler creates code in languages like Java, C++ and PHP that is of top quality. It is a goal of the Umple team to create the best open-source code-generation tool available. The generated code never needs to be edited and never should be edited, since if the generator doesn't create code of the type you would like, you can always embed native (i.e. Java, Php, etc.) methods in the Umple, or else use Umple's aspect oriented capabilities to achieve what you need. As a last resort, you can edit the code generator, since it is open source. As a result the concept of 'round tripping' is obsolete in Umple. You should treat Umple-generated code just lke you would treat bytecode-or machine code, i.e. as a development artifact that can be thrown away and recreated. Nevertheless, we have endeavoured to make the generated code as clean and readable as possible so you can verify its correctness and learn how it works.

  4. Incrementally Umplify a program. A program in a base language like Java should pass through the Umple compiler unchanged. As a result you can incrementally refactor such a program, stripping off complex code for such things as associations, state machines and patterns, and replacing it by simple Umple code. This can be done bit-by-bit, while testing thoroughly at each step. When you are done, you will have a program that should not only be more compact, but also more reliable and more maintainable. In addition, you have the benefit of being able to view UML diagrams of your program.

The term "Umple" derives from "UML Programming Language", "Simple" and "Ample".

The quickest way to get started with Umple is to go to UmpleOnline, and select an example listed under 'Select Example'. Each of these user manual pages also allows you to instantly load the examples into UmpleOnline.

To learn more about Umple, read the links on the left of this page, or go to the Umple Home page. In particular, you should browse the tutorials and videos about Umple


See here for the statement regarding privacy and other risks when using Umple.


If you are an ordinary user and notice an error in this manual, please report it using our issue tracking system here Flag it as a defect in the user documentation. If you still have trouble after reading this manual, please contact our help mailing list and post a request for help. If you are a contributer, instructions on how to edit this manual are here.

Hello World Examples

As is customary when introducing a new language, here are some 'hello world' examples for Umple. Load these examples into UmpleOnline by clicking on the links. Then generate Java code by clicking on the 'Generate' button. Next click on the 'download zip file' link and run 'javac' on the result or else compile it in Eclipse.

First example below: This looks identical to how a Java 'hello world' example would look, illustrating a key feature of Umple: Umple adds features to existing languages: Code in the original language can and does remain the same. Umple just replaces and simplifies some (or a lot) of it.

Second example below: This shows some very simple features of Umple: An attribute, an association, a generalization, some Java methods and the mixin capability:

Umple and UML: Here is the class diagram of the second example in UML. If you click on the 'open in UmpleOnline' link, you will see the UML diagram generated. You can then edit the UML diagram to change the code, or change the code to edit the UML diagram.

UML class diagram showing superclass Person (with attribute name), and with subclasses Student and Mentor. There is a 0..1 -- * association between the subclasses.

Example

/*
 * Simple Hello World example for Umple.
 * Compile this with Umple and it will generate Java
 * that is essentially the same.
 * 
 * You could just as readily compile this code directly
 * with javac. However, this serves as the starting point:
 * Other examples in this manual show other things you
 * can do with Umple
 */
class HelloWorld {
  public static void main(String [ ] args) {
    System.out.println("Hello World");
  }
}


      

Load the above code into UmpleOnline

 

Another Example

/*
 * Introductory example of Umple showing classes,
 * attribute, association, generalization, methods
 * and the mixin capability. Generate java and run this.
 * 
 * The output will be:
 * The mentor of Tom The Student is Nick The Mentor
 * The students of Nick The Mentor are [Tom The Student]
 */
class Person {
  name; // Attribute, string by default
  String toString () {
    return(getName());
  }
}

class Student {
  isA Person;
}

class Mentor {
  isA Person;
}

association {
  0..1 Mentor -- * Student;
}

class Person {
  // Notice that we are defining more contents for Person
  // This uses Umple's mixin capability
  
  public static void main(String [ ] args) {
    Mentor m = new Mentor("Nick The Mentor");
    Student s = new Student("Tom The Student");
    s.setMentor(m);
    System.out.println("The mentor of "  + s  + " is " +  s.getMentor());
    System.out.println("The students of " +  m  + " are " +  m.getStudents());
  }
}
      

Load the above code into UmpleOnline

 

Umple Tools

Umple files conventionally use the extension .ump. To create a model or a system you would use one or more of the following tools to view, edit and compile .ump files.

More details on downloading, installing and running Umple can be found here.

Structure of Umple Code

Organizing the contents of an Umple (.ump) file

An Umple file will contain a number of directives. These can be:

 

Methods in classes

Much of the code in an Umple file is processed by the Umple compiler, and used to generate code in a 'base' or 'native' language (e.g, Java, PHP or Ruby) for the final system. However methods are treated differently: They are passed through essentially unchanged to the resulting system.

If you include methods in Umple code, you therefore have to ensure that any given Umple file has methods of just one chosen target language (Java, PHP, Ruby. etc.).

Anything that Umple can't parse itself may be interpreted to be a method; this can result in unintended results: What you intend to be some Umple code such as an attribute or association may end up being treated as 'extra code', i.e. a method, and passed through unchanged without warning, with the result that expected functionality in the generated system is missing. You can use the strictness directive to force Umple to warn when this occurs; this can be particularly useful in early development, when the Umple is intended to be only a model

The resulting system will contain many more methods than those that you explicitly include. This is because one of the key points about Umple is that it generates a high percentage of the methods you would normally need to write by hand if you were programming directly in the target language. In other words, when you compile Umple constructs such as assocations, attributes and state machines, you are generating many methods that you can call; the set of methods you can call is the generated API. You can find out the API by using Javadoc, or a similar tool, on the generated code, or you can look at the quick reference manual page. One of the options in UmpleOnline is to generate Javadoc output.

 

Organizing a system containing many files

If your system is large, you should divide it into many files. One way to do this is to follow the Java convention of having one .ump file per class. Another common approach is to have one or more files for the model code (just the pure UML elements such as classes with their attributes, associations and state machines) and separate files for the methods; you can in fact have some files for Java methods, and other files for PHP or Ruby methods. The same model can then be used to deveop systems that are deplpyed in multiple base languages.

The fact that Umple allows for multiple definitions to be added to create a complete definition, also means that you can create mixins. A mixin is a file that has some definitions that can be added to add extra features to a system. You can therefore organize your system, in whole or in part, by feature. The various pieces of code needed to implement a feature (including entire new classes, or bits such as associations and methods to add to existing classes), can be therefore be grouped together. There are limits to this, however: At the current time, this mechanism does not allow you to override existing elememts, which you might need to do to add a feature. Taken together, these mechanisms allow for a form of product-line development. Umple does, however, have an extra feature, called VML that should assist with this when complete.

@@syntax [[program]] [[comment]] [[directive]] [[useStatement]] [[namespace]] [[entity]]

Convincing Potential Adopters

Convincing yourself, your development team or your management to use Model-Oriented Programming with Umple

Here are some arguments to make to help convince you, your management and your colleagues to adopt model-oriented programming and Umple in particular:

  1. Model-code duality: Umple means you no longer have to maintain models separately from the code. Your code and model become the same thing. Your models therefore don't get out of date and your volume of separately-maintained documentation becomes less. Model elements in the Umple code, along with their comments, become the design documentation.

  2. Rapid application development: Models containing the essential structure of a system can be developed extremely fast, and modified extremely rapidly. This is because most people can edit Umple text faster than they can use a drawing tool. But the ability to use a drawing tool is not sacrificed you can still draw an Umple model as a diagram with UmpleOnline!

  3. Less code to write: Code for UML constructs like associations, state machines and certain patterns is generated. Less code means fewer bugs. Developers can concentrate on the more interesting or critical parts of your code.

  4. Fewer bugs: It is extremely difficult to consistently write bug-free code for complex constructs like state machines, or associations that maintain referential integrity and respect multiplicity constraints. Umple does this for you.

  5. The full power of UML features: Unlike Umple, most other code generators do not generate code that enforces multiplicity in class diagrams, or allows unlimited levels of nesting of state machines. Umple has incorporated the research of several PhD and masters theses to deliver state-of-the-art code generation.

  6. Text-diagram duality: Umple allows visualization of key aspects of your code with UmpleOnline. Furthermore the diagram can be edited to change the code, or the code can be edited to change the diagram. Both of these occur in real time.

  7. Product-line and feature-oriented development: Umple brings mixin technology to Java and PhP, allowing you to easily build different versions of your software for different customers or hardware platforms. Umple code can also be organized on a feature-by feature basis.

  8. Aspect orientation to adapt generated code: You can inject your own code before and after any generated methods to enforce constraints or change semantics.

  9. Generation for multiple languages: Umple allows development targeted to several different programming languages at the same time: All the developer has to do is to maintain language-independent files for the models, and link them to language-specific code for algorithms.

  10. Incremental adoption: You can start with just one Umple statement in a million lines of code and gradually increase Umple usage. Your software will remain fully compliable and functional as you gradually increase your uptake of Umple.

  11. Use just like a pre-processor: Programmers have been confidently using pre-processors for half a century.

  12. Fully open source with a liberal license: If you dont like something about Umple you can fix it and contribute to the community. But there are no restrictions on what you do with Umple or its generated code since it uses an MIT-style license.

  13. Commitment to the future: The team at the University of Ottawa developing Umple plan to continue active development for the years to come. This will not become one of those research programs that comes to an end and is then abandoned. We recognize that ideas can take decades to percolate to the community. We plan to be right there supporting Umple as this happens.

Countering the counterarguments

Here are some common arguments against adopting a new software development technology, and how they dont apply in model-oriented programming:

  1. Complexity: Adding a new technology might add more complexity to our project so might require more learning by our employees and might make our systems harder to understand:
    Not true for Umple, because:

  2. Confidence: Our company would have no way to be confident about whether it works or not and we do not have the time or resources to do the needed due diligence:
    Not true for Umple, because:

  3. Support: If the technology stopped being supported, we would not be able to maintain our code base.
    Not true for Umple, because:

  4. Process: Our testing and building processes are likely to only work for well-known technologies:
    Not true for Umple, because:

  5. Compatibility: We use a lot of re-used, proprietary or legacy code that might be incompatible with the new technology:
    Not true for Umple, because:

Umple Comments

Comments provide a mechanism to document your work to provide some insight into why you are performing a certain action, as opposed to simply showing how.

Comments should be used just like in any programming language.

Comments immediately before class definitions, attribute definitions, association definitions and method definitions, as well as comments embedded in methods will be output into the generated code. Comments before definitions in Java will use Javadoc style; this means that when you generate JavaDoc output the API documentation will contain the comments. You are encouraged to create your Java comments using Javadoc tags.

Comments can be either inlineComments, or multilineComments.


Example

// The Umple system is both fun and efficient to development with


      

Load the above code into UmpleOnline

 

Another Example

// The Umple system is both fun and efficient to development with
/* 
  This apple can only be compared to 
  other apples
*/


      

Load the above code into UmpleOnline

 

Inline Comments

Use two slashes to place comments after any text on the line. The comment ends at the end of the line. This is the same syntax as in Java, C++ and several other languages.

Example

// Umple is both fun and efficient to develop with


      

Load the above code into UmpleOnline

 

Syntax


inlineComment- : // [**inlineComment]

Multiline Comments

Use multiline comments starting with slash-star and ending with star-slash to document your work. You should put a comment block, for example, at the beginning of each file.

This syntax is the same as in Java and C++.

Example

/* 
  This apple can only be compared to 
  other apples
*/


      

Load the above code into UmpleOnline

 

Syntax


multilineComment- : /* [**multilineComment] */

Types of Directives

Directives appear as the 'main' entries in an Umple file.

Syntax


// Directives are the top-level items in an umple file. See manual page TypesofDirectives
// A directive is either used to configure the system or else is
// an actual entity of the system to be modelled or generated
directive- : [[glossary]]
    | [[generate]]
    | [[distribute]]
    | [[generate_path]]
    | [[filter]]
    | [[useStatement]]
    | [[namespace]]
    | [[tracerDirective]]
    | [[entity]]
    | [[debug]]
    | [[strictness]]
    | [[toplevelExtracode]]
    | [[toplevelException]]

// The generate clause can be used to generate multiple outputs
// The --override is used to say that subsequent generate statements will be ignored
generate : generate [=language:Java
    |Php
    |RTCpp
    |SimpleCpp
    |Ruby
    |Cpp
    |Json
    |StructureDiagram
    |Yuml
    |Violet
    |Umlet
    |Simulate
    |TextUml
    |Scxml
    |GvStateDiagram
    |GvClassDiagram
    |GvClassTraitDiagram
    |GvEntityRelationshipDiagram
    |Alloy
    |NuSMV
    |Papyrus
    |Ecore
    |Xmi
    |Xtext
    |Sql
    |Umple
    |UmpleSelf
    |USE
    |Test
    |SimpleMetrics
    |Uigu2] ( [=suboptionIndicator:-s
    |--suboption] " [**suboption] " )* ;

generate_path : generate [=language:Java
    |Php
    |RTCpp
    |SimpleCpp
    |Ruby
    |Cpp
    |Json
    |StructureDiagram
    |Yuml
    |Violet
    |Umlet
    |Simulate
    |TextUml
    |Scxml
    |GvStateDiagram
    |GvClassDiagram
    |GvClassTraitDiagram
    |GvEntityRelationshipDiagram
    |Alloy
    |NuSMV
    |Papyrus
    |Ecore
    |Xmi
    |Xtext
    |Sql
    |UmpleSelf
    |USE
    |test] " [**output] " [=override:--override
    |--override-all]? ( [=suboptionIndicator:-s
    |--suboption] " [**suboption] " )* ;

// Use statements allow incorporation of other Umple files. See UseStatements
useStatement : use [use] ;

// Namespaces divide the code into logical groups. See NamespaceDirectives
namespace- : namespace [namespace] ;

// The main top level elements to be found in an Umple file
entity- : [[classDefinition]]
    | [[traitDefinition]]
    | [[fixml]]
    | [[interfaceDefinition]]
    | [[externalDefinition]]
    | [[associationDefinition]]
    | [[associationClassDefinition]]
    | [[stateMachineDefinition]]
    | [[templateDefinition]]

Use Statements

Use statements allow you to decompose your system by embedding or referencing other model or program entities (i.e. classes) within your current model.

A model file will only be included once, subsequent "use" commands for the same file will be ignored.

A common technique is create a 'master' Umple file that does nothing but have a list of use statements.

Parts of an individual class can be specified in separate files, and brought together using several use statements. For example the associations or attributes could be in one (or several) files, and the methods could be in one (or more) additional files.

Another way to decompose a system is to have a 'core' set of files that can be included in several different systems using use statements.

Use statements work in a manner similar to 'include' directives in other languages.

Example

use Core.ump;

      

Load the above code into UmpleOnline

 

Syntax


// Use statements allow incorporation of other Umple files. See UseStatements
useStatement : use [use] ;

Namespace Directives

Namespaces allow you to group similar entities to promote cohesion, as well as reduce the possibility of name collision.

Example

namespace school.admin;

class Faculty{}
class Student{}

namespace elevator.structure;

class Building
{
  1 -- * Classroom;
}

class Classroom{}

      

Load the above code into UmpleOnline

 

Syntax


// Namespaces divide the code into logical groups. See NamespaceDirectives
namespace- : namespace [namespace] ;

Strictness Directive

The strictness directive is used to control certain messages that the Umple compiler may issue. It has five subdirectives that are specified by a second keyword following 'strictness':

The first two are 'modelOnly' or 'noExtraCode'. These are used when the programmer or modeller intends not to include base language code, and wants a warning to appear if base language code is found. Base language code is code in a language like Java or PhP that is discovered by Umple but not interpreted in any way. One example is the code in the bodies of methods; however, when parsing a class, any time Umple can't parse what it finds, it assumes it must be base language code. It just emits the base language code for the base language compiler to deal with. However there are circumstances when the developer does not want this: The developer may be creating a pure model or may want intend that the only base language code would in the body of methods. It is advantageous therefore to tell the compiler to raise a warning if it thinks it has found base language code in some other context, since otherwise, and ordinary Umple syntax error may go undetected, until the base language compiler is run on the code.

The second set of subdirectives are 'expect', 'allow' and 'disallow'. These are used to control the effect of certain messages. They are followed by a message number. 'expect n' declares that message number n should occur; it is an error if the message does not. This is used in testing to create example cases of message n; an error would be triggered if message n does not appear. 'allow n' is used in the case of errors, to tell the compiler to not actually 'fail', but to report that error as if it was a warning. This is also used in testing to include cases that give message n, without the compiler reporting that it has failed. 'disallow n', where n is a warning, tells the compiler to treat n as if it was an error, and fail the compilation. Some of the above are still under development.

Example

// Tell the compiler that error 25 will appear (and fail if it does not)
strictness expect 25;

// Tell the compiler that if error 22 occurs, not to fail the compile.
// However, this does not mean that code can be generated
strictness allow 22;

// UNDER DEVELOPMENT: The following is not operational yet
// Tell the compiler that  base language code should not appear
strictness modelOnly;

// Tell the compiler that the only base language code could be in method bodies
// Any other unparsable 'extra code' in classes will be rejected.
strictness noExtraCode;


      

Load the above code into UmpleOnline

 

Syntax


// A high level of strictness will cause warnings to be issued when base language code
// is found, where it might not have been intended. Strictness can also be used
// To either suppress certain messages, or to declare that they should be present.
// NOTE: This is currently under development
strictness- : strictness ( [=strictness:modelOnly|noExtraCode|none]
    | [[strictnessMessage]] ) ;

Class Definition

A class definition defines an object-oriented class available for use as a type in your system.

To define a class, specify the keyword 'class', followed by the name of the class (starting in a capital letter) and then the body of the class within curly brackets. The body can contain various elements that are listed in the Class Content page.

The following UML diagram shows two classes: a Student class and an Address class, linked by an association. The corresponding Umple is below.

UML diagram showing Student and Address

Example


class Student
{
  firstName;   // attribute - defaults to String
  lastName;
  Integer number;  // attribute with type Integer
  * -- * Address;  // Many-to-many association
  
  public String fullName()  // Method, whose content is not processed by Umple
  {
    return getFirstName() + " " + getLastName();
  } 
}

class Address
{
  String[] line;  // Multi-valued attribute
}
      

Load the above code into UmpleOnline

 

Syntax


// Classes are the most common elements in Umple.
// See user manual page ClassDefinition
classDefinition : class [name] { [[classContent]]* }

// The following items can be found inside the body of classes or association classes
classContent- : [[comment]]
    | [[distributable]]
    | [[proxyPattern]]
    | [[classDefinition]]
    | [[trace]]
    | [[emitMethod]]
    | [[templateAttributeDefinition]]
    | [[primitiveDefinition]]
    | [[portDefinition]]
    | [[portBindingDefinition]]
    | [[position]]
    | [[displayColor]]
    | [[abstract]]
    | [[keyDefinition]]
    | [[softwarePattern]]
    | [[depend]]
    | [[symmetricReflexiveAssociation]]
    | [[attribute]]
    | [[stateMachine]]
    | [[activeMethodDefinition]]
    | [[inlineAssociation]]
    | [[concreteMethodDeclaration]]
    | [[constantDeclaration]]
    | [[modelConstraint]]
    | [[invariant]]
    | ;
    | [[exception]]
    | [[extraCode]]

interface Definition

An interface defines a list of methods that are to be implemented in one or more classes. An interface can be composed of the following elements:

Umple currently supports Java, PHP and Ruby as native languages.

To implement an interface in a class, or to create subinterfaces, use an isA clause.

Example

interface RegisterCapable
{
  depend school.util.*;
  
  boolean registerForCourse(Course aCourse);
}

class Person {
  name;
}


class CorporateClient {
  isA RegisterCapable;
  boolean registerForCourse(Course aCourse) {
     // write code here
  }
  0..1 <- * Person employees;
}

class IndividualStudent {
  isA Person, RegisterCapable;
  boolean registerForCourse(Course aCourse) {
     // write code here
  }
}


class Course
{
  name;
  description;
  * -- * Person registrants;
}
      

Load the above code into UmpleOnline

 

Syntax


// An Interface can only contain method. See interfaceDefinition
interfaceDefinition : interface [name] { [[depend]]* [[interfaceBody]] }

// Interfaces: Note that if the format of an abstractMethodDeclaration is not
// followed, then the body will extraCode and passed to the base language
// See user manual page interfaceDefinition
interfaceBody- : [[interfaceMemberDeclaration]]*

interfaceMemberDeclaration : [[comment]]
    | [[constantDeclaration]]
    | [[constantDeclarationDeprecated]]
    | [[abstractMethodDeclaration]]
    | [[position]]
    | [[displayColor]]
    | [[isA]]
    | [[distributableInterface]]
    | [[exception]]
    | [[extraCode]]

Class Content

A class can contain any of the following items. Interfaces are limited to those indicated.

isA clause

The isA keyword is used to denote an inheritance relationship (generalization) between two classes, or a class and the interfaces it implements, or a class and the traits it includes.

This corresponds to keywords such as 'extends', 'subclass', etc. in other languages. The isA keyword was chosen so as to be independent of other languages, and due to the strong conceptual similarity between interfaces, classes and traits.

Note that it is possible to avoid using the isA keyword for class generatlization, by directly embedding a subclass inside a superclass. Note that this does not create an inner class in the Java sense, but instead creates a subclass. The two examples below give identical results.

The following is how a generalization appears in UML. The corresponding Umple is below. Note that in UmpleOnline, the expected layout for generalizations places superclasses above subclasses.

Generalization with Person as superclass and Student as subclass

Example

// A superclass-subclass relationship defined using the isA keyword
class Person
{
  name;
}

class Student
{
  isA Person;
  Integer number;
}
      

Load the above code into UmpleOnline

 

Another Example

// A superclass-subclass relationship defined
// by embedding the subclass in the superclass
class Person
{
  name;
  
  class Student
  {
    Integer number;
  }
}

      

Load the above code into UmpleOnline

 

Syntax


// Generalization and inheritance isAclause
isA- : [[singleIsA]] | [[multipleIsA]]

singleIsA- : isA [[isAName]] ( , isA [[isAName]] )* ;

multipleIsA- : isA [[isAName]] ( , [[isAName]] )* ;

Depend clause

The depend clause is used to indicate a dependency to another namespace, class or interface.

See also this example of how to use the depend clause to arrange for Umple to work with external code.

Example

namespace sports.core;

class Equipment
{
  name;
  Integer weight;
}

namespace sports.baseball;

class Baseball
{
  depend sports.core.*;

  public boolean isRequired(Equipment eq)
  {
    return eq.getName().equals("bat");
  }
}


      

Load the above code into UmpleOnline

 

Syntax


// Depend clause. See user manual page Dependclause
depend- : depend [depend] ;

Traits

A trait is a partial description of a class that can be reused in several different classes.

To have a class include the content of a trait, you use the 'isA' directive, in the same manner as specifying a superclass, or an implemented interface. Traits should therefore be named to be consistent with this. For example, if you wanted to include in several classes the notion of having a colour, and some methods to manipulate the colour, you could create a trait called Colourable. The classes to be colourable would include 'isA Colourable;'. This is very similar to the way interfaces and inheritance are defined; the difference is that virtually any model or code elements can be in a trait, and they will be 'copied' into each class.

Traits can be used in place of standard inheritance where there is already a superclass, since multiple inheritance isn't allowed in Umple to be consistent with Java and several other languages. Traits can be used to inject attributes, associations, state machines, constraints, methods and many other elements. They are one of several approaches in Umple to separation of concerns; the others are the mixin ability (ability to specify a class several times and have the elements added together), and the aspect oriented capabilities. Note that traits themselves are subject to being mixed in; you can declare two parts of the same trait in two different places in an Umple system.

Traits are not part of UML. A UML class diagram drawn from an Umple file containing traits will 'flatten' the traits. The trait elements will appear in all classes that include that trait. In the first example below, the name and address attribute will appear in the class diagram of both Person and Company.

Example

// Example of use of a trait in Umple
// The trait has regular attributes, derived attribute
// and a method that are copied into Organization
// and Company
trait Identifiable {
  firstName;
  lastName;
  address;
  phoneNumber;
  fullName = {firstName + " " + lastName}
  Boolean isLongName() {return lastName.length() > 1;}  
}

class Person {
  isA Identifiable;
}

class Organization {
  Integer registrationNumber;
}

class Company {
  isA Organization, Identifiable;
}
      

Load the above code into UmpleOnline

 

Syntax


traitDefinition : trait [name] [[traitParameters]]? { [[traitContent]]* }

traitContent- : [[requiredModelElements]]
    | [[comment]]
    | [[traitDefinition]]
    | [[trace]]
    | [[position]]
    | [[displayColor]]
    | [[abstract]]
    | [[keyDefinition]]
    | [[softwarePattern]]
    | [[depend]]
    | [[symmetricReflexiveAssociation]]
    | [[attribute]]
    | [[stateMachine]]
    | [[inlineAssociation]]
    | [[concreteMethodDeclaration]]
    | [[abstractMethodDeclaration]]
    | [[constantDeclaration]]
    | [[invariant]]
    | ;
    | [[exception]]
    | [[extraCode]]

Attribute Definition

An attribute represents some information held by a class.

The attribute can have many properties, and can be defaulted to a certain value.

It is important to distinguish an attribute from the concept of a 'field' or 'instance variable' in Java or another programming language. An attribute is a UML/Umple entity that represents simple data. In Java it will become a field, but there will also be methods associated with the Umple attribute to get it, set it, and constrain its value. An attribute may also automatically be added to the argument list of the constructor and constructed in the constructor. In addition to representing attributes, Java fields also represent the ends of associations. Both attributes and associations should be considered more abstract than fields

Umple state machines are a special kind of attribute, and Umple also allows you to inject code that will constrain or alter the values of attributes using aspect-oriented techniques.

The example below shows the basic properties of attributes.

Example


class Group 
{
  // Simple Umple Integer. Note that code generation in different languages will
  // use the simplest native type in that language. In Java it will use int.
  // The initial value must be supplied through a constructor argument.
  // The value can later be accessed through set and get methods
  // (here setI and getI).
  Integer i;

  // const: Declares a constant (static final in Java).
  const Integer max = 100;

  // immutable: A constructor argument is required so it can be set at
  // construction time; cannot be changed after that since no set method
  // is generated.
  immutable String str;
  
  // lazy: A constructor argument is not required. Numbers are initialized
  // to zero, Objects (including Strings) are initialized to null,
  // Booleans are initialized to false.
  lazy Time t;
  lazy Boolean b;
  lazy s;
  
  // settable: Set using a constructor argument and can be changed after that.
  // This is the default, so the settable keyword can be omitted.
  settable Date d;
  
  // internal: No getter and setter methods created. Only for private
  // use in internal methods. However in this case it is initalized using =
  // The code following = is in the 'base' language, here Java.
  internal Time t2 = new Time(System.currentTimeMillis());

  // autounique: Every new object created will have a new integer assigned.
  // You can get the value (an integer) but not set it.  
  autounique x;

  // The value is initialized as shown in the constructor.
  // There is no constructor argument generated.
  String q = "chicken"; 
      
  // defaulted: Set in the constructor to the default, and can be reset to the
  // default any time by calling a reset method (here resetP()). 
  // Can also be set to any other value using setP().
  // The default can be queried by calling getDefaultP().
  defaulted String p = "robot";
  
  // Similar to the above, except this shows that if no type is given,
  // then the default type is String.
  // Note that currently in Umple the space before and after the =
  // is required.
  defaulted r = "";
}

      

Load the above code into UmpleOnline

 

Syntax


// Details of attributes. See user manual page AttributeDefinition
attribute : [[simpleAttribute]]
    | [[autouniqueAttribute]]
    | [[derivedAttribute]]
    | [[complexAttribute]]

simpleAttribute- : [=gpIdentifier:%]? [~name] ;

autouniqueAttribute- : [=autounique] [~name] ;

derivedAttribute- : [=modifier:immutable
    |settable
    |internal
    |defaulted
    |const
    |fixml]? [[typedName]] = ( [[moreCode]] )+

complexAttribute- : [=unique]? [=lazy]? [=modifier:immutable
    |settable
    |internal
    |defaulted
    |const
    |fixml]? [[typedName]] (= [**value])? ;

Umple Builtin Data Types

The following examples illustrate the data types available for Umple attributes. Except as specified, they will generate primitive datatypes in Java

Example


class Demo 
{
  Integer i;
  Float flt;
  String str;  // the default of no type is specified
  Double dbl;
  Boolean bln;
  Date dte; // In Java. uses the java.sql.Date class
  Time tme; // In Java. uses the java.sql.Time class
}

      

Load the above code into UmpleOnline

 

Another Example


class DemoNonUmpleType
{
  // If you use a non-umple type that is specific to a base
  // programming language, then code will be generated
  // consistent with that type, but generation of code
  // independent of base language is no longer possible
  int demoJavaInt;
}

      

Load the above code into UmpleOnline

 

Classes as Attribute Types

You can declare a class as a data type of an attribute. This allows for declaration of a 'containment' relationship.

If you use the methods in the Umple-generated API to access the object stored in such an attribute, and pass this contained object to some remote subsystem, then that remote subsystem will be able to affect the containing object in a backhanded sort of way. This is considered content coupling in software engineering, and should be carefully controlled or avoided. We may in future add a capability to Umple to ensure this cannot happen.

In the examples below, we show how using attribute notation is very simular to using a directed association, except that with attribute notation, you can set the value to null.

Example

// This first example uses attribute notation
// The address is required on the constructor, but can be null
// An instance of Address can be considered to be contained
// within the Person class.
//
// Although there is nothing currently preventing the same address
// from being re-used in multiple classes, it is strongly suggested
// to avoid that. If you want to reuse the same Address, then use
// association notation instead.
class Person {
  name;
  
  // The following uses a class as the attribute type
  Address address;
}

class Address {
  street;
  city;
  postalCode;
  country;
}


      

Load the above code into UmpleOnline

 

Another Example


// Contrast this example with the previous one
// Here we use a directed association instead of an attribute.
// Note that the multiplicity on the left is of no relevance.
// It is conventional to show it as * to indicate that the
//  value could be attached to several objects.
//
// Here when you construct a Person, the address cannot be
// null. 
class Person {
  name;
  
  * -> 1 Address address;
}

class Address {
  street;
  city;
  postalCode;
  country;
}
      

Load the above code into UmpleOnline

 

Another Example

// In this example, we have made the address optional. Now, 
// it does not appear on the constructor. However when you
// add an address it still cannot be null.
//
// Note also that in this example, the role name 'address'
// is left off to show  it is optional.

class Person {
  name;
  
  * -> 0..1 Address;
}

class Address {
  street;
  city;
  postalCode;
  country;
}
      

Load the above code into UmpleOnline

 

MultiValued Attributes

As in UML, you can have attribute with multiple values.

We encourage the use of association notation in this context, however the attribute notation can be useful sometimes.

Example

class Office {
   Integer number;
   Phone[] installedTelephones;
} 

class Phone {
  String digits;
  String callerID;
}


      

Load the above code into UmpleOnline

 

Syntax


complexAttribute- : [=unique]? [=lazy]? [=modifier:immutable
    |settable
    |internal
    |defaulted
    |const
    |fixml]? [[typedName]] (= [**value])? ;

Lazy Immutable Attributes

If you want to avoid having an attribute change after it is initially set, but do not want to have an argument in the constructor, then use the combination of keywords 'lazy immutable'.

You can call the set method just once on such an attribute. The set method will return false if you try again. This is useful for interacting with architectures where objects are constructed for you, so you have no ability to specify constructor arguments.

Note that if the lazy keyword is omitted, then there will be no set method and an argument will be present in the constructor to initialize the attribute. See also the immutable pattern.


Example

class A 
{
    lazy immutable z;
}

      

Load the above code into UmpleOnline

 

Syntax


complexAttribute- : [=unique]? [=lazy]? [=modifier:immutable
    |settable
    |internal
    |defaulted
    |const
    |fixml]? [[typedName]] (= [**value])? ;

Derived Attributes

When declaring an attribute in Umple, you can specify an arbitrary expression after the equals sign to create an attribute that will be computed. There will be no set method on such an attribute.

Note that unless you use the simplest of expressions, you will be limited to only being able to generate code for the language of the expression.

You should make sure you call the get methods provided in the Umple-generated API (rather than directly accessing variables) and avoid having any side-effects in your expressions. Currently this is not enforced, but may be in the future.

For other examples of derived attributes see the sections on the Delegation pattern and sorted associations.

Example

class Point 
{
    // Cartesian coordinates
    Float x;
    Float y;
    
    // Polar coordinates
    Float rho = {Math.sqrt(Math.pow(getX(), 2) + Math.pow(getY(), 2))}
    Float theta = {Math.toDegrees(Math.atan2(getY(),getX()))}
}


      

Load the above code into UmpleOnline

 

Another Example

class Rectangle {
  Double height;
  Double width;
  Double area = Java {height*width} Php {$height*$width}
}  

      

Load the above code into UmpleOnline

 

Syntax


derivedAttribute- : [=modifier:immutable
    |settable
    |internal
    |defaulted
    |const
    |fixml]? [[typedName]] = ( [[moreCode]] )+

Aspects of attributes under development

The unique keyword currently generates no code. In future the intent is that it will force all values of an attribute in your running program to be different.

If you discover any other problems or have requests please add an issue at bugs.umple.org.

Association Definition

An association defines a relationship from a class to another class. More specifically, it defines which links (i.e. references or pointers) may exist at run time between instances of the classes.

Umple supports binary associations (associations with just two ends). This definition includes reflexive associations, in which both ends are the same class.

An association can specify the following information:

The following is a UML diagram showing associations. The corresponding Umple is at the end of the page.

UML class diagram showing classes A, B and C with several associations

Associations can be presented in two ways in Umple.

There are several special kinds of associations in Umple.

Umple will report an error if the an association refers to a non-existent class.

@@example @@source manualexamples/AssociationDefinition1.ump @@endexample

Multiplicity

Multiplicity describes the allowable number of entities that can participate in one end of an association. In most cases you provide both a lower and upper bound, but the "many" (or "*") case assumes a zero lower bound.

The most common cases are:

Multiplicity must be specified for both ends of an association. At run time, code generated by Umple will ensure that the lower bounds and upper bounds are respected. Also the multiplicity determines which methods will be generated in the API for the model. For example, when * is specified, methods are generated to access all the associated objects, and to access an object at a specific index. The number of objects linked at run-time is called 'cardinality'.

If multiplicity is specified incorrectly, the compiler will generate an error message highlighting the line with the multiplicity error.

 

Example

// When multiplicity is given as *, which is the same as 0..*
// there can be any number of links from an instance at the other end
// of the association to instances at this end 
//
// The lower bound is zero and the upper bound is 'many'
// When multiplicity is given as *, which is the same as 0..*
// there can be any number of links from an instance at the other end
// of the association to instances at this end 
//
// The lower bound is zero and the upper bound is 'many'
class A
{
  // an instance of A has many B's
  1 -- * B;
  
  // An instance of C has many A's
  * -- 1 C;
}

class B {} class C {}
      

Load the above code into UmpleOnline

 

Another Example

// When the mutiplicity is shown as two integers separated by ..
// then the first integer is the lower bound, and the second integer
// is the upper bound.
//
// Here, at one end of the association
// the lower bound is 0..1 (which means 'optional'
// and at the other end of the association
// the lower bound is 3 and the upper bound is 5
class D {
  0..1 -- 3..5 E;
}

class E{}

      

Load the above code into UmpleOnline

 

Another Example

// When the multiplicity is a single integer there must be
// exactly that number of objects linked at all times (including
// when the object at the other end is first created).
// These multiplicities are rare
// Here, there must be exactly two objects (lower and upper bound are both 2)
class F {
  0..1 -- 2 G;
}

class G{}

      

Load the above code into UmpleOnline

 

Syntax


multiplicity- : [!lowerBound:\d+|[**]] .. [!upperBound:\d+|[**]] | [!bound:\d+|[**]]

Inline Associations

An association represents a relationship between two classes. Associations can be defined within a class, in a similar manner as you would define an attribute.

Contrast this with the same model defined using independently defined associations.

Example


class Group 
{
  // a many-to-many association
  // An item has zero or more groups and a group has zero or more items
  * -- * Item item;
  
  // An item has an optional description
  // The association is directed, so descriptions do not know
  // which groups link to them
  1 -> 0..1 Description;
}

class Item
{}

class Description
{}
      

Load the above code into UmpleOnline

 

Syntax


inlineAssociation : [=modifier:immutable]? [[inlineAssociationEnd]] [=arrow:--
    |->
    |<-
    |><
    |<@>-
    |-<@>] [[associationEnd]] ;

inlineAssociationEnd : [[multiplicity]] [~roleName]? [[isSorted]]?

// note: gpIdentifier = general parameter identifier
associationEnd : [[multiplicity]] [=gpIdentifier:%]? [type] [~roleName]? [[isSorted]]?

Independently Defined Associations

An association can be defined separately from the any class. Contrast this with the Umple code showing the same model with inline associations.

Example


class Group { }
class Item {}
class Description {}

association {
  * Group -- * Item;
}

association {
  1 Group -> 0..1 Description;  
}
      

Load the above code into UmpleOnline

 

Syntax


// Associations can be declared outside the body of classes.
// See user manual page IndependentlyDefinedAssociations
associationDefinition : association [name]? { ([[comment]] | [[association]])* }

association : [=modifier:immutable]? [[associationEnd]] [=arrow:--
    |->
    |<-
    |><
    |<@>-
    |-<@>] [[associationEnd]] ;

// note: gpIdentifier = general parameter identifier
associationEnd : [[multiplicity]] [=gpIdentifier:%]? [type] [~roleName]? [[isSorted]]?

association : association [associationNum];

Role Names

A role name is an additional name attached to an association. In the following example, the word 'supervisor' could be omitted, but it clarifies that the graduate student's professor is called his or her supervisor. @@example @@source manualexamples/RoleNames1.ump @@endexample

Reflexive Associations

A reflexive association is an association from a class to itself. There are two main types: Symmetric and Asymmetric.

Asymmetric Reflexive Associations: The ends of the association are semantically different from each other, even though the associated class is the same. Examples include parent-child, supervisor-subordinate and predecessor-successor.

The first and second examples below show courses having prerequisites that are other courses. It is necessary to specify a role name at one or both ends of the association to distinguish the ends. Also it is necessary to ensure that the lower bound is always zero on both ends. The reason for this is that otherwise an illogical situation would arise: For example, if you said that each course must have one or more pre-requisites, then what about the very first courses in the hierarchy? The compiler will report an error if the lower bound on a multiplicity is one or higher.

The following is how an asymmetric reflexive association appears in UML, as generated by UmpleOnline. The corresponding Umple code is in the first example below.

UML Class course with asymmetric reflexive many-many association with role names prerequisites and successors  

Symmetric Reflexive Associations: There is no logical difference in the semantics of each association end. The fourth example shows one of these: A set of courses that are mutually exclusive with each other essentially make up a set. If course A is mutually exclusive with B, then course B is mutually exclusive with A. In other words, students who have taken one course cannot take another in the set. Umple uses the keyword 'self' to identify this case. Note that at the current time the asociaton itself does not appear in UmpleOnline; this will be fixed.

 

Example

// Example asymmetric association with role names on both ends
class Course {
  * successor -- * Course prerequisite;
}

      

Load the above code into UmpleOnline

 

Another Example

// Example asymmetric association with role name on one end
class Course {
   * -- * Course prerequisite;
}

      

Load the above code into UmpleOnline

 

Another Example

// Example asymmetric association with role name on the other end
class Person {
   0..2 parents -- * Person;
}

      

Load the above code into UmpleOnline

 

Another Example

// Example symmetric association. Note the use of the keyword self
class Course {
   * self  isMutuallyExclusiveWith;
}

      

Load the above code into UmpleOnline

 

Syntax


symmetricReflexiveAssociation : [[multiplicity]] self [roleName] ;

Compositions

A composition is a subtype of association where the delete is mandatory regardless of the multiplicity (enforced delete).

Compositions are used for associations where once the objects are associated, it makes sense for the deletion of one to cause the deletion of the other. This differs from the pre-existing associations, where the delete is dependent on the multiplicity.

For example, consider the case of a Vehicle and Wheel classes. With a regular association, the code would be as follows (where a Wheel can be associated to at most 1 Vehicles, and a Vehicle can have between 2 and 4 Wheels).

See Example 1

Here, the delete code for Vehicle does not delete the associated Wheels, since the multiplicity on Wheel is 0..1 which means the Wheel can exist without a Vehicle. However, on deleting a Vehicle it would make more sense for the associated Wheels to be deleted.

This is where compositions are useful. Rewriting the above example so that a Vehicle is composed with Wheel:

See Example 2

With the composition code, notice how the delete code for the Vehicle deletes all the Wheels associated, although the multiplicity is unchanged.

Compositions can be specified inline, or as separate associations (the same way as regular associations). The following two examples are equivalent to the Wheel-Vehicle example specified above.

See Examples 3 and 4

The following diagram is a representation of how the composition in the included examples is represented in UML, as generated in an editable class diagram by UmpleOnline.

UML class diagrams for Vehicle composed with Wheel  

Syntax

The syntax for compositions is the same as for regular associations, except for the arrow used. While in regular associations, the syntax is a -- b for "a associated with b", for compositions it is a <@>- b for "a composed with b", or a -<@> b for "b composed with a". In the class diagrams generated for compositions, the symbol is a filled-in diamond arrow.

 

Example

class Vehicle {}

class Wheel {}

association {
    0..1 Vehicle v -- 2..4 Wheel w;
}

      

Load the above code into UmpleOnline

 

Another Example

class Vehicle {}

class Wheel {}

association {
    0..1 Vehicle v <@>- 2..4 Wheel w; // vehicle composed with wheels
}

      

Load the above code into UmpleOnline

 

Another Example

class Vehicle {
   0..1 v <@>- 2..4 Wheel w;
}

class Wheel {}

      

Load the above code into UmpleOnline

 

Another Example

class Vehicle {}

class Wheel {
  2..4 w -<@> 0..1 Vehicle v;
}

      

Load the above code into UmpleOnline

 

Syntax


association : [=modifier:immutable]? [[associationEnd]] [=arrow:--
    |->
    |<-
    |><
    |<@>-
    |-<@>] [[associationEnd]] ;

inlineAssociation : [=modifier:immutable]? [[inlineAssociationEnd]] [=arrow:--
    |->
    |<-
    |><
    |<@>-
    |-<@>] [[associationEnd]] ;

association : association [associationNum];

Association Specializations

A specialization is a subset of duplicate associations where:

For example, consider the case of Vehicle and Wheel classes and an Optional One to Many association between them. A Wheel can only belong to one Vehicle, but the concept of a Vehicle can include any number of Wheels. Say, for instance, we wanted to create a new Bicycle class that extends Vehicle, but we would like to make use of the association that already exists with a stricter multiplicity (say, a Bicycle can have up to 2 Wheels).

 

Without specialiations, we need to create a new association between Bicycle and Wheel and thus generate some unneeded code and duplicate data fields (both Vehicle and Bicycle would have a list of Wheels, which behave more or less the same). With specializations, simply stating that we want a new association between Bicycle and Wheel (as long as the names match up to the Vehicle to Wheel association) is enough to generate more appropriate code.

 

Example

// Here we define our base classes
class Vehicle {}
class Wheel {}

// Here we define our subclasses
class Bicycle { isA Vehicle; }
class Unicycle { isA Vehicle; }

// This is the "parent association" so to speak.
// It defines the Vehicle to Wheel relationship with
// as much abstraction as possible.
association { 0..1 Vehicle vehicle -- 0..* Wheel wheel; }

// Here, we'd like to extend the functionality of the 
// previous association to work with subclasses of Vehicle,
// while utilizing as much of the existing code as possible.
// Specializations allow us to do this, since:
// -> Bicycle and Unicycle extend Vehicle;
// -> Wheel is part of the Wheel hierarchy;
// -> The bounds on the left are not less specific than
//    the left bound of the parent association;
// -> The bounds on the right are not less specific than
//    the right bound of the parent association;
// -> Finally, the role names are the same.
association { 0..1 Bicycle vehicle -- 0..2 Wheel wheel; }
association { 0..1 Unicycle vehicle -- 0..1 Wheel wheel; }


      

Load the above code into UmpleOnline

 

Association Class Definition

An association class defines an object-oriented pattern to manage * -- * (many to many) associations when data needs to be stored about each link of that association.

An association class is a class and can have most of the items found in an ordinary class. However it always has two or more 1..many associations to other classes. These are syntactically shown as just a multiplicity (usually *, but 1..* and similar cases are allowed) followed by the name of the participating class (and an optional role name).

Example

// A person can attend many seminars,
// and a seminar can be attended by many people
// The relationship between Person and Seminar is thus
// many-to-many.
//
// There is, however, data to record about each ticket.
// This can be  recorded as an association class
//
// Note the following doesn't currently render
// in UmpleOnline using Correct UML association class
// notation. There are plans to fix this.
associationClass Ticket
{
  Integer ticketNumber;
  Double price = 0.0;
  
  * Person attendee;
  * Seminar;
}

class Person
{
  name;
}

class Seminar
{
  Date when;
  address;
}
      

Load the above code into UmpleOnline

 

Another Example

// The following shows the same example as using a regular class
// Instead of an association class
class Ticket
{
  Integer ticketNumber;
  Double price = 0.0;
  
  1 -- * Person attendee;
  1 -- * Seminar;
}

class Person
{
  name;
}

class Seminar
{
  Date when;
  address;
}
      

Load the above code into UmpleOnline

 

Another Example

// The following shows a 'quaternary' association, where the association
// class represents data in an association that links four classes.
class SportsPlayer {
  name;
}

class Season {
  year;
}

// e.g. goalie, forward etc.
class PlayingPosition {
  description;
}

class Team {
  name;
}

// This gathers the number of points a player gained on a particular team
// in a particular position while playing in a particular position
// To get the total points in any one category, you would have to add the points several instances
associationClass PlayerInPosition {
  Integer points;
  * SportsPlayer player;
  * Season;
  * Team;
  * PlayingPosition position;
}
      

Load the above code into UmpleOnline

 

Syntax


// Associations that would be many-many can also become full-fledged classes too
// See user manual page AssociationClassDefinition
associationClassDefinition : associationClass [name] { [[associationClassContent]]* }

associationClassContent- : [[comment]]
    | [[classDefinition]]
    | [[position]]
    | [[displayColor]]
    | [[invariant]]
    | [[softwarePattern]]
    | [[depend]]
    | [[singleAssociationEnd]]
    | [[stateMachine]]
    | [[attribute]]
    | [[association]]
    | [[inlineAssociation]]
    | ;
    | [[extraCode]]

singleAssociationEnd : [[multiplicity]] [type] [~roleName]? ;

Sorted Associations

It is possible to arrange for associations to maintain themselves in sorted order according to the value of an attribute. Create a derived attribute in order to define a complex sort order or to sort on the value of an attribute of an associated class (the example below does this in one case).

To declare an association as sorted do the following: after specifying the multiplicity, and any role name, give the keyword 'sorted' followed by the name of an attribute (sort key) in curly brackets. Whenever an add method is called to add an item to the association, Umple ensures the association is maintained in sorted order. .

Note that Umple associations are always 'ordered' by default; i.e. the user controls the position of items. Declaring an association as sorted makes this automatic. The presence of 'sorted' adds a 'sort' function to the API to allow for resorting (if the attributes on which sorting is based are changed, for example) and removes the API for manually ordering the association using addXAt().

At the time of writing, there remain several issues: For now, you should avoid having two sorted associations in the same class.

Errors are generated if the attribute specified as the sort key attribute does not exist in the class, or the sort key attribute is not of a recognized type.

Example

// This example demonstrates two cases of sorted associations
// The main program adds items out of order
// But when they are printed the output will be sorted
class Academy {
  1 -- * Course;
  1 -- * Student registrants sorted {id};
}

class Student {
  Integer id;
  name;
}

class Course {
  code;
}

class Registration {
  * -- 1 Student;

  // In each course, sort registrations by name
  * sorted {name} -- 1 Course;

  // Derived delegated attribute used for sorting printing
  name = {getStudent().getName()}

  // Derived delegated attribute used for sorting printing
  code = {getCourse().getCode()}

  
  public String toString() {
    return "Registration: " + getName() + ":" + getCode();
  }
}

// Mixin with main program and toString method
class Academy {
  public static void main(String [ ] args) {
    Academy ac = new Academy();
    Student j = ac.addRegistrant(12,"Jim");
    Student a = ac.addRegistrant(4,"Ali");
    Student m = ac.addRegistrant(8,"Mary");
    Student f = ac.addRegistrant(3,"Francois");
    Course c = ac.addCourse("CS191");
    Course c2 = ac.addCourse("AN234");    
    j.addRegistration(c);
    a.addRegistration(c);
    m.addRegistration(c);
    f.addRegistration(c);
    m.addRegistration(c2);
    f.addRegistration(c2);
    System.out.println(ac);
  }
  public String toString() {
    String result="Students:\n";
    for (Student s: getRegistrants()) {
      result +=s + "\n";
    }
    result +="Courses:\n";
    for (Course c: getCourses()) {
      result +=c + "\n";
    }

    return result;
  }
}

class Student {
  public String toString() {
    String result="Student=" + id + "[" + name + "\n";
    for (Registration r: getRegistrations()) {
      result +="  In: " + r + "\n";
    }
    return result;
  }
}

class Course {
  public String toString() {
    String result ="Course=" + code + "\n";
    for (Registration r: getRegistrations()) {
      result +="  Has: " + r + "\n";
    }    
    return result;
  }
}
      

Load the above code into UmpleOnline

 

Syntax


inlineAssociationEnd : [[multiplicity]] [~roleName]? [[isSorted]]?

isSorted- : sorted { [priority] }

Basic State Machines

A state machine has a fixed set of of values (called states) The state machine transitions from state to state by the occurrence of events. State machines are very useful for quickly defining a program's behaviour.

In Umple, a state machine is modeled as a special type of attribute. In any class, simply specify the state machine name, and follow the name by a block starting with '{' and ending with '}'. This indicates to Umple that you are defining a state machine, and not an ordinary attribute.

Within the block, you list the names of the various states. Each state is followed by a block, again indicated using '{' to start and '} to end. This block defines the details of a state.

Details of each state can include:

Note that, in addition, you can specify code to be executed whenever an event is processed by using before or after directives.

The following diagram shows a garage door state machine as a UML diagram. The Umple code for this is at the bottom of this page. Note that UmpleOnline currently cannot draw state machines. state machne for garage door  

Example


// This example shows a simple state machine without any actions or guards
//
// In the following, status is a state machine, and acts like an
// attributes, whose value is set by various events.
//
// Open, Closing, Closed, Opening and HalfOpen are the possible
// values, or states, of status.
//
// buttonOrObstacle, reachBottom and reachTop are events. These
// become generated methods that can be called to cause a state
// change.
//
// To make the state diagram appear in UmpleOnline, select 'Options'
// then choose 'GraphViz State Diagram'
class GarageDoor
{
   status {
      Open { buttonOrObstacle -> Closing;  }
      Closing {
          buttonOrObstacle -> Opening;
          reachBottom -> Closed;
      }
      Closed { buttonOrObstacle -> Opening; }
      Opening {
          buttonOrObstacle -> HalfOpen;
          reachTop -> Open;
      }
      HalfOpen { buttonOrObstacle -> Opening; }
  }
}


      

Load the above code into UmpleOnline

 

Another Example

// This is a more fully-featured state machine for
// a garage door corresponding to the diagram above
class Garage {
  lazy Boolean entranceClear=true;
  GarageDoor { 
    Closed {
      entry/{stopMotor();}  
      entry/{triggerEnergySaveMode();}
      exit/ {triggerNormalEnergyMode();}
      pressButton -> /{turnLightOn();} Opening; 
    }
    Opening {
      entry/{runMotorForward();}
      openingCompleted -> Open;
    }
    Open {
      entry/{stopMotor();}
      // do {wait(60000); turnLightOff();}
      pressButton [getEntranceClear()] -> Closing;
    }
    Closing {
      entry/{runMotorInReverse();}
      closingCompleted -> Closed;
      pressButton -> /{flashLightOn();} Opening; 
    }
  }
  
  boolean runMotorInReverse() {
     System.out.println("Running motor in reverse");
    return true;
  }
  
  boolean flashLightOn() {
     System.out.println("Flashing light on");
    return true;
  }

  boolean turnLightOn() {
     System.out.println("Turning light on");
    return true;
  }
  
   boolean turnLightOff() {
     System.out.println("Turning light off");
    return true;
  }
  
  boolean runMotorForward() {
     System.out.println("Running motor forwards");
    return true;
  }

  boolean triggerEnergySaveMode() {
     System.out.println("Triggering Energy Saving Mode");
    return true;
  }

  boolean stopMotor() {
     System.out.println("Stopping motor");
    return true;
  }

  boolean triggerNormalEnergyMode() {
     System.out.println("Triggering Normal Energy Mode");
         return true;
  }
  
  boolean waitawhile() {
    System.out.println("Waiting");
    return true;
  }
  
  boolean test() {
          System.out.println("Testing");
         return true;
  }
  
}

      

Load the above code into UmpleOnline

 

Syntax


stateMachine : [[enum]]
    | [[inlineStateMachine]]
    | [[referencedStateMachine]]
    | [[activeDefinition]]

//Issue 148
inlineStateMachine : [=queued]? [=pooled]? [~name] { ( [[comment]]
    | [[state]]
    | [[trace]]
    | [=||]
    | [[standAloneTransition]])* }

// An enum is a state machine that has no events
// stateName is prefixed with ~ to match alphanumeric names only.
// This is needed to solve issue 399, which is cause when a terminating } is parsed as part of the statename.
enum : [~name:key] { [~stateName]? (, [~stateName])* }

state : [=final]? [stateName] { [[stateInternal]]* }

stateEntity- : [=||]
    | [[entryOrExitAction]]
    | [[autoTransition]]
    | [[transition]]
    | [[activity]]
    | [[state]]
    | [[trace]]
    | ;

autoTransition : [[activity]]? [[autoTransitionBlock]]

// Autotransitions have no event. The transition is immediately taken
// or taken after the do activity ends[[guard]]? -> [[action]]?
// The action can come before or after the arrow
autoTransitionBlock- : [[guard]]? ( [[action]] -> | -> [[action]] | -> ) [stateName] ;

// A transition guard can come before or after the arrow
// The order of guard and event definition can also be interchanged
transition : ( [[eventDefinition]] [[guard]]
    | [[guard]] [[eventDefinition]]
    | [=unspecified]? [[guard]]
    | [[eventDefinition]])? ( [[action]] ->
    | -> [[action]]
    | -> ) [stateName] ;

eventDefinition- : [[afterEveryEvent]] | [[afterEvent]] | [~event] ( [[parameterList]] )?

// The timer in a timed event can be an number, variable, function() or function(num)
afterEveryEvent- : afterEvery ( [!timer:[+*/a-zA-Z0-9_\.-]+(\([0-9\.]*\))?] )

afterEvent- : after ( [!timer:[+*/a-zA-Z0-9_\.-]+(\([0-9\.]*\))?] )

// An action can be executed on a transition, or on entry or exit
action : / [[moreCode]]+

entryOrExitAction : [=type:entry|exit] / [[moreCode]]+

// A do activity is long-lasting and can be interrupted
activity : do [[moreCode]]+

guard : [ [[constraint]] ]

State Machine Actions and Do Activities

When an transition is taken, an action can occur. This is indicated using a slash "/" followed by arbitrary code in braces.

Similarly, when entering or exiting a state, an action can occur. This is indicated using the keywords entry or exit, followed by a slash, followed by code.

The actions described above should take negligible time to execute.

If a longer-running computation or activity should run while in a state, encode this using the keyword do, followed by code. In languages such as Java that support it, a thread will be started to invoke the thread. This allows the state machine to 'stay live' and be able to respond to other events, even while the do activity is running. Note that at the current time, the do activity thread must terminate itself; as an enhancement, the do activity thread should be interrupted and cancelled when a transition is taken out of the state.

Example


namespace example;

class LightFixture
{
  bulb
  {
    On {
      entry / { doEntry(); }
      exit / { doExit(); }
      push -> /{ doTransition(); } Off;
      do { doThisContinuouslyWhileOn(); }
    }
    Off {}
  }

  void doEntry() {System.out.println("Entry");}
  void doExit() {System.out.println("Exit");}
  void doTransition() {System.out.println("Transition");}
  void doThisContinuouslyWhileOn() {
    while (true) {
      System.out.println("Still on");
      try {
        Thread.sleep(1000);
      }
      catch (InterruptedException e) {}
    }
  }
}


      

Load the above code into UmpleOnline

 

Another Example

// This demonstrates that actions can be different in different target languages
class DemoSM
{
  Integer id;
  sm {
    s1 {
      e1 / Java {id=5;} Php {$id=5;} -> s2;
    }
    s2 {
    }
  }
}


      

Load the above code into UmpleOnline

 

Syntax


// An action can be executed on a transition, or on entry or exit
action : / [[moreCode]]+

entryOrExitAction : [=type:entry|exit] / [[moreCode]]+

// A do activity is long-lasting and can be interrupted
activity : do [[moreCode]]+

Nested State Machines

State machined can be nested inside another. This often allows for simpler Umple (or UML) notation, since events that need to cause effects in every substate of the outer state do not have to be repeated in each of the substates.

The first example below illustrates nesting abstractly. The next example shows nesting in a concrete example. The third example is the same as the second, but with no nesting, to illustrate the difference.

Example


// Illustration of nested states. Event e1 will take the system into
// state s2, and its first substrate s2a. Event e2 directly goes to s2b.
// Event e3 toggles between s2b and s2a. Event e1 when in s2, goes to s1

class A {
  sm {
     s1 {
        e1 -> s2;
        e2 -> s2b;
     }
     s2 {
        e1 -> s1;
        s2a {
          e3 -> s2b;
        }
        s2b {
          e3 -> s2a;
        }
     }
  }
}


      

Load the above code into UmpleOnline

 

Another Example

// Example showing nested states.

class Course {
  code;
  description;
  1 -- * CourseSection;
}

class CourseSection
{
  // Example from Lethbridge and Laganiere: Object Oriented Software
  // Engineering: Practical Software Development using UML and Java
  // McGraw Hill, 2005  www.lloseng.com

  sectionId;
  Integer classSize = 0;
  Integer minimumClassSize = 10;
  Integer maximumClassSize = 100;
  
  // State machine controlling status
  status
  {
    Planned {
      openRegistration -> NotEnoughStudents;
    }
    Open {
      cancel -> Cancelled;
      NotEnoughStudents {
        closeRegistration -> Cancelled;
        register [getClassSize() > getMinimumClassSize()] -> EnoughStudents;
      }
      EnoughStudents {
        closeRegistration -> Closed;
        register [getClassSize() > getMaximumClassSize()] -> Closed;
      }
    }
    Cancelled {}
    Closed {}
  }

  boolean requestToRegister(Student aStudent)
  {
    register();
    return setClassSize(getClassSize()+1);
  }
}

class Student {
  //Remainder of this class defined elsewhere
}
      

Load the above code into UmpleOnline

 

Another Example

// Example with an opportunity to nest states, to avoid repeating
// transitions

class Course {
  code;
  description;
  1 -- * CourseSection;
}

class CourseSection
{
  // Example from Lethbridge and Laganiere: Object Oriented Software
  // Engineering: Practical Software Development using UML and Java
  // McGraw Hill, 2005  www.lloseng.com

  sectionId;
  Integer classSize = 0;
  Integer minimumClassSize = 10;
  Integer maximumClassSize = 100;
  
  // State machine controlling status
  status
  {
    Planned {
      openRegistration -> OpenNotEnoughStudents;
    }
    OpenNotEnoughStudents {
      closeRegistration -> Cancelled;
      cancel -> Cancelled;
      register [getClassSize() > getMinimumClassSize()] -> OpenEnoughStudents;
    }
    OpenEnoughStudents {
      closeRegistration -> Closed;
      cancel -> Cancelled;
      register [getClassSize() > getMaximumClassSize()] -> Closed;
    }
    Cancelled {}
    Closed {}
  }

  boolean requestToRegister(Student aStudent)
  {
    register();
    return setClassSize(getClassSize()+1);
  }
}

class Student {
  // Remainder of class defined elsewhere
}
      

Load the above code into UmpleOnline

 

Auto-Transitions

It is possible to arrange for a state machine to transition automatically from one state to the next immediately after completing entry actions or upon completion of a do activity. This is specified using a transition without any preceding event. Such transitions may have guards and transition actions.

Example


// In this example, the system will transition to s2 automatically
// when the do activity ends
class X {
  sm {
    s1 {
      entry / {
        System.out.println("Starting first sleep");
      }
      do {
        Thread.sleep(2000);
        System.out.println("Ending first sleep");
      }
      -> s2;
    }
    s2 {
      entry / {
        System.out.println("Starting second sleep");
      }
      do {
        Thread.sleep(2000);
        System.out.println("Ending second sleep");
      }
    }
  }
  public static void main(String [ ] args) {
    X x = new X();
  }
}


      

Load the above code into UmpleOnline

 

Syntax


autoTransition : [[activity]]? [[autoTransitionBlock]]

// Autotransitions have no event. The transition is immediately taken
// or taken after the do activity ends[[guard]]? -> [[action]]?
// The action can come before or after the arrow
autoTransitionBlock- : [[guard]]? ( [[action]] -> | -> [[action]] | -> ) [stateName] ;

Timed Transitions

A transition can be triggered after a specified delay (a floating point value, given in seconds). The transition will be taken after the delay provided the object is still in the state and any guard is true. This is accomplished using the 'after' keyword.

The 'afterEvery' keyword, tries to trigger a transition repeatedly at a specified interval while the object remains in the state.

Example


// In this example, the system will transition to state b
// after a 1-second delay
class X {
  sm {
    a {
      entry / {System.out.println("entering a");}
      after(1) -> b;
    }
    b {
      entry / {System.out.println("entering b");}
    }
  }
  public static void main(String [ ] args) {
    X x = new X();
  }
}


      

Load the above code into UmpleOnline

 

Another Example

// In this example, the system will transition to state b
// when the value of the attribute count drops below 5
// An attempt to make this transition is taken every second
// The do activity slowly drops the value of count
class X 
{
  Integer count = 10;
  sm 
  {
    a 
    {
      entry / { System.out.println("entering a"); }
      do 
      {
        while (count > 0) 
        {
          System.out.println("Count = " + count);
          Thread.sleep(1000);
          count --;
        }
      }
      afterEvery(1) [count<5] -> b;
    }
    b 
    {
      entry / { System.out.println("entering b"); }
    }
  }

  public static void main(String [] args) 
  {
    X x = new X();
  }
}


      

Load the above code into UmpleOnline

 

Syntax


// The timer in a timed event can be an number, variable, function() or function(num)
afterEveryEvent- : afterEvery ( [!timer:[+*/a-zA-Z0-9_\.-]+(\([0-9\.]*\))?] )

afterEvent- : after ( [!timer:[+*/a-zA-Z0-9_\.-]+(\([0-9\.]*\))?] )

Events With Parameters

An event can have a parameter (of any valid type that the generated language can accept). The generated event method will have this parameter. The value of the parameter can be used in guards or transition actions.

It is absolutely necessary that all events with the same name have the same parameter type, or else an error will be raised.

Example


// The do activity of the first state machine is a thread that
// communicates with the second state machine.
// It calls the event method e with different arguments.
// The second state machine only changes state when the
// guard detects that the argument is valid
// The argument is also used in the transition action code.
class X {
  stateMachine1 {
    s1a {
      do {
        // This do activity sends events to stateMachine1
        e(5);
        Thread.sleep(1000);
        e(6);
        Thread.sleep(1000);
        e(7);
        Thread.sleep(1000);
        e(8);
      }
      -> s1b;
    }
    s1b {}
  } 
  stateMachine2 {
    s2a {
      entry / {System.out.println("s2a");}
      e(int a) [a > 6] / {System.out.println("e"+a);} -> s2b;
    }
    s2b {
      entry / {System.out.println("s2b");}
      e(int a) / {System.out.println("e"+a);} -> s2a;
    }
  }
  public static void main(String [ ] args) {
    X x = new X();
  }
}


      

Load the above code into UmpleOnline

 

Syntax


Queued State Machines

Standard state machines operate in a single thread. When an event method is called, the state machine code that runs continues the same thread of the caller. This can be satisfactory for simple applications, but it doesn't work in multi-threaded environments, and can also result in deadlocks.

To overcome the above problems, a state machine may be declared as 'queued' by just placing the keyword queued before the declaration of the state machine. In a queued state machine, the calls to the event methods simply add a record to the queue, and then return. The calling thread can then continue and do other activities. A separate thread exists in each state machine to take events off the queue and process them, in the order they are received.

A queued state machine will process events in the same order as a regular state machine. See also pooled state machines for a variation on this semantics.

Example


// Test of queued state machines.
// The word queued results in a thread being created to process events.

class TestSM {
  queued sm{
    s1 {
      e1 /{System.out.println("e1");} ->s2;
    }
    s2 {
      e2 /{System.out.println("e2");} ->s3;
    }
    s3 {
      e3 /{System.out.println("e3");} ->s4;
    }
    s4 {
      e4 /{System.out.println("e4");} ->s1;
    }
  }
  
  public static  void main(String [] ags){
    TestSM test=new TestSM();
    test.e1(); // processed s2
    test.e2(); // processed s3
    test.e3(); // processed s4
    test.e4(); // processed s1

    test.e1(); // processed s2
    test.e3(); // queued: ignored  pooled: left in queue, until we are next in s3
    test.e4(); //      pooled: left in queue, until next in s4
    test.e2(); //      pooled: processed goes to s3
               //      pooled: process e3 from queue goes to s4
               //      pooled: process s4 from queue goes to s1
    test.e1(); 
    test.e3(); 
    test.e2(); 
    test.e4();
    
    test.e1();
    test.e2();
    test.e3();
    test.e4();

    test.e1();
    test.e2();
    test.e4();
    test.e3();
    test.e4();

    test.e1();
    test.e3();
    test.e2();
    test.e3();
    test.e1();
    test.e4();

    test.e2();
    test.e1();
    test.e2();

  }
}


      

Load the above code into UmpleOnline

 

Syntax


//Issue 148
inlineStateMachine : [=queued]? [=pooled]? [~name] { ( [[comment]]
    | [[state]]
    | [[trace]]
    | [=||]
    | [[standAloneTransition]])* }

Pooled State Machines

Queued and regular state machines always process events in the order they arrive, and ignore events that cannot be handled in the current state. Sometimes, however, you want to 'save' events that arrive out of sequence, and process them as soon you enter a state that can handle them. This is accomplished by adding the word 'pooled' before a state machine definition.

In a pooled state machine there is a queue in a separate thread, just like in a queued state machine, however, if the next event to be processed has no handler in the current state, then it remains at the front of the queue, and the queue processor looks further back in the queue for the first event that can be handled.

A queued state machine will therefore often process events in a different order from a regular state machine.

Example


// Test of pooled state machines.
// The word pooled results in a thread being created to process events, and
// 'pooled' semantics being employed. Events which cannot be handled are kept waiting
// until entry into a state where they can be handled.

class TestSM {
   String ev="";
   pooled sm{
    s1 {
      e1 /{ev="e1";} ->s2;
      e5 /{ev="e5";} ->s2;
    }
    s2 {
      e2 /{ev="e2";} ->s3;
    }
    s3 {
      e3 /{ev="e3";} ->s4;
    }
    s4 {
      e4 /{ev="e4";} ->s1;
    }
  }
  after e* {
    if(wasEventProcessed)
      System.out.println(ev);
  }
  
  public static  void main(String [] ags){
    TestSM test=new TestSM();
    test.e1(); // processed s2
    test.e5(); // Will only be processed in the pooled case (eventually)
    test.e2(); // processed s3
    test.e3(); // processed s4
    test.e4(); // processed s1

    test.e1(); // processed s2
    test.e3(); // queued: ignored  pooled: left in queue, until we are next in s3
    test.e4(); //      pooled: left in queue, until next in s4
    test.e2(); //      pooled: processed goes to s3
               //      pooled: process e3 from queue goes to s4
               //      pooled: process s4 from queue goes to s1
    test.e1(); 
    test.e3(); 
    test.e2(); 
    test.e4();
    
    test.e1();
    test.e2();
    test.e3();
    test.e4();

    test.e1();
    test.e2();
    test.e4();
    test.e3();
    test.e4();

    test.e1();
    test.e3();
    test.e2();
    test.e3();
    test.e1();
    test.e4();

    test.e2();
    test.e1();
    test.e2();

  }
}


      

Load the above code into UmpleOnline

 

Syntax


//Issue 148
inlineStateMachine : [=queued]? [=pooled]? [~name] { ( [[comment]]
    | [[state]]
    | [[trace]]
    | [=||]
    | [[standAloneTransition]])* }

Method Definition

The Umple language allows a developer to extend the functionality of a class with arbitrary methods written the natively compiled language (e.g. Java, Php or Ruby).

Within these arbitrary methods, a developer may call generated methods that access the Umple attributes, associations and state machines. To determine what API methods are available to be called by methods, refer to the API reference or generate Javadoc from an Umple file using UmpleOnline.

A standard Umple method will specify the return type, then the name, then the argument list and finally the method body in curly brackets. The generated output for the method will use correct format for the generated language and will be public.

Example

generate Java;

// A class with a method displayName() that has no arguments
class Person
{
  name;
  
  String displayName()
  {
    return("Hello, my name is " + getName());
  }
}

      

Load the above code into UmpleOnline

 

Another Example

generate Java;

// A class with a method that has arguments
class Person
{
  name;
  
  String displayName(String greeting, String property)
  {
    return(
      greeting +
      ", my " +
      property +
      " is " +
      getName());
  }
}


      

Load the above code into UmpleOnline

 

Another Example

generate Java;

// A class with a method that uses 'public'.
class Person
{
  name;
  
  public String displayName()
  {
    return("Hello, my name is " + getName());
  }
}

      

Load the above code into UmpleOnline

 

Syntax


// Methods: The code in concrete methods is passed to the base language
// See user manual page MethodDefinition
concreteMethodDeclaration : [=modifier:public|protected|private]? [=static]? [type]? [[methodDeclarator]] [[methodThrowsExceptions]]? [[methodBody]]
    | [=modifier:public|protected]? [=abstract] [type]? [[methodDeclarator]] [[methodThrowsExceptions]]? ;

methodDeclarator : [methodName] [[parameterList]]

parameterList : ( ([[parameter]] ( , [[parameter]] )* )? )

parameter : [[typedName]]

Alternative Languages

In Umple, the body of a method will by default be emitted unchanged. This ties the model to the particular programming language. However it is possible to provide alternative implementations for different programming languages by preceding the method body with the language name.

This multi-lingual capability also works for other places where native code is injected such as in state machine guards and actions, or in derived attributes.

Example

// Generating Java and Php the following will result in the appropriate 
// method body being selected.
class LanguageSpecific {
  int m1() Java {
    // Return 1 if the model is compiled into Java
    return 1;
  }
  Php {
     // Return 0 if the model is compiled into Php
    return 0;
  }
}

      

Load the above code into UmpleOnline

 

Another Example

// A method body may work for several languages.
// If no language is specified it is taken as the default.
class LanguageSpecific {
  int m1()
  Java,Php {
    // Return 0 if the model is compiled into Java or Php
    return 0;
  }
  {
    // Default implementation for other languages
    return 1;
  }
}

      

Load the above code into UmpleOnline

 

Basic Templates

Generating string output is a very common task for programs. Common types of output include html, xml and executable code. Umple has a special capability for this, as do many other technogies (it is central to PhP, for example). The advantage of Umple's approach is that it adds generation templates in a uniform manner to C++, Java, PhP and other languages that Umple supports. The same templates can be reused.

The Umple generation templates are essentially a readable way to generate special methods that emit Strings (and also in Java's case StringBuilders).

Two basic elements are needed to use generation templates:


 

Templates The first essential element is the templates themselves. These are shown as a name followed by arbitrary text in <<! !>> brackets. The text in the brackets can contain anything you want. See the examples below to understand how these are used.

<<!output this!>>

will build the string 'output this' when specified in an emit method (below).


 

Emit method specifications: The second essential element is one or more 'emit' statements. These specify the methods to be generated. As with any method there can be a set of arbitrary parameters. Following this, in a second set of parameters is comma-separated list of templates to emit. For example, the following says to generate a method with signature String printRow(intTimes, intCount); that will emit a string containing the contents of the row and cr templates:

emit printRow(int times, int count)(row, cr);  


 

Optional elements in templates are:

Expression blocks: Inside the template, programmers can specify arbitrary expressions in <<= >> brackets. These can refer to attributes of the class, parameters to the emit method, states and so on. The result of the expression will be substituted every time the template method is called. This appears in all examples below.

Code blocks: Also inside the template program logic can be embedded in <<# #>> brackets. This enables conditional emission of parts of a template, or looping within the template. This appears in the second example below.

Comment blocks: Comments in templates can be shown within <</* */>>


 

The first two examples below show how simple templates can be used to output strings, in this case a one-column multiplication table. The first example uses two template methods, the second being called in a loop. The second example generates the same output, but all the looping logic is enclosed in the template itself. The third example shows a more substantial template with a lot of 'boilerplate' text that is easy to read and edit in the Umple source. Manually writing the generated would be substantially more awkward.

Umple's mixin capability allows templates to be kept in separate files. This can faciliatate reuse.

Example

// Simple example to demonstrate umple's template base string generation
// mechanism.
// In this approach there is an iterative call to the emit function

class MathExample {

  // A simple template to inject a platform-specific newline
  cr <<!
!>>

  // Two templates for different lines of output
  header <<!Print out a <<=times>> times table!>>
  row <<!  <<=times>> times <<=count>> is <<=times*count>>!>>

  // Specification for two methods to be generated to output  
  // parts of the text
  // Method arguments are in the first parentheses
  // Templates to output are in the second set
  emit printHeader(int times)(header, cr);
  emit printRow(int times, int count)(row, cr);

  // Main program to run the above and generate the output
  public static void main(String[] argv) {
    int times = 10; // default
    MathExample m = new MathExample();

    if(argv.length > 0) {
      times=Integer.parseInt(argv[0]);
    }

    // Print the header
    System.out.print(m.printHeader(times)); 
    // Print one row for each element
    for (int i=0; i <= times; i++) {
      System.out.print(m.printRow(times,i));
    }
  }
}


      

Load the above code into UmpleOnline

 

Another Example

// Simple example to demonstrate umple's template base string generation
// mechanism.
// In this approach iteration is embedded in the rows template
// and there is a single emitter function generated called result

class MathExample {

  // A simple template to inject a platform-specific newline
  cr <<!
!>>

  // A template for the header lines
  header <<!Print out a <<=times>> times table!>>

  // A template that generates all the rows by iterating
  rows <<!<<# for  (int i=0; i <= times; i++) {#>>

<<=times>> times <<=i>> is <<=times*i>><<#}#>>!>>

  // Specification of a single method to emit the result
  emit result(int times)(header, rows, cr);
  
  public static void main(String[] argv) {
    int times = 10; // default
    if(argv.length > 0) {
      times=Integer.parseInt(argv[0]);
    }
    // Output the entire result
    System.out.print(new MathExample().result(times)); 
  }
}


      

Load the above code into UmpleOnline

 

Another Example

// Example of creating a lengthy output in Umple from a template
// Note this is plain text. See the next page for html generation.
// The company is, of course, fictitious.
class RefLetterRequest {
  // Attributes used to construct the instance
  String fileno; String recipient; String applicant;
  String sender; String senderTitle;
  
  // Letter template
  letterTemplate <<!
Subject: Reference request for <<=applicant>>, File #<<=fileno>>

Dear <<=recipient>>,
Our company, Umple Enterprises, is hiring talented software
engineers.

We have received an application from <<=applicant>> who named you
as an individual who could provide a letter of reference. Would you
please reply to this letter, answering the following questions:
  * In what capacity do you know <<=applicant>>
  * For how long have you known <<=applicant>>
  * Describe the abilities of <<=applicant>> in software development
  * What his or her strengths and weaknesses?
  * Please provide your phone number and suitable times to call in
    case we need to follow up 
    
Yours sincerely,
<<=sender>>
<<=senderTitle>>
!>>

  // Specification of the method to generate
  emit letterTemplate()(letterTemplate);

  // Main program to generate the letter
  public static void main(String[] argv) {
    if(argv.length < 5) {
      System.err.println("You must specify arguments for fileno, recipient, applicant, sender, sendertitle");
    }
    // Output the entire result
    else System.out.print(new RefLetterRequest(
      argv[0], argv[1],argv[2], argv[3], argv[4]
    ).letterTemplate()); 
  }
}


      

Load the above code into UmpleOnline

 

Syntax


templateAttributeDefinition : [[templateName]] [[templateAttribute]]

templateName : ( [~classname] . )? [name] [[templateParameters]]?

emitMethod : [=modifier:public
    |protected
    |private]? [=static]? [type]? [=emit] [[methodDeclarator]] [[templateList]]?;

templateList- : ( ( [[templateName]] ( , [[templateName]] )* )? )

templateAttribute# : <<! [[templateAttributeContent]]* !>>

templateAttributeContent- : [[templateExpression]]
    | [[templateComment]]
    | [[templateCodeBlock]]
    | [[templateExactSpaces]]
    | [[templateInclude]]
    | [[templateText]]

templateText# : [**templateTextContent:<<(=|#|/[*]|$|@)]

templateComment# : <</* [**templateCommentContent] */>>

templateExpression# : <<= ( [[templateExpression]]
    | [**templateExpressionContent:<<(=|#|/[*]|$|@)] )+ >>

templateCodeBlock# : <<# ( [[templateExpression]] | [**templateLanguageCode:<<(=|#|/[*]|$|@)] )* #>>

Html Generation

The first example below illustrates the generation template capability of Umple. It is an html generation library. The second example is a program that uses the second example.

Example

// Umple library for generating html
// Currently it supports h1, h2 ... as well as p, and table tags.
// This will be extended to support more of html later
// It serves as an illustration of Umple's generation templates

// Class representing either a top level html node or a collection of subnodes
class HtmlNode {
  String getContent() {return "";};  // should be abstract
}

// Simple text to be output between tags - these are leaves
class HtmlTextNode {
  isA HtmlNode;
  String content;
}

// Non-leaf nodes in the html tree
class HtmlRegularNode {
  isA HtmlNode;
  const String Xmltagstart = "<";
  const String Xmltagend = ">";

  // Arguments for the constructor
  String tag; // e.g. p, h1, a
  String arguments; // e.g. href
  
  0..1 -> * HtmlNode subnodes; // whatever to emit between tags
  
  // The following template will render any html node
  rendering <<!<<=Xmltagstart>><<=getTag()>> <<=getArguments()>><<=Xmltagend>>
  <<#
  for(HtmlNode n : getSubnodes()) {#>><<=n.getContent()>>
  <<#}#>><<=Xmltagstart>>/<<=getTag()>><<=Xmltagend>>!>>
  
  emit getContent()(rendering);
  
  HtmlTable table() {
    HtmlTable t = new HtmlTable();
    addSubnode(t);
    return t;
  }
  
  HtmlTextNode text(String s) {
    HtmlTextNode t = new HtmlTextNode(s);
    addSubnode(t);
    return(t);
  }

  HtmlRegularNode taggedText(String tag, String arguments, String s) {
    HtmlRegularNode r = new HtmlRegularNode(tag, arguments);
    HtmlTextNode t = new HtmlTextNode(s);
    r.addSubnode(t);
    addSubnode(r);
    return(r);
  }
}

class HtmlTable {
  isA HtmlRegularNode;

  HtmlTable() {
    super("table","");
  }

  HtmlRow tr() {
    HtmlRow r = new HtmlRow();
    addSubnode(r);
    return r;
  }  
}

class HtmlRow {
  isA HtmlRegularNode;

  HtmlRow() {
    super("tr","");
  }

  // Add a cell that contains text
  HtmlCell td(String s) {
    HtmlCell c = td();
    c.text(s);
    return(c);
  }

  // Add a cell that can contain anything
  HtmlCell td() {
    HtmlCell c = new HtmlCell();
    addSubnode(c);
    return c;
  }
}

class HtmlCell {
  isA HtmlRegularNode;

  HtmlCell() {
    super("td","");
  }
}

class HtmlGen {

  lazy HtmlNode firstNode;

  // Subtrees for the header and body
  0..1 -> * HtmlNode headerNodes;
  0..1 -> * HtmlNode bodyNodes;
 
  after constructor {
    firstNode = new HtmlTextNode(filehead());
  }

  filehead <<!!>>
  emit filehead()(filehead);

  xmlns <<!xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"!>>
  emit xmlns()(xmlns);
  
  wholefile <<!<<=getFirstNode().getContent()>>

  
  <<#for(HtmlNode h: getHeaderNodes()) {#>>
    <<=h.getContent()>>
  <<#}#>>
  
  
  <<#for(HtmlNode h: getBodyNodes()) {#>>
    <<=h.getContent()>>
  <<#}#>>
  

!>>
    
  emit wholefile()(wholefile);

  // Creates a new simple node; but does not add it anywhere
  HtmlRegularNode simpleNode(String tag, String content) {
    HtmlTextNode t = new HtmlTextNode(content);
    HtmlRegularNode r = new HtmlRegularNode(tag,"");
    r.addSubnode(t);
    return r;
  }

  // Add a top level node of any type that contains a string
  HtmlNode addNode(HtmlNode n) {
    addBodyNode(n);
    return n;
  } 

  // Add a node of any type that contains a string
  HtmlRegularNode addSimpleNode(String tag, String text) {
    HtmlRegularNode t = simpleNode(tag,text);
    addBodyNode(t);
    return t;
  } 

  // Adds a top level header at a certain level with plain text
  // Subsequent calls can be made to add additional elements
  // to the result
  HtmlRegularNode h(int level, String text) {
    return addSimpleNode("h"+level,text);
  } 

  // Adds a top level p with plain text
  // Subsequent calls can add additional elements to the p
  // beyond just the text
  HtmlRegularNode p(String text) {
    return addSimpleNode("p",text);
  } 

    
  // Adds a top level table
  HtmlTable table() {
    HtmlTable t = new HtmlTable();
    addBodyNode(t);
    return t;
  }
}


      

Load the above code into UmpleOnline

 

Another Example

// Umple program demonstrating generation
// of the html generation library for Umple

use ../HtmlGeneration.ump;

class TimesTable {
  public static void main(String[] argv) {
    int times = 10; // default
    HtmlGen h = new HtmlGen();
    HtmlRegularNode p;

    if(argv.length > 0) {
      times=Integer.parseInt(argv[0]);
    }
    
    // Specify the table main header
    h.h(1, "Multiplication Table: "+times);

    // Generate an explanatory paragraph
    p = h.p("The following is a ");
    p.taggedText("i","","simple");
    p.text(" multiplication table");
    
    // Generate another paragraph with some subnodes
    // showing a slightly different use of the API
    p = new HtmlRegularNode("p","");    
    h.addNode(p);
    p.text("Nodes in ");
    p.taggedText("font", "color=\"red\"", "red");
    p.text(" are powers of 3");

    h.h(2, "The table");

    // Create a table at the top level
    HtmlTable t=h.table();

    // Add the top row of the table
    HtmlRow r;
    r=t.tr();
    r.td("*");
    for(int i=1; i<= times; i++) {
      r.td().taggedText("b","",""+i);;
    }

    // Add the interior rows of the table
    for(int i=1; i<= times; i++) {
      r=t.tr();
      r.td().taggedText("b","",""+i);
      for(int j=1; j<= times; j++) {
        String output=""+i*j;
        if((i*j)%3==0) {
          HtmlCell c = r.td();
          c.taggedText("font", "color=\"red\"",output);
        }
        else {
          r.td(output);
        }
      }
    }
    
    System.out.println(h.wholefile()); 
  }
}


      

Load the above code into UmpleOnline

 

Active Objects

An active object is an object that, when constructed, runs its own thread. This is indicated in Umple by the 'active' keyword followed by a block of code. A collection of active objects, working together, constitute a concurrent system.

Additional Umple features are under development to allow for sending signals to and from concurrent objects.

Example

class A {
  name;
 
  active {
    System.out.println("Object "+getName()+"is now active");
    for (int i = 1; i < 10; i++) {
      System.out.println(" "+name+" was here");
      Thread.sleep(1000);
    }
  }

  public static void main(String[] argv) {
    new A("1");
    new A("2");
  }
}


      

Load the above code into UmpleOnline

 

Syntax


activeDefinition : [=active] [[codeLangs]] [name]? [[moreCode]]+

Concurrency Using Do Activities

Multiple concurrent blocks that become active when in a particular state can accomplished in Umple using a state machine with two substates separated by the || symbol, each with a do activity. Both do activities will run concurrently.

Example

class X {
  activesm {
    topstate {
      thread1 {
        do {
          System.out.println("Doing the activity - Normally this would last a long time");
          Thread.sleep(1000);
          System.out.println("Done thread 1");
        }
      }
      ||
      thread2 {
        do {
          System.out.println("Doing the other activity - Again normally this would last a long time");
          Thread.sleep(3000);
          System.out.println("Done thread 2");
        }
      }
    }
  }
  public static void main(String[] argv) {
    new X();
  }
}


      

Load the above code into UmpleOnline

 

Another Example

// This is a more sophisticated example
class X {
 sm {
   s1 {
     do {
        System.out.println("In S1");
        Thread.sleep(1000);
        System.out.println("Still in S1 after sleep");
        Thread.sleep(2000);
        System.out.println("About to leave S1");
      }
      -> s2;
    }
    s2 {
     do {
        System.out.println("In S2");
        Thread.sleep(1000);
        System.out.println("Still in S2 after sleep");
        Thread.sleep(2000);
        System.out.println("About to leave S2");
      }
      nesteds2a {
        do {
          System.out.println("In S2a");
          Thread.sleep(1000);
          System.out.println("Still in S2a after sleep");
          Thread.sleep(2000);
          System.out.println("About to leave S2a");
        }
      }
      ||
      nesteds2b {
       do {
          System.out.println("In S2b");
          Thread.sleep(1000);
          System.out.println("Still in S2b after sleep");
          Thread.sleep(2000);
          System.out.println("About to leave S2b");
        }
      }
    }
  }
  public static void main(String[] argv) {
    System.out.println("In Main");
    X theX = new X();
    System.out.println("End of Main");
  }
}


      

Load the above code into UmpleOnline

 

Simple Constraints

Umple supports basoc OCL-type constraints that limit what umple-generated mutator methods (set, add, etc.) and constructors can do.

Constraints are specified within square brackets, in the same manner as guards on state machines.

Additional capabilities are being developed in Umple to allow other types of constraints.

Example

// The following demonstrates two simple constraints limiting the range of age
// The test code demonstrates that this works as expected.
class Client {
  const Integer minAge =18;
  Integer age;
  [age >= minAge]
  [age <= 120]
  
  public static void main(String [ ] args) {
    Client c = new Client(40);
    for (int i: new int[] {-1,10,17,18,19,50,119,120,122,1000}) {
       System.out.println("Trying to initialize age to "+i);
       System.out.println(c.setAge(i) ? "  Success" : "  FAILURE");
    }
  }
}


      

Load the above code into UmpleOnline

 

Another Example

// Example with a few more operators
class X {
  Integer i;
  Integer j;
  [i > j]
  [i < 5 && j > 0]
  [! (i == 10)]
}

      

Load the above code into UmpleOnline

 

Syntax


// A constraint is an expression optionally be surrounded in round brackets or negated
constraint- : [[constraintBody]] [[linkingOp]]? | [[constraintExpr]] [[linkingOp]]?

negativeConstraint : ( ! | not ) ( [[constraintName]] | [[constraint]] )

// A constraint body is a constraint expression (possibly with a linking operator such as && or ||).
constraintBody : ( [[constraint]] )

linkingOp- : ( [=andOp:and|&&|&]
    | [[equalityOperator]]
    | [!orOp:(or|\Q||\E)] ) [[linkingOpBody]]

constraintExpr- : [[statemachineExpr]]
    | [[stringExpr]]
    | [[boolExpr]]
    | [[numExpr]]
    | [[associationExpr]]
    | [[genExpr]]
    | [[loneBoolean]]
    | { [!fakeContraint:[^\n]+] }

//must be string
stringExpr : [[stringExprOperator]] | [[stringExprPlain]]

//basically the "other" catagory, contains everything that can be equal to something else
genExpr : [[constraintVariable]] [[equalityOperator]] [[constraintVariable]]

//for floats, doubles and ints
numExpr : [[numberExpression1]]
    | [[numberExpression2]]
    | [[numberExpression3]]
    | [[numberExpression4]]

ordinalOp- : [=greaterOp:greater|>=|=>|=>=]
    | [=lessOp:less|<=|=<|=<=]
    | [=moreOp:larger|>]
    | [=smallerOp:smaller|<]

Preconditions

You can specify basic preconditions in methods as shown below. This is still under development.

Example

class PotentialVoter {
  Integer age;
  
  int vote(int candidate) {
    [pre: age >= 18]
    [pre: candidate > 0]
    // rest of stuff that we do not interpret
     return 0;
  }
}


      

Load the above code into UmpleOnline

 

Syntax


methodBody- : ( [[codeLangs]] { ( [[precondition]] | [[postcondition]] )* [**code] } )+

// Constraints in Umple.
// This is currently under development. Constraint capability is being
// developed in agile increments. The first step, described below,
// allows limiting the values of attributes. Code generation is not currently enabled.
// Constraints may appear in classes (including association classes)
// as well as in states.
precondition : [ [name]? pre : [[constraint]] ]

Basic Composite Structure Diagrams

A composite structure diagram is used to show how various instances of classes, called parts, are connected at run time in order communicate with each other.

To specify composite structure, the following are the elements that need to be present in an Umple system:

The example below first defines two classes with ports; a third class contains instances of the first two.

Under development: Composite structure diagrams, ports and active methods are currently under development. Code generation only works in C++

See also the Wikipedia page on Composite Structure Diagrams.

Example

// Example system representing constraint-based ping-pong example
// Demonstrates the composite Structure Diagram in Umple

class Component1 {
  // Relay-Port
  public in Integer pIn1;
  public out Integer pOut1;
  pIn1 -> pOut1;


  [pIn1]
  active increment {
     pOut1(pIn1 + 1);
  }

  [pOut1]
  active logOutPort1 {
     cout << "CMP 1 : Out data = " << pOut1 << endl;
  }
  
}

class Component2 {
  public in Integer pIn2;
  public out Integer pOut2;
  pIn2 -> pOut2;

  [pIn2, pIn2 < 10]
  active stop {
       pOut2(pIn2 + 1);
  }

  [pOut2]
  active logOutPort2 {
     cout << "CMP 2 : Out data = " << pOut2 << endl;
  }
}


class Atomic {
Component1 cmp1;
Component2 cmp2;
Integer startValue;

  after constructor {
     cmp1->pIn1(startValue);
     
  }


  cmp1.pOut1 -> cmp2.pIn2;
  cmp2.pOut2 -> cmp1.pIn1;
}


      

Load the above code into UmpleOnline

 

Syntax


primitiveDefinition : primitive [name] { [[primitiveBody]]* }

portMultiplicity : [!portMultiplicity:\[[0-9]+\]]

typedPortName : [~type]? [~portName] [[portMultiplicity]]?

portDefinition : [=modifier:public
    |protected
    |private]? [=inverse:conjugated]? [=direction:in
    |out
    |port] [[typedPortName]] ;

// Port Connectors
portBindingDefinition : ( [~fromClassname] . )? [fromPort] -> ( [~toClassname] . )? [toPort] [[bindinHandler]]

bindinHandler : { [**code] } | ;

// Port Watchlist Definition
portWatch- : ( [[constraintList]] | [[comment]] )*

// Active Method Definition
activeMethodDefinition : [[portWatch]]? [=modifier:public
    |protected
    |private]? [type]? [=activeType:atomic
    |synchronous
    |intercept]? [=active] [[activeMethodDeclarator]] [[activeMethodBody]]+

activeMethodDeclarator : [~methodName] [[parameterList]]?

//activeMethodBody : [[activeDirectionHandler]] { ( [[activeTrigger]] )* [**code] }
activeMethodBody : [[activeDirectionHandler]]? { ( [[comment]] | [[activeTrigger]] | [**code] )* }

activeDirectionHandler : [=direction:forward|inverse] ( , [=direction:forward|inverse] )*

activeTrigger : [[hitchConstraint]]? [[constraintList]]? [=trigger:/] [[activeTriggerBody]] [[thenDefinition]]? [[resolveDefinition]]?

activeTriggerBody- : ( [[deferredList]] | [[activeTriggerDefinition]] )

deferredList : [ [[activeTriggerDefinition]] ( , [[activeTriggerDefinition]] )* ]

activeTriggerDefinition- : [[anonymousTriggerBody]] | [[invoke]]

thenDefinition : .then ( [[anonymousTriggerBody]]? )

resolveDefinition : .resolve ( [[anonymousTriggerBody]]? )

hitchConstraint : [=clause:after|poll] ( [timer] )

constraintList : [ [[basicConstraint]] ( , [[basicConstraint]] )* ]

basicConstraint- : [[timeConstraint]] | [[messageConstraint]] | [[constraint]]

timeConstraint : [=clause:latency|period|timeout] ( [timer] )

messageConstraint : [=clause:priority] ( [priorityValue] )

invoke : ( [~classname] . )? [name] ( ( [parameter] ( , [parameter] )* )? ) ;

anonymousTriggerBody : { [**code] }

Singleton Pattern

Use the Singleton keyword to mark a class as a singleon class. The code ensures that only one object of the class is instantiated at runtime.

For more details on the Singleton pattern, see this Wikipedia page.


Example


class Airline
{
  singleton;
}

      

Load the above code into UmpleOnline

 

Syntax


softwarePattern- : [[isA]] | [[singleton]] | [[immutable]] | [[keyDefinition]] | [[codeInjection]]

// A class that can have only one instance SingletonPattern
singleton- : [=singleton] ;

Immutable Pattern

Mark a class as immutable to force all its contents to be immutable. The code ensures all attributes and associations can only be set in the constructor, and cannot be modified again subsequently.

The only associations allowed to be immutable are directed associations to other immutable classes

A class can only be immutable if all its superclasses are also immutable. Declaring a superclass immutable forces its subclasses to be immutable; in other words, immutability is inherited. If the subclasses break immutability constraints (such as the type of attributes allowed), then errors will be raised.

Individual attributes and associations can be marked as immutable instead of the entire class. An attribute can be marked as lazy immutable if it needs to be initialized after the constructor has finished.

For more details on the Immutable pattern, see this Wikipedia page.


Example

// A simple example of an immutable class
class Point2D
{
  immutable;
  Float x;
  Float y;
}

      

Load the above code into UmpleOnline

 

Another Example

// An example of one immutable class making reference to another

class Path
{
  immutable;
  1 -> * Point2D pathElements;
}

class Point2D
{
  immutable;
  Float x;
  Float y;
}

      

Load the above code into UmpleOnline

 

Another Example

// Example of the declaration of an association to be immutable
// Note that this can be set only the first time
class X {
  Integer id;
  immutable * -> 0..1 Y;
}

class Y {
  immutable;
  someInfo;
}  

      

Load the above code into UmpleOnline

 

Syntax


association : [=modifier:immutable]? [[associationEnd]] [=arrow:--
    |->
    |<-
    |><
    |<@>-
    |-<@>] [[associationEnd]] ;

inlineAssociation : [=modifier:immutable]? [[inlineAssociationEnd]] [=arrow:--
    |->
    |<-
    |><
    |<@>-
    |-<@>] [[associationEnd]] ;

derivedAttribute- : [=modifier:immutable
    |settable
    |internal
    |defaulted
    |const
    |fixml]? [[typedName]] = ( [[moreCode]] )+

complexAttribute- : [=unique]? [=lazy]? [=modifier:immutable
    |settable
    |internal
    |defaulted
    |const
    |fixml]? [[typedName]] (= [**value])? ;

softwarePattern- : [[isA]] | [[singleton]] | [[immutable]] | [[keyDefinition]] | [[codeInjection]]

// A class that can't be modified when created ImmutablePattern
immutable- : [=immutable] ;

association : association [associationNum];

Delegation Pattern

Delegation is one of the most fundamental patterns, that underpins many more sophisticated patterns found in the Gang of Four book. To simplify code, reduce coupling, and adhere to the 'Law of Demeter', it encourages you to create one-line methods that do nothing other than call methods in neighbouring classes. Other code in your class then calls the delegation methods, rather than also calling the methods in the neighbouring classes. That way, very few methods (just the delegation methods) actually need to traverse associations

In Umple there is no special syntax for delegation, however the notation for derived attributes has the effect of creating delegation methods in the manner shown in the example below.

Delegation methods can also be used to help build occurrences of other patterns such as

Note that delegation methods as shown here are 'read only'. They generate a get method with the name of the derived attribute, not a set method.


Example


// This system has many delegation methods so that information in one class can
// be obtained in a neighbouring class easily. The delegation is created using
// derived attributes, which generate get methods for use by other code.
class Airline {
  code;
  name;
  1 -- * RegularFlight;
}

// A regular flight flies every day and has a flight number and other fixed data.
class RegularFlight {
  Integer number;
  Time depTime;
  * outgoing -- 1 Airport origin;
  * incoming-- 1 Airport destination;
  fullNumber = {getAirline().getCode()+getNumber()}
}

// A specific flight actually has passengers
class SpecificFlight {
  * -- 1 RegularFlight;
  Date depDate;
  
  // Four delegation attributes to save multiple methods in this
  // class from having to traverse the association
  flightNumber = {getRegularFlight().getFullNumber()}
  Airport origin = {getRegularFlight().getOrigin()}
  Airport destination = {getRegularFlight().getDestination()}
  Time plannedDepTime = {getRegularFlight().getDepTime()}
}

// A passenger on a flight
class Booking {
  lazy seat;
  * -- 1 SpecificFlight;
  * -- 1 Passenger;
  
  // Second-level delegation - data comes from RegularFlight
  flightNumber = {getSpecificFlight().getFlightNumber()}
  Airport destination = {getSpecificFlight().getDestination()}
  
  // Simple delegation
  passengerName = {getPassenger().getName()}
  Time plannedDepTime = {getSpecificFlight().getPlannedDepTime()}

  //Simple method using the data gathered by delegation
  public String toString() {
    return getFlightNumber()+" "+getPlannedDepTime()+" "+
      getDestination().getName()+" "+getPassengerName()+" "+getSeat();
  }
}

class Passenger {
  lazy Integer freqFlyerNumber;
  name;
} 

class Airport {
  code;
  name;
 }


// Mixin with main program to test the above
class Airline {
  public static void main(String [ ] args) {
    Airport ott = new Airport("YOW","Ottawa");
    Airport tor = new Airport("YYZ","Toronto Pearson");
    Airline a = new Airline("AO","Air Ottawa");
    RegularFlight r = a.addRegularFlight(100,java.sql.Time.valueOf("13:12:00"),ott,tor);
    SpecificFlight f = r.addSpecificFlight(java.sql.Date.valueOf("2017-03-15"));
    Passenger p = new Passenger("John");
    Booking b = new Booking(f,p);
    System.out.println(b);
  }
}
      

Load the above code into UmpleOnline

 

Keys for Equality and Hashing

In any class you can specify a set of attributes and associations as keys. The associations must have a multiplicity of 1 at the other end. This allows Umple to generate code that defines what objects of the class are equal (they have the same values for the key).

Umple will also generate a hashCode method in any class that has a defined key. This helps when looking up an object in a set.

Place the comma-separated list of key elements in curly brackets, after the word key. If you have multiple key statements, a warning is generated.

Example

class Sport {
  name;
  description;
  code;
  key { code }
}

class League {
  name;
  id;
  geographicalArea;
  * -- 1 Sport;
  Date seasonStart;
  Date seasonEnd;
  key { id }
}

class Team {
  name;
  * -- 1 League;
}

class Player {
  name;
  Integer id;
  key { id }
 }

class PlayerOnTeam {
  Integer year;
  * -- 1 Player;
  * -- 1 Team;
  key { year, player, team }
}

   
      

Load the above code into UmpleOnline

 

Syntax


// Keys are used to define quality and hash codes, plus Sql keys.
// See user manual page KeysforEqualityandHashing
defaultKey : key { }

key : key { [keyId] ( , [keyId] )* }

softwarePattern- : [[isA]] | [[singleton]] | [[immutable]] | [[keyDefinition]] | [[codeInjection]]

// For equality and hashing KeysforEqualityandHashing
keyDefinition- : [[defaultKey]] | [[key]]

Before and After Statements

You can request that certain code be run before or after various Umple-defined actions on attributes, associations and the components of state machines. The ability to do this with methods will be available soon, giving capabilities similar to aspect-oriented languages.

Using 'before' allows you to enforce preconditions, such that the attribute or association will not be set if the precondition is not true. To reject setting a value, add 'return false'.

You can add before and after clauses to add code to generated methods of the form getX, setX, addX, removeX, getXs (to get all elements of an association), numberOfXs, indexOfX, where X is the name of the attribute or association. You can also add code before and after the constructor.

See also this example of using aspect-orientation to help interface Umple with existing libraries.

Example


class X
{
  a;
  whenWasASet;
  
  after setA {
     setWhenWasASet(getA() + System.currentTimeMillis());
  }
}

      

Load the above code into UmpleOnline

 

Another Example


class Person {
  name;
  before setName {
    if (aName != null && aName.length() > 20) { return false; }
  }
}


      

Load the above code into UmpleOnline

 

Another Example

class Operation {
  const Boolean DEBUG=true;
  query;
  before constructor {
    if (aQuery == null)
    {
      throw new RuntimeException("Please provide a valid query");
    }
  }
  after constructor {
    if (DEBUG) { System.out.println("Created " + query); }
  }
}

      

Load the above code into UmpleOnline

 

Syntax


// Aspect oriented code injection: BeforeandAfterStatements
codeInjection- : [[beforeCode]] | [[afterCode]]

beforeCode : before ([=operationSource:custom
    |generated
    |all])? [[injectionOperation]] ( , [[injectionOperation]] )* ([[codeLang]] [[codeLangs]])? { [**code] } ( [[moreCode]] )*

afterCode : after ([=operationSource:custom
    |generated
    |all])? [[injectionOperation]] ( , [[injectionOperation]] )* ([[codeLang]] [[codeLangs]])? { [**code] } ( [[moreCode]] )*

Code Injection Pattern Matching

When creating before and after statements, you can arrange for the code to be injected into certain methods that match a pattern. You can use * as a wildcard, and ! as an exclusion operator. The following examples will both generate the same code.

Another example of pattern matching for code injection can be found on the page on pooled state machines, where the same code is injected into all the event methods matching a certain pattern

Example


class Student
{
  const Boolean DEBUG = true;
  firstName;
  lastName;
  cityOfBirth;
  before get*Name { 
    if ( DEBUG) { System.out.println("accessing the name"); }
  }
}


      

Load the above code into UmpleOnline

 

Another Example


class Student
{
  const Boolean DEBUG = true;
  firstName;
  lastName;
  cityOfBirth;
  before get*,!getCityOfBirth { 
    if ( DEBUG) { System.out.println("accessing the name"); }
  }
}

      

Load the above code into UmpleOnline

 

Code Injection in Event Methods

State machine event methods are generated automatically from a state machine. Sometimes a programmer wants to execute some code whenever a given event is processed by a state machine, no matter what state the state machine is in.

Code can be injected before or after any event, as shown in the example below. Note that in the case of queued or pooled state machines, the injected code will only be triggered when the event is actually processed by the state machine (i.e. when it is removed from the queue).

Example


class Car {
  queued radio {
    on {
      radioToggle -> off;
    }
    off {
      radioToggle -> on;
    }
  }
  after radioToggle {soundBeep();}
}


      

Load the above code into UmpleOnline

 

Model Oriented Tracing Language (MOTL)

Model Oriented Tracing Language (MOTL) allows developers to specify tracing at the model level.

Historically, developers have traced software using various techniques:

However, in software generated from UML, these techniques can only be used effectively on generated code. They require understanding the structure of that generated code; furthermore trace directives need replacing when the code is replaced. Tracing thus occurs at a level of abstraction below the level at which the system is implemented.


MOTL is designed to allow tracing with direct reference to UML model elements (state machines and their states and events, associations and attributes). MOTL specifies how to inject trace code into generated code for UML constructs.


MOTL syntax is designed to be be usable independently of Umple. For example, trace statements could be used to inject tracing into code generated from a UML model specified in Papyrus. The current implementation of MOTL focuses on tracing Umple-generated code. In order to trace a UML model created by an arbitrary UML tool, it is currently necessary to have the model from that tool converted to Umple first.


MOTL can be used to generate tracing directives for different types of tracers. At its simplest level, if the phrase 'tracer Console;' is used (or no tracer statement is included), then trace output is directed to standard error. Generation of tracing for DTrace and LTTNG is under development.


MOTL can be used in two modes:


The following pages describe how to use MOTL. Many aspects of MOTL are under development. Some future pages for tracing features under development cam be found in Umple wiki pages.


The MOTL project has been sponsored by NSERC, Ericsson and Defence Research and Development Canada, in the Distributed Multi-Core Tracing Project managed by Ecole Polytechnique de Montreal

Tracing Basics

Simple tracing is specified using trace directives, which all start with the word 'trace'. This is normally followed by the UML entity to trace (attribute, association, state, etc.).


Beyond, this, other clauses can be added to limit tracing to certain conditions, to switch on or off tracing in certain situations, and to specify data that will be output.


Each 'trace' statement emits exactly one trace record when something occurs to a matching UML entity; by default it is only changes in value that trigger emission of a trace record, but later pages describe how accesses to the value can also be traced. The format of the trace record will depend on the tracer being used but by default will contain the name of the entity and the new value of that entity.

The following are extremely simple example of tracing using MOTL on a UML Integer attribute. The default console tracer is used, so output will be sent to standard error.

Example


class Student
{
  Integer id;
  
  // Whenever the id attribute is changed, emit a trace record
  // The record will have the format id=value
  trace id;
  
  // The following Java main program can be used to demonstrate this in operation
  // This will output a record when id is set to 9.
  public static void main(String [ ] args) {
    Student s = new Student(6);
    s.setId(9); 
  }
}


      

Load the above code into UmpleOnline

 

Another Example


class Student
{
  lazy Integer id;
  lazy name;
  
  // It is possible to specify multiple UML entities to trace as follows
  // It is also possible to indicate interesting information to record
  // in addition to the value of the element being traced
  trace id, name record "interesting behavior";
  trace id record "Even more interesting";

  // Traces will be triggered for each call to a 'set' method
  // and twice for id, since there are two trace statements for id  
  public static void main(String [ ] args) {
    Student s = new Student();
    s.setId(9); 
    s.setName("Tim");
  }
}


      

Load the above code into UmpleOnline

 

Tracing Attributes

MOTL allows the tracing of attributes at the model level. Attribute tracing can occur whenever an attribute value is changed (i.e. setter is called) or/and when the value is accessed (i.e. the getter method is called). Thus, attribute tracing can be made to occur any of the following modes:

Example

// This traces setId() and setName()
class Student
{
  Integer id;
  String name;
  trace id;
  trace set name;
}


      

Load the above code into UmpleOnline

 

Another Example

// This traces  getId() method
class Student
{
  Integer id;
  trace get id;
}

      

Load the above code into UmpleOnline

 

Another Example

// This example traces getId() and setId()
class Student
{
  Integer id;
  trace set,get id;
}


      

Load the above code into UmpleOnline

 

Syntax


traceDirective : trace [[Prefix]]? [[traceEntity]] [[Postfix]] ;

traceEntity- : [traceEntity] (()? ())? ( , [traceEntity] (()? ())? )*

Tracing State Machines

State machines are representations of system behaviour. States can have entry or exit actions and do activities; they can also be composite (i.e. nested) or concurrent. MOTL provides modellers with the capability of specifying tracing for all these modelling elements.

Example

class LightBulb
{
  Integer v = 0;
  status
  {
    On { 
      entry / { setV(1); } 
      flip -> Off;
    }
    Off { 
      entry / { setV(2); }
      flip -> On;
    }
  }
  // trace whenever we enter/exit state On 
  trace On;
  // trace whenever we exit state Off and report value of attribute v 
  trace exit Off record v;
}
      

Load the above code into UmpleOnline

 

Another Example

class LightBulb
{
  status
  {
    On { 
      flip -> Off;
    }
    Off { 
      flip -> On;
    }
  }
  // trace any triggering of event flip
  trace flip;
}
      

Load the above code into UmpleOnline

 

Another Example

// this example will trace all states of State machine GarageDoor 

class GarageDoor
{
    // UML state machine digram for a Garage door, written in Umple
    status { 	
      	Open { buttonOrObstacle -> Closing;  }  	
      	Closing {
          buttonOrObstacle -> Opening;
          reachBottom -> Closed;
      	}
      	Closed { buttonOrObstacle -> Opening; }
      	Opening {
          buttonOrObstacle -> HalfOpen;
          reachTop -> Open;
      	}
      	HalfOpen { buttonOrObstacle -> Opening; }
    }
    // trace whole state machine
    trace status;
}
      

Load the above code into UmpleOnline

 

Syntax


traceDirective : trace [[Prefix]]? [[traceEntity]] [[Postfix]] ;

traceEntity- : [traceEntity] (()? ())? ( , [traceEntity] (()? ())? )*

Tracing Associations

Associations describe the relationships between class instances; role names are used to clarify the relation at both ends of an association. MOTL allows the tracing of associations by referring to the role names. Tracing can occur whenever an association link is added or deleted at run time:

Example

// This example will record any addition/removal to supervisor assoc link 

class Student {
  Integer id;
}

class Professor {
  1 -- * Student supervisor;
  
  trace supervisor;
}
      

Load the above code into UmpleOnline

 

Another Example

// This example will record any addition to assoc link 'supervisor'

class Student {
  Integer id;
}

class Professor {
  1 -- * Student supervisor;
  
  trace add supervisor;
}
      

Load the above code into UmpleOnline

 

Another Example

// This example will record any removal of any supervisor assoc link 

class Student {
  Integer id;
}

class Professor {
  1 -- * Student supervisor;
  
  trace remove supervisor;
}
      

Load the above code into UmpleOnline

 

Syntax


traceDirective : trace [[Prefix]]? [[traceEntity]] [[Postfix]] ;

traceEntity- : [traceEntity] (()? ())? ( , [traceEntity] (()? ())? )*

Tracing Constraints

Constraints can be imposed upon the traced UML entity to limit the scope of tracing to when a certain condition is true. MOTL provides a set of constraints that can be classified into a prefix and postfix constraints.

Example

class Student
{
  name;
  Integer id;

  // trace code is injected in attribute setter with specified precondition
  trace name where [name == "john"];

  // trace code is injected in attribute setter with specified postcondition
  trace id giving [id > 9000];

  // this example traces attribute name whenever its value is changed for 5 times 
  trace name for 5;
}

class Professor {
  name;
  1 -- * Student supervisor;
  
  // trace code is injected in attribute setter with role name cardinality condition
  trace name where [ supervisor cardinality > 10];
}


      

Load the above code into UmpleOnline

 

Another Example

class Student
{
  name;
  Integer id;
  // trace attribute id and record provided string message as part of  the trace output
  trace id record "i am tracing attribute name";
  
  status {
    s1 { e1 -> s2; }
    s2 {}
  }
  // trace whenever we enter/exit state "s1" and record attribute name
  trace s1 record name;
}


      

Load the above code into UmpleOnline

 

Another Example

class Student
{
  name;
  Integer id;
  
  // tracing of attribute name starts and doesn't stop until condition becomes true
  trace name until [name == "john"];

  // tracing of attribute id until condition becomes true and then always continue tracing 
  trace id after [id == 234];
}


      

Load the above code into UmpleOnline

 

Syntax


traceCondition : [=conditionType:where|until|after|giving]? [ [[constraintToken]] ]

traceFor- : for [traceFor]

// A constraint is an expression optionally be surrounded in round brackets or negated
constraint- : [[constraintBody]] [[linkingOp]]? | [[constraintExpr]] [[linkingOp]]?

Tracing Methods

Tracing non api methods is possible using MOTL. Entry and/or exit of methods can be traced.

Example

// this example shows how to trace non api method entry

class JavaMethod
{
  trace method();
    
  int method( int x ) {
    x += 5;
    return x;
  }
}


      

Load the above code into UmpleOnline

 

Another Example

// this example shows how to trace non api method exit
// incase of methods with return statement, trace code is 
// injected before the return

class JavaMethod
{
  trace exit method();
    
  int method( int x ) {
    x += 5;
    return x;
  }
}


      

Load the above code into UmpleOnline

 

Syntax


traceDirective : trace [[Prefix]]? [[traceEntity]] [[Postfix]] ;

Tracers

MOTL sets the Console to be its default tracer. However, it provides a set of potential tracers that will have an impact on how tracing is injected and how its collected. Modellers can control the model tracer using a tracer directive.

MOTL tracers can be classified into two main categories: Built in tracers and third party tracers. The main difference between these two categories is that the first category tracers doesn’t require any additional jars imported into your model generated code, while the later requires jars specific to each tracer.

  1. (Built in tracers)
  2.  
  3. (Third party tracers)

Example

// this example generates traces using the File tracer
tracer File;

class Student
{
  Integer id;
  trace id;
}


      

Load the above code into UmpleOnline

 

Another Example

// this example generates traces using the Java native logging API
tracer JavaAPI;

class Student
{
  Integer id;
  name;
  // trace id with default logging level info
  trace id;
  // trace name to logging level severe
  trace name logLevel severe;
}
      

Load the above code into UmpleOnline

 

Another Example

// this example generates tracespoints using the Lttng tracer
tracer Lttng;

class Student
{
  Integer id;
  trace id;
}

      

Load the above code into UmpleOnline

 

Another Example

// this example generates traces using the log4j tracer
// Default log4j xml configuration file is generated (log4j2.xml) 
tracer log4j;

class Student
{
  Integer id;
  name;
  
  // trace attribute id with log4j level set to (info)
  trace id logLevel info;

  // trace attribute id with log4j level set to (error)
  trace name logLevel error;
}

      

Load the above code into UmpleOnline

 

Another Example


// this example generates traces using the log4j tracer
// Customized log4j xml configuration file is generated (log4j2.xml)
// Root logger level will be debug
// Info logging level will be written into console output
// Error logging level will be written into file
tracer log4j root=debug info = console error = file;

class Student
{
  Integer id;
  name;
  
  // trace attribute id with log4j level set to (info)
  trace id logLevel info;

  // trace attribute id with log4j level set to (error)
  trace name logLevel error;
}

      

Load the above code into UmpleOnline

 

Syntax


Trace Output

Specifying trace directives at the model level will inject trace points in source code generated from the model. MOTL was designed to collect a wide range of information when tracing is triggered at the execution time.

Collected information includes current system time, thread ID, Object hash code, etc. MOTL tracers will output an initial header to indicate each traced field name.

Using UmpleOnline

The following describes how to use the UmpleOnline tool accessible online at try.umple.org

For information about writing Umple models or code in UmpleOnline, look at the Getting Started section of this user manual, or any other topic in the left column of this page, including information about defining classes, attributes, associations and state machines.


Loading and saving

Left Pane: Umple textual code

Right Pane: UML diagram

Bottom Pane: Errors, Warnings and Generated Results

Shortcuts


See here for the statement regarding privacy and other risks when using UmpleOnline.

UmpleOnline URL options

UmpleOnline allows you to append various options to its URLi, enabling startup in a certain state. These are preceded by an ampersand, except the first in a list which would be preceded by a question mark.

Umple in Presentations and Documents

Embedding a pure diagram in a web page

Using &nochrome&notext&nomenu&readOnly allows you to embed a pure diagram in a web page. Using &nochrome&nodiagram&nomenu&readOnly allows textual listings in any other web page. Using &nochrome&notext allows a UML diagram editor to be embedded.

For example, Click here to see a document with an embedded iFrame containing an editor opening on the RoutesAndLocations example. The chrome and text is hidden.

For a read-only version, with ability to generate code, use http://try.umple.org/?example=RoutesAndLocations&notext&nochrome&readOnly

Coloring model elements

Umple has a special directive that allows you to highlight certain elements (currently only classes) in UmpleOnline and GraphViz output. Simply write 'displayColor xxx;' in a class where xxx is any html colour such as "red" or "#BBCCFF". UK spelling displayColour also works.

Umplification - An Introduction

Umplification involves transforming step by step a base language program to an Umple program; each step is a refactoring. The starting point and the ending point of each transformations will be a system rendered in a textual form combining model elements in the Umple syntax and base language code.

Umplification involves increasing the proportion of modeling elements.

The key insight is that a pure Java program can be seen as a speci al case of an Umple program. A pure model can also be seen as such a special case. So Umplification involves repeatedly modifying the Umple to add abstractions, while maintaining the semantics of the program, and also maintaining to the greatest extent possible such elements as layout, algorithmic methods and comments

Two main features differentiate Umple from existing reverse engineering techniques.

  1. The Tranformations required are intended to be applie incrementally by a programmer who has a body of legacy code and wants to gradually transform it intoUmple, preserving much of the layout, comments and other aspects of the original code if possible.
  2. The transformations required are at the same time code-to-model,model-to-model and code-to-code.

Umplification Process

To start, source files with language L (e.g. Java, C++) code are initially renamed as Umple files, with extension .ump.

Then, iteratively, small transformations are performed that gradually add UML abstractions. Each iteration should involve testing to check that the program’s semantics are preserved.


Umplification can be performed automatically by a reverse engineering technology that can parse a program in any native programming language and extract the Umple model from it.

Interfacing to External Code

This example shows some of the techniques that can be used when writing Umple code that will be connected to code written separately, such as code in a GUI library. Use of the:

Example

/*
This example demonstrates an example of using the internal,
depends, external, before and after keywords to interface
umple code to code in another system.

The internal keyword is suitable for situations where the
developer doesn't want setter/getters to be generated.
GUI windows are an example of such a case. A GUI window/unit
contains several components but the rest of the program
may only need the value stored within those components.
So it's a good practice to hide UI components from classes
other than the containing one. 

*/

// required to make HelloInternals class a JFrame
external JFrame{}

class HelloInternals {
  // HelloInternals extends JFrame
  isA JFrame;

  // importing required classes
  depend javax.swing.JFrame;
  depend javax.swing.JLabel;

  /* messageLabel is a component of the frame; often we don't want sub-components
  of a GUI unit to be settable/gettable. By making them internal Umple will avoid
  generating setter/getter for messageLabel. Using lazy Umple will avoid adding a
  constructor parameter for this component */
  lazy internal JLabel messageLabel;
  
  // the contents of messageLabel 
  String message;
  
  /* before getting the message, this code updates the message attribute using the
  text from messageLabel */  
  before getMessage {
    message=messageLabel.getText();
  }
  
  /* after setting the messae, this code updates messageLabel to contain the newly
  updated message */
  after setMessage {
    messageLabel.setText(message);
  }
  
  // using after constructor is a good way of initiating a GUI unit
  after constructor {
    getContentPane().setLayout(null);
  
    messageLabel=new JLabel(message);
    messageLabel.setBounds(10, 10, 200, 20);
    add(messageLabel);
    
    pack();
    setSize(250, 200);
  }
}


      

Load the above code into UmpleOnline

 

2D Shapes System

Example

// 2D Shapes class hierarchy - sample UML class diagram in Umple
// From Book by Lethbridge and Laganiere, McGraw Hill 2004
// Object-Oriented Software Engineering: Practical Software Engineering using UML and Java
// See http://www.lloseng.com

//Namespace for core of the system.
namespace Shapes.core;

class Shape2D {
 center;
}
//Abstract
class EllipticalShape {
 isA Shape2D;
 semiMajorAxis;
}
//Abstract
class Polygon { 
 isA Shape2D;
}
class Circle {
 isA EllipticalShape;
}
class Ellipse{
 isA EllipticalShape;
}
class SimplePolygon {
 orientation;
 isA Polygon;
}
class ArbitraryPolygon {
 points;
 isA Polygon;
}
class Rectangle {
 isA SimplePolygon;
 height;
 width;
}
class RegularPolygon {
 numPoints;
 radius;
 isA SimplePolygon;
}

      

Load the above code into UmpleOnline

 

Airline System

A simple airline system that manages flight and passenger information

Example

// Airline system - sample UML class diagram in Umple
// From Book by Lethbridge and Laganiere, McGraw Hill 2004
// Object-Oriented Software Engineering: Practical Software Engineering using UML and Java
// See http://www.lloseng.com

namespace Airline;

class Airline{
  1 -- * RegularFlight;
  1 -- * Person;
}

class RegularFlight{
  Time time;
  unique Integer flightNumber;
  1 -- * SpecificFlight;
}

class SpecificFlight{
  unique Date date;
}

class PassengerRole
{
  isA PersonRole;
  immutable String name ;
  1 -- * Booking;
}
  

class EmployeeRole
{
  String jobFunction ;
  isA PersonRole;
  * -- 0..1 EmployeeRole supervisor;
  * -- * SpecificFlight;
}

class Person
{
  settable String name;
  Integer idNumber;
  1 -- 0..2 PersonRole;
}

class PersonRole{}

class Booking{
  String seatNumber;
  * -- 1 SpecificFlight;
}

      

Load the above code into UmpleOnline

 

Banking System

Example

// Sample UML class diagram for a banking system, written in Umple

//Namespace for core of the system.
namespace BankingSystem.core.humanResources;
class PersonRole{}

class Person{
 name;
 address;
 phoneNumber;
 
 1 -- * PersonRole;
}

class Employee{
 isA PersonRole;
}

class Client
{
 isA PersonRole;
 name;
 address;
 phoneNumber;
 1..2 -- 1..* Account;
}

class Manager {
 isA Employee;
 0..1 -- * Employee;
}

//Accounts,  priviledges, etc.
namespace BankingSystem.core.intangableResources;
class Account{
 Integer accountNumber;
 Float balance;
 Float creditLimit;
 * -> 1 AccountType;
}

class AccountType
{
 Float monthlyFee;
 Float interestRate;
 
 * -- * Privilege;
}

class Privilege
{
 description;
}

class CreditCardAccount{
 isA Account;
 Date expiryDate;

 1 -- 1..* Card;
}

class MortgageAccount {
 isA Account;
 collateral;
}

//Anything physicaly tangable
namespace BankingSystem.core.tangableResources;
class Card
{
 holderName;
}

class Branch {
 isA Division;
 address;
 branchNumber;

 1 -- * Account;
}

class Division{
 name;
 
 1 -- * Employee; 
 0..1 -- 0..* Division subDivision;
}

      

Load the above code into UmpleOnline

 

Banking System (b)

Example

/*
  Banking System - sample UML class diagram written in Umple
  Last updated: February 21, 2011
*/
//Namespace for core of the system.
namespace BankingSystem.core;

class FinancialInstitution {
 name;
 1 -- * ReusableFinancialInstrument;
}

class CreditCardCompany{
 isA FinancialInstitution;
}

class Bank{
 isA FinancialInstitution;
 1 -- * Branch;
}

class FinancialInstrument{
}

class ReusableFinancialInstrument{
 isA FinancialInstrument;
 number;
 pin;
 * -> 1 Currency;
}

class CreditCard {
 isA ReusableFinancialInstrument;
 creditLimit;
 name;
}

class DebitCard {
 isA ReusableFinancialInstrument;
}

class Cheque {
 isA FinancialInstrument;
 amount;
 Date date;
 sequenceNumber;
}

class BankAccount{
 isA FinancialInstrument;
 accountNumber;
 balance;
 Float overdraftOrCreditLimit;
 
 1..* -- * DebitCard;
 1 -- * Cheque; 
}

class Currency
{
 code;
 exchangeRate;
}

class Branch
{
 name;
 address;
 1 -- * BankAccount;
}

class Loan{
 isA BankAccount;
}

      

Load the above code into UmpleOnline

 

Election System


Example

// UML class diagram for a system for managing elections, written in Umple
namespace electorial;

// association should be ->
class PollingStation {
 Integer number;
 address;

 1 -- * PollInElection; 
} 
 
class ElectedBody{
 description;

 1 -- * Position;
}

 //Different elections may have different sets of polls
class Election{
 Date date;
 
 1 -- * PollInElection;
 1 -- * ElectionForPosition;
}

class ElectionForPosition{
 1 -- * Candidature;
}

//Eg. Mayor, Councilor. AKA seats
//A position can have different elections for it at different times, eg. once every four years.
class Position {
 description;
 1 -- * ElectionForPosition;
}

//We need candidature class since a candidate can run for different 
//positions and for the smae positions at subsequent elections
class Candidature {
 internal Boolean isIncumbent = false;
 
 public void markAsIncumbent()
 {
   isIncumbent = true;
 }
 
 public String toString()
 {
   return isIncumbent ? "Incumbent" : "Candidature";
 }
}

class Candidate {
 name;
 Integer phoneNumber;
 address;
 
 1 -- * Candidature;
}

class PollInElection {
 Integer number;
 
 1 -- * Voter;
}

associationClass VotesInPoll{
 * Candidature;
 * PollInElection;
 Integer numVotes;
}

class Voter{
 name;
 address;
 * -- * Candidature;
}

class ElectoralDistrict{
 1 -- * Voter; 
 0..1 -- * Position; 
 0..1 -- * ElectoralDistrict subDistrict;
}    

      

Load the above code into UmpleOnline

 

Warehouse System

Example

// UML class diagram of a system for managing a warehouse
namespace warehouse;

class MovementLocation{}

class SlotSet{
 isA MovementLocation;
 0..1 -- 0..1 BoxOrPallet;
 1 -- * Slot;
}

class Slot{
 Integer number;
 Double width;
}

class Level{
 Integer height;
 Integer number;
 1 -- * Slot;
}

class LoadingGate{
 Integer number;
 isA MovementLocation;
}

class Truck{
 Integer registerNum;
 Boolean isWaiting;

 1 -- * DeliverOrShipmentBom;
}
class Rwbm{
 Integer id;
}

class Item{
 Double value;
 Integer hazardID;
 Integer breakability;
}

class Row{
 Integer depth;
 Integer number;
 
 1 -- * Level;
}

//Note that here we have the choice to use
// Time or Double, if the customer requires Double due to 
// some interoperability issues with a legacy syste, we can easily
// accomodate them and use Double instead of Time.
class RwbmMovement{
 Double startTime;
 Double endTime;
 
 * toMovement -- 1 MovementLocation to;
 * fromMovement -- 1 MovementLocation from;
 * -- 1 BoxOrPallet movedBox;
 1 -- * Rwbm;
}

// Both associations should be ->
class DeliverOrShipmentBom {
 Double startTimeLoadOrUnload;
 Double endTimeExpected;
 * delivery -- 0..1 LoadingGate sentThrough;
 * arrival -- 0..1 LoadingGate arriveAt;
}

class BoxOrPallet{
 Integer rfidTagNumber;
 Double lengthINmm;
 Double widthINmm;
 Double heightINmm;
 Double weightINkg;
 String contentType;
 
 * -- * DeliverOrShipmentBom;
 1 -- * Item; 
}

      

Load the above code into UmpleOnline

 

Canal System

Canal system class diagram.

See also the state diagram for the canal lock.

The following are the requirements from which this was derived:

The Canal Monitoring and Control System is used to automate canal locks in response to water craft that want to pass through a canal system. The system can be installed in any network of canals. Each canal is divided up into segments. Each segment has two ends which can either be a bend, a lock gate, a low bridge, or a system entry/exit point (where boats can move to or from other waterways such as rivers and lakes). A special kind of canal segment is a lock. The water level in a lock can be raised or lowered so its height matches the height of an adjacent segment. Several locks can exist side by side (as in the Rideau Canal next to Parliament Hill in Ottawa). A low bridge is a location where the bridge needs raising for a boat to pass. A bend is simply a place where the canal changes direction - keeping track of these helps simplify mapping of the system.

The system keeps track of the GPS co-ordinates of each segment end, the height of the water above sea level in each segment (which can change in locks), and optionally a name given to a series of locks or segments.

Each water craft using the system must have a transponder. The transponder includes a GPS unit and transceiver. When the captain of a craft wants to travel through the system, he enters his plannned destination in the transponder. The size of the boat is also tracked. The transponder regularly transmits the location of the craft to the control system so the control system can monitor traffic.

When a craft reaches a gate, the system knows it is there and needs to pass through since it has received the data about the desired destination. The control system takes care of opening the gate, raising or lowering of the water level, and then opening the next gate, etc. When a boat reaches a low bridge, a similar procedure takes place, except that raising or lowering the water doesn't happen.

When there are a lot of boats, the system makes several of them queue up so they can pass through a lock or low bridge at the same time. The system has, however, to ensure that only the right number and size of boats are put into a lock at once, so the lock doesn't become overly full (the system knows the size of each lock). Complicating matters is the fact that there will be boats travelling in both directions.

Example

// UML class diagram that models a canal as a network of segments, with Locks
// See the State Machine section for a state machine for each lock
class CanalNetwork {
  name;
  0..1 -- * CanalNetwork subNetwork;
  0..1 -- * Craft activeVessels;
  * -- * SegEnd;
}

class SegEnd {
  name;
  GPSCoord location;
}

class Segment {
  Float waterLevel; // m above sea level 
  1..* -- 2 SegEnd;
}

class Lock {
  isA Segment;
  Float maxLevel;
  Float minLevel;
}

class Bend {
  isA SegEnd;
}

class EntryAndExitPoint {
  isA SegEnd;
}

class MooringPoint {
  isA SegEnd;
}

class Obstacle {
  isA SegEnd;
  0..1 downstreamObstacle -- * Craft upStreamQueue;
  0..1 upstreamObstacle -- * Craft downStreamQueue;  
}

class LowBridge {
  isA Obstacle;
}

class LockGate {
  isA Obstacle;
}

class Craft {
  lazy GPSCoord location;
}

class Trip {
  0..1 -> 1..* SegEnd;
  0..1 -- 1 Craft;
}

class Transponder {
  id;
  0..1 -- 0..1 Craft;
}

class GPSCoord {
   Float lattitide;
   Float longitude;
}
      

Load the above code into UmpleOnline

 

Canal Lock State Machine

Canal Lock State Machine

See also the class diagram and requirements for the canal system.

Example

// UML state machine diagram for a canal lock, represented in UML 

class Lock
{
  Boolean boatGoingDown = false;
  Boolean boatGoingUp = false;
  Boolean boatBlockingGate = false;
  
  lockState {
    BothDoorsClosedLockFull {
      // Waiting for boat
      boatRequestsToEnterAndGoDown -> OpeningUpperGate;
      boatRequestsToEnterAndGoUp -> LoweringWater;
    }

    OpeningUpperGate {
      upperGateFullyOpen -> UpperGateOpen;
    }

    UpperGateOpen {
      entry / {setBoatGoingUp(false);}
      boatInLockRequestingToGoDown -> / {setBoatGoingDown(true);} ClosingUpperGate;
      after3minutes [!boatBlockingGate] -> ClosingUpperGate;
    }

    ClosingUpperGate {
      upperGateFullyClosed [boatGoingDown]-> LoweringWater;
      upperGateFullyClosed [!boatGoingDown]-> BothDoorsClosedLockFull;   
    }
    
    LoweringWater {
      waterLevelMatchesDownStream -> OpeningLowerGate;
    } 
    
    
    BothDoorsClosedLockEmpty {
      // Waiting for boat
      boatRequestsToEnterAndGoUp -> OpeningLowerGate;
      boatRequestsToEnterAndGoDown -> RaisingWater;
    }

    OpeningLowerGate {
      lowerGateFullyOpen -> LowerGateOpen;
    }

    LowerGateOpen {
      entry / {setBoatGoingDown(false);}
      boatInLockRequestingToGoUp -> / {setBoatGoingUp(true);} ClosingLowerGate;
      after3minutes [!boatBlockingGate] -> ClosingLowerGate;
    }

    ClosingLowerGate {
      lowerGateFullyClosed [boatGoingUp]-> RaisingWater;
      lowerGateFullyClosed [!boatGoingUp]-> BothDoorsClosedLockEmpty;   
    }
    
    RaisingWater {
      waterLevelMatchesUpStream -> OpeningUpperGate;
    } 
  }
}

      

Load the above code into UmpleOnline

 

Card Games

This system will allow players to play card games such as Whist and Oh Hell online.

The system should manage the cards in a deck of cards, the players (including who is dealer), the hands of cards each player has, the tricks, the pile of cards on the table. It should also manage the matches between players. Use some background research to improve these simple requirements.

Example

// Umple class diagram representing card games in the Oh Hell and Whist family

class Card {
  suit;  // "hearts", "clubs", "diamonds", "spades" 
  rank;  // A23456789JQK
  Boolean isJoker; // suit and rank are null for a Joker
}

class CardSet {
  // Could be a complete deck or a trick
  1 -- * Card;
}

class NotDealtCardSet {
  // This would be initialized with a complete 52-card set
  // at the start of each game
  // During dealing, the cards would be distributed to players
  isA CardSet;
}

class Trick {
  // A group of cards with one contributed by each player, and
  // eventually won by a player
  // One is built after each player has played a card
  isA CardSet;
}

class Player {
   // These are the people playing.
   name;

   // A hand is dealt at the start of a game
   // The cards a player has in his or her hand
   0..1 -- * Card hand; 

   // The tricks won by a player this game
   1 -- * Trick; 
   
   // All hands and tricks are cleared at the end of each game
   // ready for dealing again

   // The following is used only in Oh Hell
   Integer currentTricksBid;
}

class ScoringTeam {
   // for Oh Hell, it is each player for himself, so there is one player
   // for Whist there are partners, so there are two players
   1 -- 1..2 Player;
   
   // The score that each team has accumulated so far
   // based on tricks taken or difference between tricks and bid
   Integer score;
}

class Match {
  // A match is played in a number of games
  Boolean isWhist; // True if whist; false if Oh Hell  

  // The following determines the players
  // the first player in the first team deals first
  * -- 2..* ScoringTeam; // Exactly 2 if Whist
  
  Integer scoreToWin; // The score agreed to in order to declare winner

  1 -- * Game games; // Games continue until a player or team wins
  // Assume that the last game in games is the current one
}

class Game {
   trumps; // a suit (if any) that is the trumps for this game
   
   // One player is the dealer each game
   // The dealer deals out all or most of the cards at the start
   // Players take turn laying down cards to form the next trick
   * -- 1 Player dealer;
   
   // As the cards are laid down the following set is created.
   // After all players have contributed a new trick is created from the
   // following and awarded to a player
   0..1 -- * Card currentTrickBeingBuilt;

   * gameLed -- 0..1 Player currentLead; // the player next to lay down a card
}

class Card
{
  position 125 15 135 100;
}

class CardSet
{
  position 186 153 109 45;
  position.association Card__CardSet 30,0 31,100;
}

class NotDealtCardSet
{
  position 129 244 123 45;
}

class Trick
{
  position 278 245 109 45;
}

class Player
{
  position 43 429 192 82;
  position.association Card:hand__Player 7,0 0,88;
}

class ScoringTeam
{
  position 561 411 122 64;
  position.association Player__ScoringTeam 0,31 192,55;
}

class Match
{
  position 532 48 159 82;
  position.association Match__ScoringTeam 120,82 60,0;
  position.association Game:games__Match 30,82 72,0;
}

class Game
{
  position 442 280 123 64;
  position.association Game__Player:currentLead 11,64 192,11;
  position.association Card:currentTrickBeingBuilt__Game 0,10 135,50;
  position.association Game:gameLed__Player:currentLead 24,64 192,30;
  position.association Game__Player:dealer 0,38 192,10;
}


      

Load the above code into UmpleOnline

 

Pizza Delivery

Requirements for this system are as follows:

A take-out pizza restaurant wants to set up an online ordering system. A customer must have an account to use the system. When the customer creats his or her account, the following information is stored: Email address (which becomes the user id), contact phone number, password, name, address, preferred credit card number, and credit card expiry date. When the customer creates an order the following information is stored: The time the order was placed, the address for delivery, the contact phone number, the total price, the credit card number charged, the expiry date of the credit card, the items ordered and the total price. An item can be pizza or drinks. For each pizza item, the information stored will include the kind of pizza (thin crust, thick crust or gluten-free crust), the size (small, medium, large), the list of toppings (e.g. cheeze, bacon, vegetables, etc.), the number of items like this (e.g. 10 would mean 10 identical pizzas) and the total price for this pizza item. For each drink item, the information stored is type, size, number, and total price. The system also records each delivery: Associated with each delivery is the name of the delivery driver; the time the driver picked up the order(s) and the time each order was delivered. A driver may take more than one order on a delivery run.

Example

// UML Class diagram representing a system for taking online orders for Pizza

class Account
{
  emailAddress;
  contactPhoneNumber;
  password;
  name;
  address;
  preferredCredCard;
  expiryDate;
  0..1 -- * Order;
}

class Order
{
  timePlaced;
  contactPhoneNumber;
  Float totalPrice;
  creditCardCharged;
  expiryDate;
  1 -- * OrderItem;
}

class OrderItem
{
  Integer number;
  Float totalPrice;
}

class PizzaOrder
{
    isA OrderItem;
kind;
  * -> * ToppingType toppings;
  * -> 1 StandardPizzaSize;
}

class ToppingType
{
  description;
}

class StandardPizzaSize
{
  sizeLabel;
}

class DrinkOrder
{
    isA OrderItem;
    drinkSize;
size;
}

class Delivery
{
  Time timePickedUp;
  Time timeDelivered;
  * -- 0..1 Driver;
  0..1 -- 1..* Order;
}

class Driver
{
  name;
}


      

Load the above code into UmpleOnline

 

Community Association

Requirements for this system are as follows:

You are in charge of the website of a community. Residents in the community can sign up to join the community association for a fee of $30. If they do, then they can vote for the executive of the association and can use facilities and attend certain events for free. Only one membership is required per residence and it must be renewed by the end of October each year (it is valid for one year). For each member the system stores the street address, apartment number (if there is one) the email address, the telephone number, and the names of the residents. Anyone under 18 is flagged, as there are special events for these people. The community runs a rink in the winter and three tennis courts in the summer. Members of the community association are given priority to sign up for blocks of time in these facilities, to a maximum of four hours per week. Residents who are not members can sign up 24 hours before their booked time, if there are still any free time slots. When a non-member signs up in this way, they need to give their name, street address and email address. Some time slots in the rink and tennis courts are left unbooked for free 'first-come-first-served' access'

@@example @@source CommunityAssociation.ump @@endexample

Co-Op Education

Requirements for a University System to Manage Co-Op Programs

The co-op system works as follows. Employers contact the university and list potential jobs. Each job has a description, employer, location, start and end date, and a list of programs (e.g. SEG, CSI, MCG) for which it is applicable.

Each student in the system has a name, student number, list of available time slots (when they are not in courses, or not doing interviews), resume and transcript.

Students in various programs apply for jobs. Students choose a set of jobs they are interested in. The system shows the list of interested students to employers, and employers pick a set of students to interview. The system sets interview times that match the employee’s and student’s availability (set of available time slots).

At the end of the process, the system arranges for the employer to offer each job to a student. If the first student does not accept, the system arranges for other students (the employer’s second, third choices, etc. ) to be offered the job

Example

// UML class diagram in Umple showing the data managed by
// a co-operative education system that has to place students with employers

class Program
{
  name;
  1..* -- * Student;
}

class Application
{
  * -- 1 Student;
  * -- 1 Job;
  1..* -- 0..1 Interview;
  1 -- 0..1 Offer;
}

class Job
{
  description;
  location;
  Date startDate;
  Date endDate;
  * -- 1..* Program;
}

class Employer
{
  name;
  1 -- * Job;
  0..1 -> * TimeSlot;
}

class Interview
{
  location;
  0..1 -> 0..1 TimeSlot;
}

class TimeSlot
{
  startTime;
  endTime;
  status;
}

class Student
{
  Integer stNum;
  1 -- 1 Transcript;
  0..1 -> * TimeSlot;
}

class Resume
{
  text;
  0..1 -- 1 Student;
}

class Transcript
{
  text;
}

class Offer
{
  ranking;
  Boolean accepted;
}


      

Load the above code into UmpleOnline

 

Vending Machine Classes

The following are basic requirements for a vending machine

A vending machine dispenses a variety of products. Each product is held in one or more dispensers, identified by slot and row in the machine. The system keeps track of the number of each product type in each dispenser, so it knows when a dispenser becomes empty.

The vending machine has several coin holders. Each coin holder can contain a specific type of coin worth a particular number of cents, and with a certain weight and diameter. The system tracks the number of coins in each holder, so it can determine whether it can give change, and what coins it should give as change when somebody buys a product. Each holder also has a maximum capacity The system keeps an electronic record of each successful purchase (transaction); it records the product dispensed from a dispenser and the number of coins added (i.e. paid by the customer) or deleted (i.e. given as change) from coin holders.

Example

// UML state machine diagram of a vending machine
// There is also a class diagram example separately
class VendingMachine
{
  controlUnit {
    ReceivingMoney {
      pressSelection  -> ReceivingMoney;
      enterCoin  -> ReceivingMoney;
      pressSelection -> DeliveringItem;
    }

    DeliveringItem {
      deliveryComplete  -> Waiting;
      deliveryComplete -> ReturningMoney;
    }
    
    ReturningMoney {
      retunringComplete -> Waiting;
    }
    
    Waiting {
      enterCoin -> ReceivingMoney;
    }
  }
}
      

Load the above code into UmpleOnline

 

Routes And Locations

This example has been built for the Comparing Modeling Approaches Workshop

Example

// RoutesAndLocations.ump  Class diagram represented in Umple
//
// Author: Timothy C. Lethbridge

namespace routesAndLocations;

/* 

This file describes reusable model elements that are used in the 
bCMS Crisis Management System. It is necessary to have a rudimentary
Graphical Information System such as described in this submodel as part
of bCMS in order to plan routes and to track where crises are. This file
has the necessary classes.

*/

/* 
 * A CityMap contains the precompiled streets and landmarks
 * This must be read in from the database on system initialization
 */
class CityMap {
  singleton;
  0..1 -> * Landmark fireStn;
  0..1 -> * Landmark policeStn;
  0..1 -> * Landmark otherLm;
  0..1 -> * NamedRoad;
}
  
/*
 * A Location describes a place such as an intersection, landmark, bend in a road, etc.
 */
class Location {
  Float lattitude;
  Float longitude;
}

class Landmark {
  isA Location;
  
  // Name of landmark (name of fire station, business, address)
  description;  
  landmarkType { fireStation { } policeStation { } touristDestination { } other { } } 
}

/*
 * RoadNodes are places where RoadSegments connect. A node with just one incoming
 * and one outgoing is used to handle changes in direction, e.g. as a road turns
 * a corner, changes in speed limit, changes in number of lanes, and other factors.
 * When there is more than one outgoing or incoming, the node represents points
 * where traffic flow can split and join.
 * A crossroads is one type. Entry into a roundabout would be another,
 * Highway merges and exits are other kinds as are parking lots and entries
 * into or out of fire stations..
 *
 * RoadSegments leaving the city lead to no RoadNode
 * RoadSegments entering the city come from no RoadNode
 */
class RoadNode {
  Integer id;
   // Could be at a landmark
  0..1 -> 1 Location nodeLocation;
  0..1 end -- * RoadSegment incomingRoads;
  0..1 start -- * RoadSegment outgoingRoads;
}

class Intersection {
  isA RoadNode;
  // illegal, but possible turns for police and fire
  0..1 -> * Turn illegalTurns;
  // Impossible turns , e.g. because of barriers, turning radius
  0..1 -> * Turn impossibleTurns;
}

/* 
 * Turns are used to model illegal turns, e.g. turning left
 * when there is 'no left turn' allowed, or 'no U turn' allowed.
 */
class Turn {
  RoadSegment turnFrom;
  RoadSegment turnTo;
}

/*
 * A named road might have the name of a street, the number of
 * a highway, etc. A RoadSegment can have several names because
 * for example, sometimes several numbered highways share a segment
 */
class NamedRoad {
  name;
  
  // Most roads have two directions, e.g. North and South
  direction;  
  
  // Listed in order
  * -- 1..* RoadSegment segments; 
}
  
/*
 * A RoadSegment represents a section of road on which a vehicle can drive.
 * The ends of each segment have been modeled using RoadNodes.
 * Note that distance can be calculated from the speed limit, and locations
 */
class RoadSegment {
  Integer speedLimit;
  
  // Indicator of real-time congestion; 0=blocked
  Integer currentReportedSpeed; 
  Integer lanes;
  
  // The following are used to determine addresses
  Integer streetNumberAtStart;
  Integer streetNumberAtEnd;
  * -> * RoadSegment inverseSegments;
}

/* 
 * A route is a plan to get from one location to another
 * It is built by algorithms that traverse the nodes and arcs of the map
 * taking into account speed, congestion, etc.
 */
class Route {
   // Ordered list of segments
   0..1 -> 1..* RoadSegment;

   // Time seconds at current flow speeds
   Integer estimatedTime; 
}

      

Load the above code into UmpleOnline

 

Coordination State Machine

This example has been built for the Comparing Modeling Approaches Workshop

Note that this file is too large for the 'Open In UmpleOnline' to work in most browsers. You will need to copy the text to the clipboard and paste it into UmpleOnline.

Example

// CoordinationStateMachine.ump
// This UML state machine diagram in Umple is for the
// bCMS car crash management system
// See http://cserg0.site.uottawa.ca/cma2012/CaseStudy.pdf
// and http://www.cs.colostate.edu/remodd/v1/content/repository-model-driven-development-remodd-overview
// Author: Timothy C. Lethbridge

/* 
 * State machine for co-ordination of the
 * crisis, as seen from one SC. If  
 * communication is operating properly the
 * other coordinators' state machines will
 * generally be in the same states and
 * substates.
 *
 * Modelled given Section 4 of the requirements
 * This is a mixin to class crisis.
 */
class Crisis {

  // Number of ms allowed to negotiate routes,  
  // establish credentials
  Integer timeoutInMs = 20000;
  
  // True if we are the initiator of the crisis 
  // request, false otherwise
  Boolean thisSideInitiator;
  Boolean thisSideInitiatorOfTermination;
  
  Boolean routeAgreedYet;
  
  // True of we are the PSC, false of we are  
  // the FSC
  Boolean police;

  // Top level state machine
  crisisCoordinationStage {
  
    // 0. When initiated the crisis is in 
    // noCrisis state
    // It has been created but not yet 
    // populated, awaiting initiation
    // of coordination and data..
    noCrisis {
      entry / {setThisSideInitiator(false);}
      // We are initiating and requesting the 
      // other side to respond
      initiateCrisis / {
        setThisSideInitiator(true);
        sendInitiateCrisisRequestToOtherSC(); 
        } -> establishingCommunication;

      // We are responding to a request from 
      // the other SC 
      receiveInitiateCrisisRequest -> 
        establishingCommunication;
    }
    
    // 1. Establish communication and 
    // identification when a crisis begins
    establishingCommunication {
      entry / {sendSecureCredentials();}
      secureCredentialsConfirmed -> 
        managingCrisis;
      
      // Return to idle after some delay if 
      // other side initiated and did not
      // respond. It might have been a 
      // hacker. Alternatively if there is a
      // real crisis, normal manual processes 
      // would happen.
      after (timeoutInMs) 
        [!isThisSideInitiator()] -> noCrisis;
    }

    // Managing crisis involves continually 
    // exchanging information
    // Negotiating or renegotiating routes and 
    // other crisis details
    // These are handled concurrently.
    managingCrisis {
      // A crisis is underway. We initially 
      // start with empty data
      // which will be populated over time
      entry / {initiateEmptyCrisis(); }
    
      // 2,4,5,6. Exchanging details about what 
      // each knows about the crisis
      // So the information each coordinator 
     // has is the same.
      exchangingDetails {
        // Requirement Scenario 2
        ourUpdateToCrisisData
          / {sendCrisisData();}
          -> exchangingDetails;
        receiveCrisisData
          / {updateCrisisData();}
          -> exchangingDetails;
        
        // Requirement Scenario 4
        ourVehicleDispatched
          / {sendVehicleDispatch();}
          -> exchangingDetails;
        receiveVehicleDispatched
          / {updateTheirDispatch();}
          -> exchangingDetails;
        
        // Requirement Scenario 5
        ourVehicleArrived
          / {sendVehicleArrived();}
          -> exchangingDetails;
        receiveVehicleArrived
          / {updateTheirArrival();}
          -> exchangingDetails;
        
        // Requirement Scenario 6
        ourVehicleMetObjective
          / {sendVehicleMetObjective();}
          -> exchangingDetails;
        receiveMetObjective
        / {updateTheirMetObjective();}
        -> exchangingDetails;
        
        // Requirement 5.a - breakdown
        breakdown / {dispatchAndUpdateOther();} 
          -> exchangingDetails;
        
        // Requirement 5.b - 
        // congestion/blockage
        // TO DO
        
        // Requirement 5.c escalate crisis - 
        // renegotiate routes
        // TO DO
        
        
      } // End of exchangingDetails
        //concurrent substate
      ||
      
      // 7. Both parties must agree to close 
      // the crisis; either can initiate
      crisisEndManagement {
      
        // Normal substate of crisisEndManagement - no end in sight yet
        ongoingCrisis {
        
          // We could initiate termination
          initiateTermination / {
            setThisSideInitiatorOfTermination(true);
            sendTerminationRequestToOtherSC();
            } -> waitingForTerminationConfirmation;
          receiveTerminationRequestFromOtherSC 
          -> 
            waitingForUserTerminationAgreement;
        }
        
        waitingForUserTerminationAgreement {
          do {confirmWithUserToTerminate();}
          confirmTermination -> tearDown;
          after (timeoutInMs) -> ongoingCrisis;
        }
            
        // Substate of where we are waiting for 
        // the other end to agree
        waitingForTerminationConfirmation {
          receiveTerminationConfirmation
            -> tearDown;
          
          // If the other side has not agreed, 
          // we keep the crisis active
          after (timeoutInMs) -> ongoingCrisis;
        }
        
        // End of crisis
        tearDown {
          entry / {deleteCrisis();}
          -> noCrisis;
        }
      } // End of crisisEndManagement 
        // concurrent substate
      ||

      // 3. Negotiating route plan
      negotiatingRoutePlan {
    
        // Negotiation happens in parallel with 
        // reporting timeout
        negotiation {
          entry / {setRouteAgreedYet(false);}
          informOfNumberOfVehicles
            / {sendNumberOfVehicles();}
            -> negotiation;
          receiveNumberOfVehicles [isPolice()] 
            -> planningRoute;
          receiveRouteProposal [!isPolice()]
            -> approvingRoute;
          
          // Requirement 3.3.a2.a1
          receiveNoAgreeableRoute
            [!isPolice()] -> noRouteAgreement;
          
          // The PSC plans the route -- only 
          // PSC can be in this state
          planningRoute {
             do {planRoute();}
             routePlanComplete
               / {sendPlanToFSC(); }
               -> awaitingRouteApproval;
             
             // Requirement 3.3.a2.a1 - no more 
             // possible routes
             noMoreRoutes
               / {sendNoMoreRoutesToFSC(); }
               -> noRouteAgreement;
          }

          // The FSC approves the route  -- 
          // only FSC can be in this state
          approvingRoute {
            do {userConfirmRouteAcceptable();}
            routeAcceptable
              / {sendApprovalToPSC();}
              -> routeAgreed;
            routeUnacceptable
              / {sendDisapprovalToFSC();}
              -> negotiation;
          }
          
          // The PSC awaits for approval from 
          // the FSC. Only the PSC can be in 
          // this state
          awaitingRouteApproval {
            receiveApprovalFromFSC
              -> routeAgreed;
            
            // Requirement 3.3.a - FSC 
            // disagrees
            receiveDisapprovalFromFSC / {
              addRouteToDisapprovedChoices(); 
              } -> planningRoute;
          }
          
          routeAgreed {
            entry / {setRouteAgreedYet(true);}
          }
          
          noRouteAgreement {
             // requirement 3.3.a2.a1
          }
        } // End of Negotiation concurrent 
          // substate of negotiatingRoutePlan
        ||
        managingTimeliness {
          timeAcceptable {
            // Requirement 3.a1. Negotiations 
            // are taking excessive time
            after (timeoutInMs)
              [!isRouteAgreedYet()]
              -> timeUnacceptable;
          }
          timeUnacceptable {
            // Although negotiations may yet 
            // complete, we are going to send
            // out our own vehicles because too 
            // much time has passed
            do {
              promptAndLogReasonForTimeout(); }
          }
        } // End of managingTimeiness 
          //concurrent substate of 
          // negotiatingRoutePlan
      } // End of NegotiatingRoutePlan 
        //concurrent substate
    } // End of Managing Crisis top level state
  } // End of crisisCoordinationStage state 
    // machine
} // End of state machine mixin for 
  // Crisis

      

Load the above code into UmpleOnline

 

Privacy and Risks

 

Risks in using Umple and UmpleOnline

License: All use of Umple and UmpleOnline is subject to the Umple MIT license. Please read it carefully, since it disclaims liability. This is not because we don't want to be 'good engineers' and take responsibility for work, rather it is because we are following the open source model, which allows a wide variety of people to modify Umple.

Risk due to support by hosting organizations: UmpleOnline is hosted at the University with funds from research grants. Should these research grants cease, support for Umple may cease unless others take over responsibility for hosting. Similarly, the code is hosted on Google Code. If Google decides to cease hosting projects for free, Umple would need to be hosted somewhere else.

Risk of deprecation, missing features and defects: It is possible that code which works today may cease working in the future. Development is performed by students and in the context of research. You will therefore find incomplete features and bugs. We encourage you to report new ones (and fix them) and to realize that you may need to work around the existing ones. That said, we do use test-driven development to maintain what we believe is a high level of quality.

Limitations of UmpleOnline: The purpose of UmpleOnline is purely to allow people to explore Umple and model-oriented programming, particularly in an educational context. UmpleOnline is not intended to be a commercial or open source development tool; this is one of the reasons why it is only capable of storing a single Umple file per user session. If you want to do serious development in Umple, with multiple files, you should download it.

Not certified for safety critical or mission critical use: At the current time Umple-generated code should not be used for mission-critical or safety critical uses, including software for any device that may pose a safety risk if it performs incorrectly, or software that would cause economic damage if it failed. We intend that, in time, Umple and tools like it will in fact help improve safety and reliability. But at the current time we have not subjected Umple to the rigorous validation it needs for such uses, and there are many known issues that would preclude such current use.

Need to apply best practices: Should you choose to use Umple for production use, it is critical that you follow rigorous software engineering practices including (but not limited to): Requirements analysis, careful design and thorough testing. See here for a list of Umple best practies.

 

Privacy: Saving of data in UmpleOnline

Models entered in UmpleOnline are automatically stored on servers at the University of Ottawa. Each time you type and pause for three seconds, each time you make an edit to a diagram, and each time you generate code, your data is saved. The data includes one or more .ump files, plus the data you have generated from those files (Java code etc.).

Data saved automatically in this way remains stored at the University of Ottawa for up to two days. This is so you can continue an editing session, even if you walk away from your computer for an extended period. We have an automated process that will normally delete such data after two days. However we reserve the right to record general statistics about the size of models and other uses of Umple tools before we delete such data.

If you choose 'Create a Bookmarkable URL' then your model is stored, indefinitely, subject to deletion rules described below. Such a file can be edited and deleted by anyone to whom you give the URL, or by anyone who guesses the URL.

If we detect abuse of UmpleOnline, we reserve the right to attempt to track the user using such tools as the originating IP address, and to block access from such an address or address range.

We do intend to install tools to survey users about their experiences with Umple. We will likely use external tools such as SurveyMoney for such surveys; people who complete such surveys would then be subject to the privacy rules of such external tools. Users would be requested to give informed consent prior to taking such a survey, and such informed consent would first be approved by the University of Ottawa's Research Ethics Board.

 

Sharing of personal data in UmpleOnline

The only data saved by UmpleOnline is the model you create, either graphically or textually or both. There is currently no login mechanism so there is no userid, name or other personal data associated with your model. We may impose a login requirement in the future, but in that case we would only store the minimum of data (loginID, your name, an encrypted salted password, and an email address for account confirmation, to contact you and to allow for password reset).

You may, however, embed (at your choice) confidential information in the code or models you write in UmpleOnline. It is important for you to realize that this information is accessible to others.

Since no userid is currently associated with UmpleOnline models, we have no way of determining who has saved which models at the current time. We cannot guarantee to be able to recover any file you may have 'lost'. Nor can we determine whether anyone else has looked at or modified your files.

 

Data deletion

You may delete your own model in UmpleOnline: Simply select all the text and delete it. To delete all records of generated code, it is suggested that you replace your model by a single line of code (such as class X {} and then generate code from it (generate code in all formats you have previously generated).

Staff at the University of Ottawa reserve the right to delete models for any of the following reasons:

 

Access and use by others

If somebody is able to guess the URL of your model, or you give it to them, then they can modify and delete your model. Important models should therefore be saved using other means. Instructions for how to do that are here.

 

Anonymity

There is currently no login mechanism to UmpleOnline so there is no way to trace users, as stated earlier. This may change in the future

Languages supported

Umple code can result in generation of various languages. Code from these languages can be inserted into Umple, or Umple can be inserted into code for the languages.

Syntax


// The generate clause can be used to generate multiple outputs
// The --override is used to say that subsequent generate statements will be ignored
generate : generate [=language:Java
    |Php
    |RTCpp
    |SimpleCpp
    |Ruby
    |Cpp
    |Json
    |StructureDiagram
    |Yuml
    |Violet
    |Umlet
    |Simulate
    |TextUml
    |Scxml
    |GvStateDiagram
    |GvClassDiagram
    |GvClassTraitDiagram
    |GvEntityRelationshipDiagram
    |Alloy
    |NuSMV
    |Papyrus
    |Ecore
    |Xmi
    |Xtext
    |Sql
    |Umple
    |UmpleSelf
    |USE
    |Test
    |SimpleMetrics
    |Uigu2] ( [=suboptionIndicator:-s
    |--suboption] " [**suboption] " )* ;

generate_path : generate [=language:Java
    |Php
    |RTCpp
    |SimpleCpp
    |Ruby
    |Cpp
    |Json
    |StructureDiagram
    |Yuml
    |Violet
    |Umlet
    |Simulate
    |TextUml
    |Scxml
    |GvStateDiagram
    |GvClassDiagram
    |GvClassTraitDiagram
    |GvEntityRelationshipDiagram
    |Alloy
    |NuSMV
    |Papyrus
    |Ecore
    |Xmi
    |Xtext
    |Sql
    |UmpleSelf
    |USE
    |test] " [**output] " [=override:--override
    |--override-all]? ( [=suboptionIndicator:-s
    |--suboption] " [**suboption] " )* ;

Umple Grammar

Below is the complete grammar for Umple . This page is generated automatically from the grammar used to parse Umple code.

Refer to the Grammar Notation section for more explanation of the EBNF syntax used here.



// The master source of this first part of the Umple grammar is available at
// http://code.google.com/p/umple/source/browse/trunk/cruise.umple/src/umple_core.grammar
// The html rendering is generated from the master and appears in the Umple User manual
// at page http://grammar.umple.org

// Copyright: All contributors to the Umple Project
// This file is made available subject to the open source license found at:
// http://umple.org/license

// The core of umple is a "program". This is the grammar's 'start symbol'
// Comments and lone semicolons are ignored
program- : [[useProgram]] | [[umpleProgram]]


umpleProgram- : ( [[comment]] | [[directive]] | ; )*


// Directives are the top-level items in an umple file. See manual page TypesofDirectives
// A directive is either used to configure the system or else is
// an actual entity of the system to be modelled or generated
directive- : [[glossary]]
    | [[generate]]
    | [[distribute]]
    | [[generate_path]]
    | [[filter]]
    | [[useStatement]]
    | [[namespace]]
    | [[tracerDirective]]
    | [[entity]]
    | [[debug]]
    | [[strictness]]
    | [[toplevelExtracode]]
    | [[toplevelException]]


// A glossary item is used to fine tune pluralization during code generation
glossary : glossary { [[word]]* }

word : [singular] : [plural] ;

distribute :distributable [=distributeTech:RMI
    |WS]? [=distributePattern:0
    |1
    |2
    |3]? [=distributeVal:on
    |off
    |forced] ;

// A high level of strictness will cause warnings to be issued when base language code
// is found, where it might not have been intended. Strictness can also be used
// To either suppress certain messages, or to declare that they should be present.
// NOTE: This is currently under development
strictness- : strictness ( [=strictness:modelOnly|noExtraCode|none]
    | [[strictnessMessage]] ) ;

strictnessMessage : [=message:allow|ignore|expect|disallow] [messageNumber]


// The generate clause can be used to generate multiple outputs
// The --override is used to say that subsequent generate statements will be ignored
generate : generate [=language:Java
    |Php
    |RTCpp
    |SimpleCpp
    |Ruby
    |Cpp
    |Json
    |StructureDiagram
    |Yuml
    |Violet
    |Umlet
    |Simulate
    |TextUml
    |Scxml
    |GvStateDiagram
    |GvClassDiagram
    |GvClassTraitDiagram
    |GvEntityRelationshipDiagram
    |Alloy
    |NuSMV
    |Papyrus
    |Ecore
    |Xmi
    |Xtext
    |Sql
    |Umple
    |UmpleSelf
    |USE
    |Test
    |SimpleMetrics
    |Uigu2] ( [=suboptionIndicator:-s
    |--suboption] " [**suboption] " )* ;


generate_path : generate [=language:Java
    |Php
    |RTCpp
    |SimpleCpp
    |Ruby
    |Cpp
    |Json
    |StructureDiagram
    |Yuml
    |Violet
    |Umlet
    |Simulate
    |TextUml
    |Scxml
    |GvStateDiagram
    |GvClassDiagram
    |GvClassTraitDiagram
    |GvEntityRelationshipDiagram
    |Alloy
    |NuSMV
    |Papyrus
    |Ecore
    |Xmi
    |Xtext
    |Sql
    |UmpleSelf
    |USE
    |test] " [**output] " [=override:--override
    |--override-all]? ( [=suboptionIndicator:-s
    |--suboption] " [**suboption] " )* ;


// Use statements allow incorporation of other Umple files. See UseStatements
useStatement : use [use] ;


toplevelExtracode : top [top] [[moreCode]]


// Namespaces divide the code into logical groups. See NamespaceDirectives
namespace- : namespace [namespace] ;


// The main top level elements to be found in an Umple file
entity- : [[classDefinition]]
    | [[traitDefinition]]
    | [[fixml]]
    | [[interfaceDefinition]]
    | [[externalDefinition]]
    | [[associationDefinition]]
    | [[associationClassDefinition]]
    | [[stateMachineDefinition]]
    | [[templateDefinition]]


// Comments follow the same conventions as C-family languages. UmpleComments
comment- : [[inlineComment]] | [[multilineComment]]

inlineComment- : // [**inlineComment]

multilineComment- : /* [**multilineComment] */


// The Debug statement turns on debugging in code generation. For developer use only
debug- : [=debug] ;


// Instructs a class or method to be abstract
abstract- : [=abstract] ;

// The master of this second part of the Umple grammar is available at
// http://code.google.com/p/umple/source/browse/trunk/cruise.umple/src/umple_classes.grammar

// Copyright: All contributors to the Umple Project
// This file is made available subject to the open source license found at:
// http://umple.org/license

// Classes are the most common elements in Umple.
// See user manual page ClassDefinition
classDefinition : class [name] { [[classContent]]* }


//The external keyword declares a class that is defined in a different
// compilation unit
externalDefinition : external [=interface]? [name] { [[classContent]]* }


// An Interface can only contain method. See interfaceDefinition
interfaceDefinition : interface [name] { [[depend]]* [[interfaceBody]] }


// Associations can be declared outside the body of classes.
// See user manual page IndependentlyDefinedAssociations
associationDefinition : association [name]? { ([[comment]] | [[association]])* }


// Associations that would be many-many can also become full-fledged classes too
// See user manual page AssociationClassDefinition
associationClassDefinition : associationClass [name] { [[associationClassContent]]* }


// The following items can be found inside the body of classes or association classes
classContent- : [[comment]]
    | [[distributable]]
    | [[proxyPattern]]
    | [[classDefinition]]
    | [[trace]]
    | [[emitMethod]]
    | [[templateAttributeDefinition]]
    | [[primitiveDefinition]]
    | [[portDefinition]]
    | [[portBindingDefinition]]
    | [[position]]
    | [[displayColor]]
    | [[abstract]]
    | [[keyDefinition]]
    | [[softwarePattern]]
    | [[depend]]
    | [[symmetricReflexiveAssociation]]
    | [[attribute]]
    | [[stateMachine]]
    | [[activeMethodDefinition]]
    | [[inlineAssociation]]
    | [[concreteMethodDeclaration]]
    | [[constantDeclaration]]
    | [[modelConstraint]]
    | [[invariant]]
    | ;
    | [[exception]]
    | [[extraCode]]

associationClassContent- : [[comment]]
    | [[classDefinition]]
    | [[position]]
    | [[displayColor]]
    | [[invariant]]
    | [[softwarePattern]]
    | [[depend]]
    | [[singleAssociationEnd]]
    | [[stateMachine]]
    | [[attribute]]
    | [[association]]
    | [[inlineAssociation]]
    | ;
    | [[extraCode]]



// Interfaces: Note that if the format of an abstractMethodDeclaration is not
// followed, then the body will extraCode and passed to the base language
// See user manual page interfaceDefinition
interfaceBody- : [[interfaceMemberDeclaration]]*

interfaceMemberDeclaration : [[comment]]
    | [[constantDeclaration]]
    | [[constantDeclarationDeprecated]]
    | [[abstractMethodDeclaration]]
    | [[position]]
    | [[displayColor]]
    | [[isA]]
    | [[distributableInterface]]
    | [[exception]]
    | [[extraCode]]

distributableInterface : [[distributable]]

// Constants in interfaces (e.g. const String ACONSTANT="aValue";)
// Note: in Classes const is a modifier
constantDeclarationDeprecated : constant [[typedName]] (= [**value])? ;

constantDeclaration : const [[typedName]] (= [**value])? ;



distributable- : [=distributable:distributable] [=distributeTech:RMI|WS]? ;

proxyPattern- : [=proxyPattern:proxyPattern] ;

moreCode- : [[codeLangs]] { [**code] }

codeLangs- : ([=codeLang:Java
    |RTCpp
    |SimpleCpp
    |Cpp
    |Php
    |Ruby
    |Alloy
    |UmpleSelf] ( , [=codeLang:Java
    |Alloy
    |RTCpp
    |SimpleCpp
    |Cpp
    |Php
    |Ruby
    |UmpleSelf] )* )?


// Methods: The code in concrete methods is passed to the base language
// See user manual page MethodDefinition
concreteMethodDeclaration : [=modifier:public|protected|private]? [=static]? [type]? [[methodDeclarator]] [[methodThrowsExceptions]]? [[methodBody]]
    | [=modifier:public|protected]? [=abstract] [type]? [[methodDeclarator]] [[methodThrowsExceptions]]? ;

abstractMethodDeclaration : [type] [[methodDeclarator]] ;

methodBody- : ( [[codeLangs]] { ( [[precondition]] | [[postcondition]] )* [**code] } )+

methodDeclarator : [methodName] [[parameterList]]

methodThrowsExceptions : throws [~exception] ( , [~exception] )*

parameterList : ( ([[parameter]] ( , [[parameter]] )* )? )

parameter : [[typedName]]


// Details of associations: See manual page AssociationDefinition

association : [=modifier:immutable]? [[associationEnd]] [=arrow:--
    |->
    |<-
    |><
    |<@>-
    |-<@>] [[associationEnd]] ;

symmetricReflexiveAssociation : [[multiplicity]] self [roleName] ;

inlineAssociation : [=modifier:immutable]? [[inlineAssociationEnd]] [=arrow:--
    |->
    |<-
    |><
    |<@>-
    |-<@>] [[associationEnd]] ;

inlineAssociationEnd : [[multiplicity]] [~roleName]? [[isSorted]]?

singleAssociationEnd : [[multiplicity]] [type] [~roleName]? ;

// note: gpIdentifier = general parameter identifier
associationEnd : [[multiplicity]] [=gpIdentifier:%]? [type] [~roleName]? [[isSorted]]?

multiplicity- : [!lowerBound:\d+|[**]] .. [!upperBound:\d+|[**]] | [!bound:\d+|[**]]

isSorted- : sorted { [priority] }


// Details of attributes. See user manual page AttributeDefinition
attribute : [[simpleAttribute]]
    | [[autouniqueAttribute]]
    | [[derivedAttribute]]
    | [[complexAttribute]]

simpleAttribute- : [=gpIdentifier:%]? [~name] ;

autouniqueAttribute- : [=autounique] [~name] ;

derivedAttribute- : [=modifier:immutable
    |settable
    |internal
    |defaulted
    |const
    |fixml]? [[typedName]] = ( [[moreCode]] )+

complexAttribute- : [=unique]? [=lazy]? [=modifier:immutable
    |settable
    |internal
    |defaulted
    |const
    |fixml]? [[typedName]] (= [**value])? ;



// Keys are used to define quality and hash codes, plus Sql keys.
// See user manual page KeysforEqualityandHashing
defaultKey : key { }

key : key { [keyId] ( , [keyId] )* }


// Depend clause. See user manual page Dependclause
depend- : depend [depend] ;


// Anything inside a class that is not parsable by Umple is passed on to the base language
// compiler. To raise warnings when this occurs, use the strictness directive.
extraCode- : [**extraCode]


list- : [!list:\[\s*\]]

typedName- : [type]? [[list]]? [~name]

traitDefinition : trait [name] [[traitParameters]]? { [[traitContent]]* }

traitContent- : [[requiredModelElements]]
    | [[comment]]
    | [[traitDefinition]]
    | [[trace]]
    | [[position]]
    | [[displayColor]]
    | [[abstract]]
    | [[keyDefinition]]
    | [[softwarePattern]]
    | [[depend]]
    | [[symmetricReflexiveAssociation]]
    | [[attribute]]
    | [[stateMachine]]
    | [[inlineAssociation]]
    | [[concreteMethodDeclaration]]
    | [[abstractMethodDeclaration]]
    | [[constantDeclaration]]
    | [[invariant]]
    | ;
    | [[exception]]
    | [[extraCode]]

traitParameters : < [[traitFullParameters]] ( , [[traitFullParameters]] )* >

traitFullParameters : [~parameter] ([[traitParametersInterface]])?

traitParametersInterface- : isA [~tInterface]( & [~tInterface])*

requiredModelElements : require ([[requiredState]] | [[requiredEvent]])

requiredState : [smName] ;

//.[~stateName](.[~stateName])* ;
requiredEvent : [smName] ( ( [parameter] ( , [parameter] )* )? ) ;

//.[~stateName](.[~stateName])*


//iE = Include Exclude
AllInclusionExclusionAlias- : [[InclusionExclusionAlias]] ( , [[InclusionExclusionAlias]] )*

InclusionExclusionAlias- : [[functionIncludeExcludeAlias]] | [[StateMachineIncludeExcludeAlias]]

functionIncludeExcludeAlias- : [[functionInExAlias]] ( , [[functionInExAlias]] )*

functionInExAlias- : [[functionAliasName]] | [[iEFunction]] | [[traitAppliedParameters]]

iEFunction : [=modifier:+|-]? [~methodName] [[iEParameterList]]

iEParameterList : ( ( [parameter] ( , [parameter] )* )? )

functionAliasName : [=modifier:+]? ( ( [~smName]
    | [!smPattern:\d+|[**]]) .)? [~methodName] [[iEParameterList]] as [[IEVisiAlias]]


IEVisiAlias- : [[IEVisiAlias1]] | [[IEVisiAlias2]] | [[IEVisiAlias3]]

IEVisiAlias1- : [=iEVisibility:public|private|protected] [~aliasName]

IEVisiAlias2- : [=iEVisibility:public|private|protected]

IEVisiAlias3- : [~aliasName]

traitAppliedParameters : [~pName] = [~rName]


StateMachineIncludeExcludeAlias- : [[ StateMachineInExAlias]] ( , [[StateMachineInExAlias]] )*

StateMachineInExAlias- : [[StateMachineAliasName]] | [[iEStateMachine]]

//| [[StateMachineTransitionAlias]]
StateMachineAliasName : ([=iEStateMachineModifier:+])? [~smName] ([[StateNames]])? as [~smDesName] ([[DesStateNames]])?

StateNames : . [~sName] ( [[StateNamesPassing]] )*

DesStateNames :[[StateNames]]

StateNamesPassing : [[StateNames]]

//iEStateMachine : [=iEStateMachineModifier:+|-] [~smName] [[StateNames]]?
iEStateMachine : [=modifier:+|-] [~smName] ( [[StateNames]] ( ( [[iEParameterList]] [[guardOption]]? )
    | ( . [[guardOption]] ) )? )?

guardOption : [[guard]] | []

//This is for events in state machines
//StateMachineTransitionAlias : ( [~smName] | [!smPattern:\d+|[*]]) . [~eventName] [[iEParameterList]] as [~AliasName]
//This is Umple's grammar for parsing fixml documents
fixml : [[fixmlDefinition]] | [[fixmComment]] | [[fixmlDoc]]

fixmlDoc : <! [**value] >

fixmComment : <?xml [[tagDefinition]]* ?>

fixmlDefinition : <FIXML> [[fixmlContent]]* </FIXML>

fixmlContent : [[endContent]] | [[ extendContent ]]

endContent : < [~name] ( [[tagDefinition]] )* />

extendContent : < [~name] ( [[tagDefinition]] )* > ( [[endContent]]
    | [[extendContent]]
    | [[attContent]])* < ( / ) [~name] >

tagDefinition : [name] = "[**value]"

attContent : < [~name] > [**value:\<] < ( / ) [~name] >

// The master of this second part of the Umple grammar is available at
// http://code.google.com/p/umple/source/browse/trunk/cruise.umple/src/umple_patterns.grammar

// Copyright: All contributors to the Umple Project
// This file is made available subject to the open source license found at:
// http://umple.org/license

softwarePattern- : [[isA]] | [[singleton]] | [[immutable]] | [[keyDefinition]] | [[codeInjection]]


// Generalization and inheritance isAclause
isA- : [[singleIsA]] | [[multipleIsA]]

singleIsA- : isA [[isAName]] ( , isA [[isAName]] )* ;

multipleIsA- : isA [[isAName]] ( , [[isAName]] )* ;

isAName- : " [**extendsNames] " [[gTemplateParameter]]?
    | [extendsName] [[gTemplateParameter]]?


gTemplateParameter : < [[AllInclusionExclusionAlias]] >


// A class that can have only one instance SingletonPattern
singleton- : [=singleton] ;


// A class that can't be modified when created ImmutablePattern
immutable- : [=immutable] ;


// For equality and hashing KeysforEqualityandHashing
keyDefinition- : [[defaultKey]] | [[key]]


// Aspect oriented code injection: BeforeandAfterStatements
codeInjection- : [[beforeCode]] | [[afterCode]]


parameterTypes : [parameterType] (, [parameterType])*

parameterListing : ( ([[parameterTypes]])? )


injectionOperation : [operationName] ([[parameterListing]])?


beforeCode : before ([=operationSource:custom
    |generated
    |all])? [[injectionOperation]] ( , [[injectionOperation]] )* ([[codeLang]] [[codeLangs]])? { [**code] } ( [[moreCode]] )*

afterCode : after ([=operationSource:custom
    |generated
    |all])? [[injectionOperation]] ( , [[injectionOperation]] )* ([[codeLang]] [[codeLangs]])? { [**code] } ( [[moreCode]] )*

// The master of this part of the Umple grammar is available at
// http://code.google.com/p/umple/source/browse/trunk/cruise.umple/src/umple_state_machines.grammar

// Copyright: All contributors to the Umple Project
// This file is made available subject to the open source license found at:
// http://umple.org/license

// State machine elements in Umple. See user manual page: BasicStateMachines
stateMachineDefinition : statemachine [=queued]? [=pooled]? [name] { [[state]]* }

stateMachine : [[enum]]
    | [[inlineStateMachine]]
    | [[referencedStateMachine]]
    | [[activeDefinition]]


activeDefinition : [=active] [[codeLangs]] [name]? [[moreCode]]+


//Issue 148
inlineStateMachine : [=queued]? [=pooled]? [~name] { ( [[comment]]
    | [[state]]
    | [[trace]]
    | [=||]
    | [[standAloneTransition]])* }

referencedStateMachine : [name] as [definitionName] ( { [[extendedStateMachine]] } | ; )


//Issue 547 and 148
extendedStateMachine# : ( [[comment]]
    | [=changeType:+| - |- |*]? [[state]]
    | [[standAloneTransition]] )*


// An enum is a state machine that has no events
// stateName is prefixed with ~ to match alphanumeric names only.
// This is needed to solve issue 399, which is cause when a terminating } is parsed as part of the statename.
enum : [~name:key] { [~stateName]? (, [~stateName])* }


state : [=final]? [stateName] { [[stateInternal]]* }


//Issue 547 and 148
stateInternal-# : [[comment]]
    | [=changeType:+| - |- |*]? [[stateEntity]]
    | [[standAloneTransition]] |[**extraCode]

stateEntity- : [=||]
    | [[entryOrExitAction]]
    | [[autoTransition]]
    | [[transition]]
    | [[activity]]
    | [[state]]
    | [[trace]]
    | ;


autoTransition : [[activity]]? [[autoTransitionBlock]]


// Autotransitions have no event. The transition is immediately taken
// or taken after the do activity ends[[guard]]? -> [[action]]?
// The action can come before or after the arrow
autoTransitionBlock- : [[guard]]? ( [[action]] -> | -> [[action]] | -> ) [stateName] ;


// A transition guard can come before or after the arrow
// The order of guard and event definition can also be interchanged
transition : ( [[eventDefinition]] [[guard]]
    | [[guard]] [[eventDefinition]]
    | [=unspecified]? [[guard]]
    | [[eventDefinition]])? ( [[action]] ->
    | -> [[action]]
    | -> ) [stateName] ;


//Issue148
standAloneTransition : ( [[eventDefinition]] [[guard]]
    | [[guard]] [[eventDefinition]]
    | [=unspecified]? [[guard]]
    | [[eventDefinition]])? [~fromState] ( [[action]] ->
    | -> [[action]]
    | -> ) [~toState] ;


eventDefinition- : [[afterEveryEvent]] | [[afterEvent]] | [~event] ( [[parameterList]] )?


// The timer in a timed event can be an number, variable, function() or function(num)
afterEveryEvent- : afterEvery ( [!timer:[+*/a-zA-Z0-9_\.-]+(\([0-9\.]*\))?] )

afterEvent- : after ( [!timer:[+*/a-zA-Z0-9_\.-]+(\([0-9\.]*\))?] )


// An action can be executed on a transition, or on entry or exit
action : / [[moreCode]]+

entryOrExitAction : [=type:entry|exit] / [[moreCode]]+


// A do activity is long-lasting and can be interrupted
activity : do [[moreCode]]+


guard : [ [[constraint]] ]

// The master of this part of the Umple grammar is available at
// http://code.google.com/p/umple/source/browse/trunk/cruise.umple/src/umple_traces.grammar

// Copyright: All contributors to the Umple Project
// This file is made available subject to the open source license found at:
// http://umple.org/license

// Trace capabilities of the MOTL sublanguage of Umple.
// See user manual page: ModelOrientedTracingLanguage(MOTL)

// ======= TRACER
// ======= grammar rules - The tool to output the trace: Tracers
tracerDirective : tracer [tracerType] [[tracerOptions]] ;

tracerOptions- : [[logConfig]]* [[traceMessageHeader]]? [tracerArgument]?

logConfig : (root = [rootLevel])
    | (monitorInterval = [monitorInterval])
    | ( [logLevel] ( , [logLevel] )* = [logAppender] ( , [logAppender] )* )

traceMessageHeader : [=switch:on|off] : [option] ( , [option] )*


// ======= TRACE
// ======= grammar rules

trace : [[traceDirective]] | [[traceCase]]


traceDirective : trace [[Prefix]]? [[traceEntity]] [[Postfix]] ;


traceEntity- : [traceEntity] (()? ())? ( , [traceEntity] (()? ())? )*


Prefix : [[PrefixOption]] ( , [[PrefixOption]] )*

PrefixOption- : [=option:set|get|in|out|entry|exit|cardinality|add|remove]


Postfix- : ( [[traceCondition]]
    |[[traceFor]]
    |[[tracePeriod]]
    |[[traceDuring]]
    |[[traceLevel]]
    |[[traceRecord]]
    |[[executeClause]]
    |[[logLevel]]
    |[[traceCaseActivation]] )*

traceCondition : [=conditionType:where|until|after|giving]? [ [[constraintToken]] ]

traceFor- : for [traceFor]

tracePeriod- : period [tracePeriod]

traceDuring- : during [traceDuration]

traceLevel- : level [traceLevel]

traceRecord- : record [[recordEntity]]

recordEntity- : ( only )? ( " [**recordString] " | [traceRecord] ) ( , [traceRecord] )*

logLevel- : logLevel [[logLevelOption]] ( , [[logLevelOption]] )*

logLevelOption- : [=logLevel:trace
    |debug
    |info
    |warn
    |error
    |fatal
    |all
    |finest
    |finer
    |fine
    |config
    |warning
    |severe]

executeClause- : execute { [**traceExecute] }


traceCase : [[traceCaseDef]] | [[traceCaseActivation]] | [[traceCaseDeactivation]]

traceCaseDef- : tracecase [tracecase_name] { [[traceDirective]]* }

traceCaseActivation- : activate [tracecase_act_name] (onAllObjects | onThisThreadOnly)? ;

traceCaseDeactivation- : deactivate [tracecase_deact_name] onThisObject [[deActivateFor]]? ;

deActivateFor- : for [deactivate_for]



//--------- Old rules (left as reference) ---------
//++Tracer
//traceType : tracer [tracerType] ( [=onoff:on|off] : [[tracerOptions]] ( , [[tracerOptions]] )* )* ( [=verbisty:verbose] )? ( [tracerArgument] )* [[log4jConfig]]* ([[tracerOptions]])* ;
//traceType : tracer [tracerType] ( , [tracerType] )* [[log4jConfig]]* ([[tracerOptions]])* ;
//traceType : tracer [=tracerType:Console|File|String|Visual] ( , [=tracerType:Console|File|String|Visual] )* ( [=onoff:on|off] : [[tracerOptions]] ( , [[tracerOptions]] )* )* ( [=verbisty:verbose] )? ( [tracerArgument] )* ;
//tracerOptions- : [[tracerOn]]? [=option:Time|time|Thread|thread|File|file|Line|line|Trace|trace|Trigger|trigger|TraceFile|tracefile|TraceLine|traceline|TriggerLine|triggerline|TriggerFile|triggerfile|Class|class|Object|object|Operation|operation|Name|name|Value|value] [=option:Time|time|Thread|thread|File|file|Line|line|Trace|trace|Trigger|trigger|TraceFile|tracefile|TraceLine|traceline|TriggerLine|triggerline|TriggerFile|triggerfile|Class|class|Object|object|Operation|operation|Name|name|Value|value]*
//tracerOn : on:|off:
//log4jConfig : (root = [rootLevel]) | (monitorInterval = [monitorInterval]) | (OPEN_ROUND_BRACKET) [log4jLevel] ( , [log4jLevel] )* (CLOSE_ROUND_BRACKET) = (OPEN_ROUND_BRACKET) [log4jAppender] ( , [log4jAppender] )* (CLOSE_ROUND_BRACKET)
//--------------------------------------------------
// The master of this part of the Umple grammar is available at
// http://code.google.com/p/umple/source/browse/trunk/cruise.umple/src/umple_constraints.grammar

// Copyright: All contributors to the Umple Project
// This file is made available subject to the open source license found at:
// http://umple.org/license

// Constraints in Umple.
// This is currently under development. Constraint capability is being
// developed in agile increments. The first step, described below,
// allows limiting the values of attributes. Code generation is not currently enabled.
// Constraints may appear in classes (including association classes)
// as well as in states.
precondition : [ [name]? pre : [[constraint]] ]

postcondition : [ [name]? post : [[constraint]] ]


invariant : [ ([name] :)? ([[constraint]]) ]

constraintToken : [[constraint]]


// A constraint is an expression optionally be surrounded in round brackets or negated
constraint- : [[constraintBody]] [[linkingOp]]? | [[constraintExpr]] [[linkingOp]]?

negativeConstraint : ( ! | not ) ( [[constraintName]] | [[constraint]] )


// A constraint body is a constraint expression (possibly with a linking operator such as && or ||).
constraintBody : ( [[constraint]] )

linkingOp- : ( [=andOp:and|&&|&]
    | [[equalityOperator]]
    | [!orOp:(or|\Q||\E)] ) [[linkingOpBody]]

linkingOpBody : [[constraint]]

constraintExpr- : [[statemachineExpr]]
    | [[stringExpr]]
    | [[boolExpr]]
    | [[numExpr]]
    | [[associationExpr]]
    | [[genExpr]]
    | [[loneBoolean]]
    | { [!fakeContraint:[^\n]+] }


loneBoolean : [[constraintVariable]]


//must be a boolean //fixing is here!!!
boolExpr : [[constraintVariable]] [[equalityOperator]] [[boolLiteral]]
    | [[boolLiteral]] [[equalityOperator]] [[constraintVariable]]
    | [[boolLiteral]]

boolLiteral : [=literal:true|false]


//must be string
stringExpr : [[stringExprOperator]] | [[stringExprPlain]]

stringExprPlain- : [[constraintVariable]] [[equalityOperator]] [[stringLiteral]]
    | [[stringLiteral]] [[equalityOperator]] [[constraintVariable]]

stringExprOperator- : [[stringComplexExpression]] [[equalityOperator]] [[stringComplexExpression]]
    | [[stringComplexExpression]] [[equalityOperator]] [[stringName]]
    | [[stringName]] [[equalityOperator]] [[stringComplexExpression]]

stringLiteral- : " [**quote] " | ' [**quote] '

stringName- : [[stringLiteral]] | [[constraintVariable]]

stringComplexExpression : [[stringPlusOperator]]

stringPlusOperator- : [[stringName]] ( [=concat:+] [[stringPlusOperator]] )?


//basically the "other" catagory, contains everything that can be equal to something else
genExpr : [[constraintVariable]] [[equalityOperator]] [[constraintVariable]]


//for floats, doubles and ints
numExpr : [[numberExpression1]]
    | [[numberExpression2]]
    | [[numberExpression3]]
    | [[numberExpression4]]

numberExpression1- : ( [[arithmeticCall]]
    | [[numberName]] ) [[ordinalOp]] ( [[arithmeticCall]]
    | [[numberName]] )

numberExpression2- : ( [[arithmeticCall]]
    | [[constraintVariable]] ) [[equalityOperator]] ( [[arithmeticCall]]
    | [[numberLiteral]] )

numberExpression3- : ( [[arithmeticCall]]
    | [[numberLiteral]] ) [[equalityOperator]] ( [[arithmeticCall]]
    | [[constraintVariable]] )

numberExpression4- : ( [[arithmeticCall]]
    | [[numberLiteral]] ) [[equalityOperator]] ( [[arithmeticCall]]
    | [[numberLiteral]] )

numberLiteral- : [!number:-?[0-9]+([\\.][0-9]+)?]

numberName- : [[numberLiteral]] | [[constraintVariable]]

arithmeticCall : ( ( [[lowArithmeticOperatorCall]]
    | [[highArithmeticOperatorCall]] ) )

lowArithmeticOperatorCall- : ( [[highArithmeticOperatorCall]]
    | [[arithmeticResolve]] )? [=operator:+|-|>>|<<] ( [[arithmeticCall]]
    | [[arithmeticResolve]] )

highArithmeticOperatorCall- : [[arithmeticResolve]] [=operator:*|/|^|%] ( [[highArithmeticOperatorCall]]
    | [[arithmeticResolve]] )

arithmeticResolve- : ( [[arithmeticCall]] ) | [[numberName]]


equalityOperator- : [=equalsOp:==|equals] | [=notequalsOp:!=|/=|=!|=/=]

ordinalOp- : [=greaterOp:greater|>=|=>|=>=]
    | [=lessOp:less|<=|=<|=<=]
    | [=moreOp:larger|>]
    | [=smallerOp:smaller|<]


associationExpr : [[constraintVariable]] [[associationOperators]] [[associationLiteral]]

associationOperators- : [=firstOp:cardinality|has] ( [[ordinalOp]] | [[equalityOperator]] | [=all] )?

associationLiteral : [[constraintParameter]] ( , [[associationLiteral]] )?


statemachineExpr : [[constraintVariable]] [[statemachineOperators]] [[statemachineLiteral]]

statemachineOperators- : [=isInOp:is|state] [=ignore:==|in]
    | [=isNotInOp:is|state] ( [=ignore:!=]
    | [=ignore:not] [=ignore:in] )

statemachineLiteral- : [=state]? [~stateName]


constraintVariable- : [[negativeConstraint]] | [[constraintName]]

constraintName : [=new]? [!name:[a-zA-Z_][a-zA-Z0-9_-]*] [[constraintIndexOperator]]* [[constraintParameterList]]? [[constraintScopeOperator]]?

constraintIndexOperator- : [ [!index:[0-9]+] ]

constraintScopeOperator : ( . | -> ) [[constraintVariable]]

constraintParameterList : ( ([[constraintParameter]] ([=comma:,] [[constraintParameter]])*)? )

constraintParameter : [=boolLit:true|false]
    | [[stringLiteral]]
    | [[constraintVariable]]
    | [[numberLiteral]]


modelConstraint- : [ model : [[modelConstraintBody]] ]

modelConstraintBody : ( [[modelConstraintBody]] ) [[modelLinkingOp]]?
    | [[modelExpr]] [[modelLinkingOp]]?

modelLinkingOp : ( [=and:&|&&|and|,] | [!or:([|][|]?|or|;)] ) [[modelConstraintBody]]

modelExpr : [~source]? [[modelRelationOp]] [~target]

modelRelationOp- : [[modelRelationOpAssociation]]
    | [[modelRelationOpAttribute]]
    | [[modelRelationOpInheritance]]

modelRelationOpInheritance : [=subclass:isA]
    | [=subclass:subclass|child|>>] ( of )?
    | [=subclass:inherits] ( from )?
    | [=superclass:parent|superclass|<<] ( of )?

modelRelationOpAttribute : [=op:has] ( attribute | attr )? [=classification:named|of]?

modelRelationOpAssociation : [[modelRelationAssociationEnd]]? [=op:--
    |->
    |<-
    |-<@>
    |<@>-] [[modelRelationAssociationEnd]]?

modelRelationAssociationEnd : [!bound:(\d+|[**])] ( .. [!bound:(\d+|[**])] )?



// NOTE: Additional grammar parts deleted while testing is ongoing.
// The master of this part of the Umple grammar is available at
// http://code.google.com/p/umple/source/browse/trunk/cruise.umple/src/umple_structure.grammar
//@author Ahmed M.Orabi {@link ahmedvc@hotmail.com}
//@author Mahmoud M.Orabi {@link mahmoud_3rabi@hotmail.com}

primitiveDefinition : primitive [name] { [[primitiveBody]]* }

primitiveBody- : [[isA]] | [[constraint]]


// Port Definition
portName : ( [~classname] . )? [name]

portMultiplicity : [!portMultiplicity:\[[0-9]+\]]


typedPortName : [~type]? [~portName] [[portMultiplicity]]?

portDefinition : [=modifier:public
    |protected
    |private]? [=inverse:conjugated]? [=direction:in
    |out
    |port] [[typedPortName]] ;


// Port Connectors
portBindingDefinition : ( [~fromClassname] . )? [fromPort] -> ( [~toClassname] . )? [toPort] [[bindinHandler]]

bindinHandler : { [**code] } | ;


// Port Watchlist Definition
portWatch- : ( [[constraintList]] | [[comment]] )*


// Active Method Definition
activeMethodDefinition : [[portWatch]]? [=modifier:public
    |protected
    |private]? [type]? [=activeType:atomic
    |synchronous
    |intercept]? [=active] [[activeMethodDeclarator]] [[activeMethodBody]]+

activeMethodDeclarator : [~methodName] [[parameterList]]?


//activeMethodBody : [[activeDirectionHandler]] { ( [[activeTrigger]] )* [**code] }
activeMethodBody : [[activeDirectionHandler]]? { ( [[comment]] | [[activeTrigger]] | [**code] )* }

activeDirectionHandler : [=direction:forward|inverse] ( , [=direction:forward|inverse] )*


activeTrigger : [[hitchConstraint]]? [[constraintList]]? [=trigger:/] [[activeTriggerBody]] [[thenDefinition]]? [[resolveDefinition]]?

activeTriggerBody- : ( [[deferredList]] | [[activeTriggerDefinition]] )

deferredList : [ [[activeTriggerDefinition]] ( , [[activeTriggerDefinition]] )* ]

activeTriggerDefinition- : [[anonymousTriggerBody]] | [[invoke]]


thenDefinition : .then ( [[anonymousTriggerBody]]? )

resolveDefinition : .resolve ( [[anonymousTriggerBody]]? )


hitchConstraint : [=clause:after|poll] ( [timer] )

constraintList : [ [[basicConstraint]] ( , [[basicConstraint]] )* ]

basicConstraint- : [[timeConstraint]] | [[messageConstraint]] | [[constraint]]

timeConstraint : [=clause:latency|period|timeout] ( [timer] )

messageConstraint : [=clause:priority] ( [priorityValue] )

invoke : ( [~classname] . )? [name] ( ( [parameter] ( , [parameter] )* )? ) ;

anonymousTriggerBody : { [**code] }


// The master of this part of the Umple grammar is available at
// http://code.google.com/p/umple/source/browse/trunk/cruise.umple/src/umple_template.grammar
//@author Ahmed M.Orabi {@link ahmedvc@hotmail.com}
//@author Mahmoud M.Orabi {@link mahmoud_3rabi@hotmail.com}

templateDefinition : template [name] { [[templateContent]]* }

templateContent- : [[comment]]
    | [[emitMethod]]
    | [[templateAttributeDefinition]]
    | [[trace]]
    | [[position]]
    | [[displayColor]]
    | [[abstract]]
    | [[keyDefinition]]
    | [[softwarePattern]]
    | [[depend]]
    | [[symmetricReflexiveAssociation]]
    | [[attribute]]
    | [[templateAttribute]]
    | [[stateMachine]]
    | [[inlineAssociation]]
    | [[concreteMethodDeclaration]]
    | [[constantDeclaration]]
    | [[invariant]]
    | ; |[[exception]]
    | [[extraCode]]



templateAttributeDefinition : [[templateName]] [[templateAttribute]]

templateName : ( [~classname] . )? [name] [[templateParameters]]?

templateParameters : ( [[templateParameter]] ( , [[templateParameter]] )* )

templateParameter- : [parameter] | " [**parameter] "


emitMethod : [=modifier:public
    |protected
    |private]? [=static]? [type]? [=emit] [[methodDeclarator]] [[templateList]]?;

templateList- : ( ( [[templateName]] ( , [[templateName]] )* )? )


templateAttribute# : <<! [[templateAttributeContent]]* !>>

templateAttributeContent- : [[templateExpression]]
    | [[templateComment]]
    | [[templateCodeBlock]]
    | [[templateExactSpaces]]
    | [[templateInclude]]
    | [[templateText]]

templateText# : [**templateTextContent:<<(=|#|/[*]|$|@)]


templateComment# : <</* [**templateCommentContent] */>>

templateExpression# : <<= ( [[templateExpression]]
    | [**templateExpressionContent:<<(=|#|/[*]|$|@)] )+ >>

templateCodeBlock# : <<# ( [[templateExpression]] | [**templateLanguageCode:<<(=|#|/[*]|$|@)] )* #>>

templateExactSpaces# : <<$ [**templateExactSpacesContent] >>

templateInclude# : <<@ [[templateName]] >>

//templateOpen- : <
//templateClose- : !>>

// The master of this part of the Umple grammar is available at
// http://code.google.com/p/umple/source/browse/trunk/cruise.umple/src/umple_layout.grammar

// Copyright: All contributors to the Umple Project
// This file is made available subject to the open source license found at:
// http://umple.org/license

// Layout elements are injected into classes as mixins by diagramming tools such
// as UmpleOnline. Programmers can tweak the layout textually.
position- : [[associationPosition]] | [[elementPosition]]

elementPosition : position [x] [y] [width] [height] ;

associationPosition : position.association [name] [[coordinate]] [[coordinate]] ;

coordinate : [x] , [y]

displayColor : ( displayColor | displayColour ) [**colorValue] ;


// The master of this second part of the Umple grammar is available at
// http://code.google.com/p/umple/source/browse/trunk/cruise.umple/src/umple_exceptions.grammar

// Copyright: All contributors to the Umple Project
// This file is made available subject to the open source license found at:
// http://umple.org/license

misnamedAttribute : [name] ; | [type] [name] ;

malformedConstraint : [ [!stuff:[^\]]*] ]

malformedStatement1 : [!stuff:[^\\{\\};]*] ( [!stuff:[^\\{\\};]*] )* ;

malformedStatemachine1 : [!stuff:[^\\{\\}\\(\\) ]*] { [**innerstuff] }

malformedStatement2 : [!stuff:[^\\{\\};]*] ( [!stuff:[^\\{\\};]*] )* { [**innerstuff] } ;

malformedStatemachine2 : [!stuff:[^\\{\\}\\(\\)]*] ( [!stuff:[^\\{\\}\\(\\)]*] )* { [**innerstuff] }

malformedMethod : [!stuff:[^\\{\\}\\(\\)]*] ( [!stuff:[^\\{\\}]*] )* { [**innerstuff] }

exception : [[misnamedAttribute]]
    | [[malformedStatement1]]
    | [[malformedStatemachine1]]
    | [[malformedStatement2]]
    | [[malformedStatemachine2]]
    | [[malformedConstraint]]
    | [[malformedMethod]]


toplevelException : [[toplevelExceptionMain]] ( { [**extraStuff] } )? ( " [**quotedStuff] " )? ( ; )?

toplevelExceptionMain : [=access:public
    |private
    |protected]? [identifier] [=queued]? [name]? [[inheritanceException]]? [name]*

inheritanceException : ( [=level:extends|implements]? [name] ( , [name] )* )+

// Copyright: All contributors to the Umple Project
// This file is made available subject to the open source license found at:
// http://umple.org/license

// beginning of use.grammar

// This is essentially rewriting the grammar rules present in the USE compiler, which exist in a similar format.

useProgram : model [id] ([[useGeneralClassDefinition]]
    | [[useInlineComment]]
    | [[useAssociation]])*


useGeneralClassDefinition- : [[useClassDefinition]]


useClassDefinition : (abstract)? class [id] [[useAttributes]]? end


useAttributes : attributes [[useAttributeDefinition]]*


useAttributeDefinition : [id] : [[useType]] (;)?


useType- : [[useSimpleType]]


useSimpleType : [id]


useInlineComment- : (-- [**inlineComment]) | (// [**inlineComment])


useAssociation : association [name] between [[useAssociationEnd]] [[useAssociationEnd]] end


useAssociationEnd : [name] [ [[useMultiplicity]] ]


useMultiplicity- : [[useMultiplicityRange]]


useMultiplicityRange : [[useMultiplicitySpec]] (.. [[useMultiplicitySpec]])?


useMultiplicitySpec : [integerSpec:\d+|[**]]

// Copyright: All contributors to the Umple Project
// This file is made available subject to the open source license found at:
// http://umple.org/license

filter : filter ( [filterName] )? { ([[filterStatement]])* }


filterStatement- : [[filterCombinedValue]] | [[filterNamespace]] | [[filterValue]] | [[hops]]


hops- : hops {([[super]] | [[sub]] | [[association]])*}


filterValue : include ([classname]) ( , [classname] )*;


super : super [superNum];


sub : sub [subNum];


association : association [associationNum];


filterNamespace : namespace [Namespace] (, [Namespace])* ;


filterCombinedValue : includeFilter ([filterName]) ( , [filterName] )*;

Grammar Notation

In Umple we use our own extended EBNF syntax for the grammar, with our own parsing tool. The reason for this is that we wanted several advanced features in the grammar and parser.

Samples of syntax in this user manual are generated directly from the input grammar files used to parse Umple code.

Our syntax offers a very simple mechanism to define a new language, as well as extend an existing one. We will be using examples to help explain our syntax.

 

Example of a simple rule

Let's start with a simple assignment rule (not part of Umple, just an example):

assignment : [name] = [value] ;

Above, the rule name is "assignment". An assignment is comprised of a non-terminal called "name", then the equals symbol ("="), a non-terminal "value" and finally a semi-colon symbol (";").

A non-terminal by default as shown above is a sequence of characters that is a non-whitespace that is delimited by the next symbol (based on the specified grammar). In the above case, the non-terminal "name" will be defined by the characters leading up to either a space, newline, or an equals ("=").

Here are a few examples that satisfy the assignment rule above:

 

Rules that refer to other rules

Let us now consider nesting sub-rules within a rule. Sub-rules are words between [[ and ]]. Again, the following is illustrative, and is not Umple itself

directive- : [[facadeStatement]] | [[useStatement]]
facadeStatement- : [=facade] ;
useStatement : use [=type:file|url] [location] ;

Above, we have three rules, "directive", "facadeStatement", and "useStatement". A "directive" is either a "facadeStatement" or a "useStatement" (the "or" expression is defined by the vertical bar "|"). As indicated earlier, to refer to a rule within another rule, we use double square brackets ("[[" and "]]").

By default, rule names are added to the tokenization string (the result of parsing the input, shown in blue below). But, some rules act more like placeholders to help modularize the grammar (and to promote reuse). To exclude a rule name (and just the name, the rule itself will still be evaluated and tokenized as required), simply add a minus ("-") at the end of its name.

Above, we see that the rule names "directive", and "facadeStatement" are not added to the tokenization string because of the trailing minus signs..

For example, the text "facade;" is tokenized as follows:
[facade:facade]

Without the ability to exclude rule names, that same text would be tokenized with the following additional (and unnecessary) text:
[directive][facadeStatement][facade:facade]

 

Terminal symbols and constants

Symbols (i.e.terminals), such as "=" and ";" are used in the analysis phase of the parsing (to decide which parsing rule to invoke), but they are not added to the resulting tokenziation string for later processing.

If we want to tokenize symbols, we can create a constant using the notation

[=name]  

In the earlier example we see that a "facadeStatement" is represented by the sequence of characters "facade" (i.e. a constant).

To support lists of potential matches we use a similar notation

[=name:list|separated|by|bars].

In the earlier example, we see that the "type" non-terminal can be the constant string sequence "file" or "url".

Hence, here are a few examples that satisfy the earlier example:

 

Optionality and repeating

Parentheses can be used to group several elements in the grammar into a single element for the purposes of the following special treatment.

An asterisk * means that zero or more of the preceding elements may occur.

A plus sign + means that one or more of the preceding elements must occur.

A question mark ? means that the preceding element may occur.

 

Avoiding consumption of whitespace

Normally when parsing, all whitespace (spaces, carriage returns, tabs, etc.) around tokens are ignored, and the token output by the parser does not contain them. However, if a # symbol is found after the rule (on the left hand side) then all whitespace is preserved. This is useful for cases where that space is actually useful, such as in Umple's templates.

 

Comments and arbitrary input

The grammar syntax supports a simple mechanism for non-terminals that can include whitespace (e.g. comments). Text in [** ] such as [**arbitraryStuff] is not parsed. However if the rule name is followed by a colon, such as [**templateTextContent:<<(=|#|/[**] then a pattern for different types of brackets that can be internally parsed can be specified. So the above says ignore everything except things in <<= <<# <</* , which will be processed.

Let us consider the rules to define inline and multi-line comments.

inlineComment- : // [*inlineComment]
multilineComment- : /* [**multilineComment] */

The [*name] (e.g. [*inlineComment]) non-terminal will match everything until a newline character. The [**name] (e.g. [**multilineComment]) non-terminal will match everything (including newlines) until the next character sequence is matched. In the case above, a "multilineComment" will match everything between "/*" and "*/".

Here are a few examples that satisfy the assignment rule above:

 

Special matching cases

By default, [name] matches identifiers that can include underscore and certain other symbols. To match alphanumeric identifiers only, then use

[~name]
To match based on a regular expression (such as a sequence of one or more digits in this case):
[!bound:\d+]

To match one or more identifiers, but with some being optionally omitted use this notation:

[attr_qualifier,attr_type,attr_name>2,1,0]

This states that there will be one, two, or three identifiers.  The priority of inputs is attr_name,attr_type and attr_qualifier.

API Summary

The following table describes the API generated from various Umple features. This is designed as a quick reference. To find the exact API for any system that would be generated in Java, use UmpleOnline and request to generate JavaDoc output.

Summary of the API generated by Umple from attributes, associations, state machines and other features
API GENERATED IN ALL CASES                        
void delete() removes object, correctly handling cascade deletion and referential integrity
any methods in the code are emitted as-is; they are made public if this is not declared
API GENERATED FROM ATTRIBUTES                        
T is the type of the attribute (String if omitted); note that Umple builtin types such as Integer become native types such as int
z is the attribute name
Note that the API for array attributes is shown as a column in the associations table further down
Umple concept   basic initialized lazy defaulted lazy immutable immutable autounique constant internal key  
Umple notation   T z; T z = val; lazy T z; defaulted T z = val; lazy immutable T z; immutable z; autounique z const T z=val internal T z; key { z }  
Querying value                        
T getZ() return the value yes yes yes yes yes yes yes; T always int depends
boolean isZ() return true if value is true if T Boolean if T Boolean if T Boolean if T Boolean if T Boolean if T Boolean depends
boolean equals(Object) is equal to another? yes
Mutating                        
boolean setZ(T) mutates the attribute yes yes yes yes yes; true only once depends
boolean resetZ() restores original default yes
Other                        
T getDefaultZ() returns original default yes
int hashCode() Likely unique value yes
constructor args T T
initial value   constructor val val null/0/false val null/0/false constructor val or val next int static val construtor val  
API GENERATED FROM ASSOCIATIONS                      
X is the name of current class
W is the name of the class at the other end of the association; used in method names unless a role name is present; pluralization rules are applied
r is a role name used when referring to W (optional, except in reflexive associations)
Umple concept   ? To many ? To many with role optional ? To one required many directional immutable immutable optional reflexive symmetric reflexive array attribute
Umple notation    -- * W;  -- * W r;  -- 0..1 W;  -- 1 W;  -- 1..* W;  -> 1--* W; immutable 1 -> * W; immutable 1 -> 0..1 W; * -- * X r; * self r; W [] r;
Querying link(s)                        
W getW() return the W yes; W or null yes W or null
W getW(index) pick a specific linked W yes yes; getR(index) yes yes yes R and X R yes; getR(index)
List<W> getWs() ges immutable list of links yes yes; getR() yes yes yes R and Xs yes; W[] getR()
boolean hasWs() is cardinality > 0? yes yes; hasR() yes yes yes R and Xs R yes; hasR()
int indexOfW(W) look up specific W -1 if none yes yes;  … ofR(W) yes yes yes R and X R yes;  … ofR(W)
int numberOfWs() cardinality yes yes; … ofR() yes yes yes R and Xs R yes; … ofR()
Mutating                        
boolean setW(W) add a link to existing W yes if * -- or 0..1 -- never never
W addW(args) construct a new W and adds link if 1 -- * W if 1 -- * W r never never
boolean addW(W) add a link to existing W yes yes; addR(W) yes yes never never R and X R yes; addR(W)
boolean setWs(W…) add a set of links yes yes never never
boolean removeW(W) remove link to W if possible yes yes; removeR(W) yes yes never never R and Xs R yes; removeR(W)
Other                        
static int minimumNumberOfWs() multiplicity lower bound yes yes; … ofR() yes yes yes R and Xs R
static int maximumNumberOfWs() multiplicity upper bound if > 1
static int requiredNumberOfWs() fixed multiplicity if > 1
boolean isNumberOfWsValid() false if breaching constraints yes; true initially
constructor args W (W args if 1 -- 1) W … W
initial value   empty empty empty constructor val empty empty constructor val constructor val empty empty empty
API GENGERATED FROM STATE MACHINES                      
sm is the name of the state machine
Umple concept   Sm with events Enum with no events                  
enum getSm() current state for statemachine sm yes yes
String getSmFullName() current state for statemachine sm yes yes
enum getSmS2() state of substate s2 yes
boolean e() event method e (for all events) yes yes
boolean setSm(enum) set state directly yes
Substates allowed yes
initial value first state listed                      
API GENERATED FROM SINGLETON                        
static X getInstance()

Umple messages

General information about Umple errors and warnings

The subsequent pages in the user manual describe each of the errors or warnings that can be emitted by the compiler. These can appear in UmpleOnline, Eclipse and the command-line compiler.

An error is a situation where the compiler can't generate code because the Umple code doesn't make sense; i.e. there is something critical missing, or there is an inconsistency.

A warning is a situation where code can be generated, but the resulting system may not to have the intended semantics (it may not behave as intended) because of an inconsistency, redundancy or assumption that may not be correct.



For developers of Umple itself: The file defining the messages in English is called en.error and is located in cruise.umple/src. Errors have severity 1 or 2, and warnings have severity 3, 4 and 5. When adding a message, a user manual page should be added describing it.
All messages should be detected in the parsing phase by calling setFailedPosition.
It is intended in the future that internationalized versions of Umple will be created; for example fr.error would be the French version. In the near future, it is intended to enable messages from Java or other compilers to be passed through as part of the Umple compilation process; these would be the same as the native language compiler, except that line numbers would be changed to point to the correct line of Umple code.

W001 Singleton With Non-Lazy Attribute

Umple semantic warning reported when a singleton class has an attribute that is not marked lazy

A singleton class can't have any arguments in its constructor. In general in Umple, unless an attribute is specified as 'lazy', then an argument for the attribute is added to the constructor. In the case of singletons this is not done. This warning is to let programmer know this. To avoid the warning, add the keyword 'lazy' to all attributes of a singleton class. However, whether or not this is done, the generated code will behave as if it had been done.

Example

// This example generates the warning message
class X {
  singleton;
  Integer x;
}

      

Load the above code into UmpleOnline

 

Another Example

// The following shows how to avoid the warning
class X {
  singleton;
  lazy Integer x;
}

      

Load the above code into UmpleOnline

 

W002 Singleton With Required Object

Umple semantic warning reported when a singleton class has an association with a multiplicity lower bound of 1 at the other end of the association

The constructor of a singleton can't take any arguments. Therefore it can't have a required link to another object, since this would have to be specified in the constructor. Any associations to other classes should therefore have multiplicity with lower bound of zero.

Note: Conceptually this warning would also have been produced if the lower bound was something greater than 1 (e.g. 5). However Umple treats a multiplicity specified with a lower bound > 1 as if the multiplicity lower bound was 0. The programmer is supposed to add the n elements immediately after construction. The API has a validity check method to verify this has been done.

Example

// This example generates the warning message
class X {
  singleton;
  0..1 -- 1 Y;
}

class Y {
}

      

Load the above code into UmpleOnline

 

Another Example

// The following shows how to avoid the warning
class X {
  singleton;
  0..1 -- 0..1 Y;
}

class Y {
}

      

Load the above code into UmpleOnline

 

W003 Redundant Lazy With Initialization

Umple syntactic warning reported when the lazy keyword in specified when there is also an initializer

The function of the 'lazy' keyword is to indicate that an attribute is not to appear in the constructor. However an initializer for the attribute has the same effect, so specifying both 'lazy' and an initializer is redundant, and hints that there may be a mistake. The solution is just to remove the extraneous 'lazy'.

Example

// This example generates the warning
class X3lazy {
  lazy Integer a = 1;
}

      

Load the above code into UmpleOnline

 

Another Example

// This shows how the warning can be removed.
class X3lazy {
  Integer a = 1;
}

      

Load the above code into UmpleOnline

 

E004 Invalid Multiplicity

Umple syntactic error reported when an invalid multiplicity is specified

Valid multiplicities in Umple include

When this error message appears, the multiplicity doesn't fit any of the above patterns. A common error, for example, is to use the notation 'n', as found in Entity-Relationship Diagrams. This is not valid in Umple; only integers, and * may appear.

Example

// This example generates the error message
class X {
  1 -- 0..1..2 Y;
}

class Y {
}

      

Load the above code into UmpleOnline

 

Another Example

// The following shows how to avoid the error
class X {
  1 -- 0..2 Y;
}

class Y {
}

      

Load the above code into UmpleOnline

 

E005 Undefined Class in Association

Umple semantic error reported when an an association is specified to a class that cannot be found

The classes at both ends of an association must exist in the system being compiled. It might be that the specified class is spelled wrongly or has been omitted from the compilation. If you are making an association to a class in existing code, then simply declare the class as external, as shown in the third example below.

Example

// This example generates the error message
class X {
  1 -- * Y;
}

      

Load the above code into UmpleOnline

 

Another Example

// The following shows how to avoid the error
class X {
  1 -- * Y;
}
class Y {}

      

Load the above code into UmpleOnline

 

Another Example

// It is also possible to designate that the class Y is external in the following manner
class X {
  1 -- * Y;
}
external Y {}

      

Load the above code into UmpleOnline

 

Another Example

// The following will also generate the error message
class X {}
class Y {}

association {
  1 X -- * Z;
}

      

Load the above code into UmpleOnline

 

E006 Missing Default

Umple syntactic error reported when no default value is specified after an attribute that is marked defaulted

The keyword 'defaulted' means that the attribute will be given a default value if the value is not set in the constructor. Omitting the default value is therefore illogical. The default value is specified after an equals sign.

Example

// This example generates the error message
class X {
  defaulted Integer a;
}

      

Load the above code into UmpleOnline

 

Another Example

// The following shows how to avoid the error
class X {
  defaulted Integer a = 5;
}

      

Load the above code into UmpleOnline

 

W007 Key Already Specified

Umple semantic warning reported when a second key statement is encountered in a class

To avoid confusion, a class should normally only have one key specification. This warning is intended to direct the programmer to list the multiple attributes within the same key directive, rather specifying them separately.

The reason for this is that without this warning, code that is separated by many lines or found in a mixin file might modify the key in a way that wasn't anticipated by the developer who is not aware of the existence of multiple key statements.

Developers can ignore this warning without any consequences. The examples below will generate the same compiled code.

Example

// This example generates the message
class X {
  name;
  id;
  key { name }
  key { id }
}


      

Load the above code into UmpleOnline

 

Another Example

// This example below avoids the message
class X {
  name;
  id;
  key { name, id }
}


      

Load the above code into UmpleOnline

 

E008 Association Class Missing End

Umple semantic error reported when an association class is only defined with one end

An association class must have two classes designated as its ends. Instances of the association class represent links between instances of the associated classes, so it is illogical for an association class to have only one end.

Example

// This example generates the error message
class A {}

class B {}

associationClass C {
   * A;
}

      

Load the above code into UmpleOnline

 

Another Example

// The following shows how to avoid the error
class A {}

class B {}

associationClass C {
   * A;
   * B;
}

      

Load the above code into UmpleOnline

 

E009 Reflexive Lower Bound

Umple semantic error reported when a reflexive association has a multiplicity with a lower bound greater than one

A reflexive association must have multiplicity with lower bounds of zero at both ends (e.g. *, 0.1 or or 0..2), otherwise an illogical situation would result. For example, creating a parent-child association on class Person (the example below) with a lower bound of 2 would mean that every Person in the system must have parents, ad infinitum.

Example

// This example generates the error message
class Person {
  * -- 2 Person parents;
}

      

Load the above code into UmpleOnline

 

Another Example

// The following shows how to avoid the error
class Person {
  * -- 0..2 Person parents;
}

      

Load the above code into UmpleOnline

 

W010 Singleton Multiplicity Over 1

Umple semantic warning reported when a singleton class has an association with incoming multiplicity > 1

Since there can only be one instance of a singleton class, it is logically impossible for another class to have links to more than one instance of the singleton class.

Example

// This example generates the warning message
class X {
  singleton;
}

class Y {
   0..1 -- * X;
}

      

Load the above code into UmpleOnline

 

Another Example

// The following shows how to avoid the warning
class X {
  singleton;
}

class Y {
   0..1 -- 1 X;
}

      

Load the above code into UmpleOnline

 

E011 Class is Subclass Of Self

Umple semantic error reported when a class is designated as a subclass of itself.

The inheritance hierarchy cannot have cycles. It must be a strict tree. It is therefore not allowed to make a class into a subclass of itself.

Example

// This example generates the error message
class X {
  isA X;
}

      

Load the above code into UmpleOnline

 

Another Example

// The following shows how to avoid the error
class Y {}

class X {
  isA Y;
}

      

Load the above code into UmpleOnline

 

E012 Class Indirectly Subclass of Self

Umple semantic error reported when a class is designated as a subclass of itself, through some other class.

The inheritance hierarchy cannot have cycles. It must be a strict tree. It is therefore not allowed to make a cycle or loop, in which a class is indirectly a subclass of itself.

Example

// This example generates the error message
class A {
  isA C;
}

class B {
  isA A;
}

class C {
  isA B;
}

      

Load the above code into UmpleOnline

 

Another Example

// The following shows how to avoid the error
class A {
}

class B {
  isA A;
}

class C {
  isA B;
}

      

Load the above code into UmpleOnline

 

E013 Non Immutable Association

Umple semantic error reported when an immutable class is defined as having an association to a non-immutable class.

By definition, an immutable class can't change state, so it can't have an association that can change state or an association to a class that can change state.

Example

// The following example generates the error message
class X {
   Integer x;
}

class Y {
  String s;
  immutable;
  0..1 -> 0..1 X;
}
      

Load the above code into UmpleOnline

 

Another Example

// One way to solve this is to make the association point to
// another immutable class
// But note that this only works for one-way associations
class X {
   Integer x;
   immutable;
}

class Y {
  immutable;
  String s;
  0..1 -> 0..1 X;
}
      

Load the above code into UmpleOnline

 

Another Example

// Another solution is to not require the association to be immutable,
// just the attributes. But this may not match the intended semantics.
class X {
   immutable Integer x;
}

class Y {
    immutable String s;
    0..1 -- 0..1 X;
}
      

Load the above code into UmpleOnline

 

E014 Immutable Subclass of Mutable

Umple semantic error reported when an attempt is made to create an immutable subclass of a mutable superclass

Immutability means that no aspect of the state (attribute, association, state machine) can change in a class once constructed. However if a superclass has mutable elements, they are inherited as mutable. As a result it is not allowed for an immutable class to be a subclass of a mutable class.

Note that this will occur if the entire subclass is being declared as immutable and if any element of the superclass is not immutable. It is possible to have mixes of immutable elements and mutable elements in any given class. In the example below, one solution would be to declare attribute b as immutable and remove the class-level immutable status. Class X14immut would be mutable because it would inherit mutable attribute a.

Example

// This example generates message 14
class B {
  a;
}

class X14immut {
  isA B;
  immutable;
  b;
}


      

Load the above code into UmpleOnline

 

W015 Immutable Class State Machine

Umple semantic warning reported when an immutable class is defined as having a state machine.

By definition, an immutable class can't change state, so it can't have a state machine. Any state machine defined is ignored.

Example

// The following example shows how to generate this warning.
// Removing the immutable keyword will solve the problem.
class X {
  immutable;
  Integer y;
  sm {
    S1 {
    }
  }
}

      

Load the above code into UmpleOnline

 

E016 Non Immutable Superclass

Umple semantic error reported when an immutable class is defined as having a superclass that is non-immutable.

In an inheritance hierarchy, all classes must be immutable, or all non-immutable, otherwise the substitutability principle would broken.

Example

// The following example generates the error message
// A solution is to make class X immutable
class X {
  a;
}
class Y {
  immutable;
  isA X;
}
      

Load the above code into UmpleOnline

 

E017 Non Immutable Bidirectionality

Umple semantic error reported when a non-directed association is declared to be immutable, or appears in an immutable class.

Allowing two-way associations to be immutable would be impossible since it would require change to one object when it is linked to the other, and that would break the concept of immutability.

Example

// The following example generates the error message
// Change the -- to -> to solve the problem
class Y {
  immutable;
  1 -- * Z;
  isA X;
}

class Z {
  immutable;
  y;
}
      

Load the above code into UmpleOnline

 

E018 Reflexive Immutable

Umple semantic error reported when an immutable reflexive association is declared as having 1 at the other end

This is a special case of the general rule that reflexive associations must have upper bounds greater than zero.

Example

// The following example generates the error message
class X {
    immutable;
    0..1 -> 1 X;
}

      

Load the above code into UmpleOnline

 

E019 Duplicate Association

Umple semantic error reported when a class is given two associations with the same name.

Associations between the same classes must be given different names. This error can occur when two associations have the same role name; the solution is to change one of the role names. The error can also occur when two associations are created without any role name at all. In that case the default name is generated from the associated class. The solution is to add a role name to one of the associations.

Example

// The following example shows how to generate this error.
class X {
}

class Y {
  1 -> * X;
  1 -> * X;
}

      

Load the above code into UmpleOnline

 

E020 Interface Association Not One Way

Umple semantic error reported when an association to an interface is declared to be bidirectional or pointing from the interface.

An association can be declared from a class to an interface, but if this is done, it must be one way using the '->' notation. The reason for this is that no concrete methods can be generated in an interface.

Example

// This example generates the message
class X20classintfarrow {
  1 -- * IA;
}

interface IA {}

      

Load the above code into UmpleOnline

 

Another Example

// This example generates the message
class X20classintfarrow {
  1 -> * IA;
}

interface IA {}

      

Load the above code into UmpleOnline

 

E021 Invalid Reflexive Association

Umple syntactic error reported when a class has a reflexive association (an association with both ends the same) but there is neither a role name (indicating it is asymmetric), nor a 'self' keyword (indicating it is symmetric).

Code cannot be generated for asymmetric reflexive associations unless there is a role name at at least one end. This ensures the generated API has distinct words for each end.

For more information about reflexive associations, see this page.

Example

// The following example shows how to generate this error.
class X {
    0..1 -- 0..1 X;
}

      

Load the above code into UmpleOnline

 

Another Example

// The following example shows how to fix the error if this is an asymmetric association.
class X {
    0..1 -- 0..1 X right;
}

      

Load the above code into UmpleOnline

 

Another Example

// The following example shows how to fix the error if this is a symmetric association.
class X {
    0..1 self right;
}

      

Load the above code into UmpleOnline

 

E022 Duplicate Attribute

Umple semantic error reported when a class is given two attributes with the same name.

Attributes in a class must have distinct names. The solution to this error is to rename or delete one of the attributes. This error is particularly prone to appear when a class is composed of two or more files using Umple's 'mixin' capability; the attribute should be defined in one file or the other, but not both.

@@example @@source manualexamples/E022DuplicateAttribute1.ump @@endexample

E023 Attribute Association Name Clash

Umple semantic error reported when an association has the same name as an attribute or vice versa,

An association generates a variable and methods that would clash with an attributes of the same name. If a role name is used, then it must be distinct from all attributes. If no role name is used then the class name (with first character converted to lower case) at the 'other end' of the association must be distinct from all attributes.

Ths problem can sometimes be hard to notice if an association is declared 'backwards' in the 'other' class, or independently of either class. It is especially tricky if the clashing association or attribute is in a separate mixin.

Example

// This example generates error 23 because an attribute and role name share a name
class X23atdupassoc1 {
   a;
   1 -- 0..1 Another a;
}

class Another {}


      

Load the above code into UmpleOnline

 

Another Example

// This generates error 23 because attribute b clashes with
// class name B in the association
class X23atdupassoc2 {
   b;
   1 -- 0..1 B;
}

class B {}

      

Load the above code into UmpleOnline

 

E024 Sort Key Not of Umple Type

Umple semantic error reported when a sort key for a sorted association does not use one of the builtin Umple types

The sort key for an sorted association must have one of the simple types Integer, Short, Long, Double, Float or String. This allows sensible code to be generated for comparisons. The set of allowed types may be expanded in the future.

Example

// This example generates the error message
class X {
  1 -- * Y sorted {endDate};
}

class Y {
   Date endDate;
}


      

Load the above code into UmpleOnline

 

E025 Sort Key Not Found

Umple semantic error reported when a sort key for a sorted association is not an attribute of the destination class

The sort key of a sorted association must be one of the attributes of the class at the other end of the association.

Example

// This example generates the error message
class X {
    * -- 1 Y sorted {nom};
}

class Y {
  name;
}


      

Load the above code into UmpleOnline

 

E026 Duplicate Key Item

Umple semantic error reported when a key has a duplicate item

If an item (attribute, association, state machine) appears twice in a key it is an error since Umple cannot tell the preferred order of items.

Example

// The following example has error 26 since they key has 'a' twice
class X26dupiteminkey {
  a;
  b;
  key {a, b, a} 
}

      

Load the above code into UmpleOnline

 

W027 Key Identifier Incorrect

Umple semantic warning reported when an identifier in a key statement was not found

The list of identifiers in a key statement can include attributes, associations (role name for example) or state machines. This message indicates that the referenced identifier could not be found. This is usually the result of a typographical error. The extraneous identifier is ignored, which is likely to result in incorrect code.

Example

// This example generates the message
class X27itemkeynotdef {
  a;
  key {b}; 
}


      

Load the above code into UmpleOnline

 

E028 Constraint Identifier Incorrect

Umple semantic error reported when an identifier (attribute, etc.) in a constraint cannot be found

Currently, constraints can refer to attributes in the current class; in the future they will be able to refer to other model elements. This message indicates that an identifier referenced in the constraint was not found. This is often just due to a typographical error, but it might be due to the current limitations of constraints.

Example

// This example generates the message
class X28attrconsrnotdef {
  Integer a;
  [b > 5]
}

      

Load the above code into UmpleOnline

 

E029 Constraint Type Mismatch

Umple semantic error reported when there is a type mismatch in a constraint

It is only possible to compare a String to a String, a Boolean to a Boolean, and a number to a number, etc. Violations result in a type mismatch error.

Example

// This example generates the message
class X29attrtypeconstr {
  a;
  [a > 5]
}

      

Load the above code into UmpleOnline

 

Another Example

// The following shows how to avoid the message
class X29attrtypeconstr {
  Integer a;
  [a > 5]
}


      

Load the above code into UmpleOnline

 

W030 Redefined Namespace

Umple semantic warning reported when a class is declared in separate places to be in two namespaces

Since a class can only be in one namespace, the last namespace declaration overides earlier ones. This can sometimes be useful, e.g. when creating a mixin to change the default location of a class. However it is normally a sign of a mistake, hence the warning.

Example

// This example generates the message
// Namespace b, encountered later, will be the namespace of the class
namespace a;

class X30redefnamespace {
}

namespace b;

class X30redefnamespace {
}

      

Load the above code into UmpleOnline

 

W031 Namespace Not Used

Umple semantic warning reported when a namespace is never applied to any class

If you declare a namespace and then declare another before using the first namespace, this warning is issued. The reason for the warning is that this can happen accidentally, for example if you add a namespace declaration before a comment and then add a different one after a comment but before the class is declared.

Example

// This example generates the message because 
// namespace n is never used
namespace n;
namespace m;

class X21namespacenotused {}

      

Load the above code into UmpleOnline

 

E032 Reserved Role Name

Umple reports this error when a specific role name is used

In order to define a reflexive association, it is necessary to specify role names. There is a situation where it is possible to define a reflexive association with one role name. When this happens, Umple uses an implicit name for the second role name which is the plural form of the class name (e.g. if the class name is Computer, plural form would be computers). Therefore, if a user uses plural form of the class name as role name, Umple produces an error.

Example

// This example generates the error message

class Course {  
  * -- * Course courses;  
}  


      

Load the above code into UmpleOnline

 

Another Example

// The following shows how to avoid the error

class Course {  
  * -- * Course course_s ;  
}  


      

Load the above code into UmpleOnline

 

Another Example

// This example generates the error message

class Course {  
  * courses -- * Course;  
}  


      

Load the above code into UmpleOnline

 

Another Example

// The following shows how to avoid the error

class Course {  
  * course_s -- * Course;  
}  


      

Load the above code into UmpleOnline

 

W033 Missing Superclass

Umple semantic warning issued when a referenced superclass is not found

When you declare a superclass of a class, that class must exist. If the class does not exist, then this warning is issued.

It might be the case that the class is in fact declared in some code that is defined externally. In that case the existence of the external class should be made known to Umple using the external keyword;

Example

// This example generates the warning since T is not defined
class S {
  isA T;
}


      

Load the above code into UmpleOnline

 

Another Example

// This example solves the problem by defining T as an external class
// Umple will not generate any code for T, but now knows it exists
class S {
  isA T;
}
external T {};


      

Load the above code into UmpleOnline

 

E034 Multiple Inheritance

Umple semantic error generated when multiple inheritance is encountered

Umple does not currently support multiple inheritance, in order to be consistent with code generated in Java, and also to make models simpler.

Example

// The following will generate this error

class P1 {}
class P2 {}

class Sub {
  isA P1, P2;
}

      

Load the above code into UmpleOnline

 

Another Example

// The following is another way of formulating the same declarations, also resulting in the error

class P1 {}
class P2 {}

class Sub {
  isA P1;
  isA P2;
}



      

Load the above code into UmpleOnline

 

Another Example

// If all but one of the parents is declared as an Interface, the problem is solved

interface P1 {}
class P2 {}

class Sub {
  isA P1;
  isA P2;
}



      

Load the above code into UmpleOnline

 

W035 Uninitialized Constant

Umple semantic warning generated when a Umple builtin data type constant is not initialized

It makes little sense to have a constant unless it is given a value. If a constant is of one of the built-in Umple data types we will set it to a default value: Integer, Double and Float will be set to zero, String will be set to an empty String, Boolean will be set to false, Date will be set to the date where the code was generated and Time will be set to midnight (00:00:00). However, the warning is issued since forgetting to initialize a constant is a common source of errors.

Example

// The following will generate this warning

class X {
  const String A; //same as const String a = "";
}

      

Load the above code into UmpleOnline

 

Another Example


// The following will resolve the issue

class X {
  const String A = "Something Interesting";
}


      

Load the above code into UmpleOnline

 

W036 Unmanaged Multiplicity

Umple semantic warning generated when a directed association has a multiplicity with hard constraints

Umple generates code to manage the manipulation of the directed end (with the arrowhead) of a directed association. However there are no inverse references in such a case. In the example below, there are no references from class B to class X. As a result, the multiplicity on the undirected end is purely 'documentation'.

Specifying a hard constraint such as 1 or 2 for the upper or lower bound in such a case may be misleading and is typically incorrect. This error is raised whenever the multiplicity is other than * or 0..1

Example

// The following will generate this warnbing

class X {
  1 -> * B first;
  1..3 -> * B second;
  0..2 -> * B third;
}

class B {}

      

Load the above code into UmpleOnline

 

Another Example

// The following solves the problem by either making the association unndirected
// or making the bounds have soft constraints

class X {
  0..1 -> * B first;
  * -> * B second;
  0..2 -- * B third;
}

class B {}


      

Load the above code into UmpleOnline

 

E037 Uninitialized Constant Object

Umple semantic error generated when an Object constant is not initialized

It makes little sense to have a constant unless it is given a value. Since there is no obvious default value for arbitrary data types, unitialized constants that are not from a default Umple data type the code cannot be parsed until the constants are initialized.

Example

// This example generates error 37
class X {
  const Y A;
}

class Y {
  Integer a;
}

      

Load the above code into UmpleOnline

 

Another Example

// This example resolves error 37

class X {
  const Y A=new Y(3);
}

class Y {
  Integer a;
}

      

Load the above code into UmpleOnline

 

E040 Singleton Has Subclasses

Umple semantic error generated when a singleton class has subclasses

Singleton is a software pattern to allow only one instance of a class. A singleton class has a private constructor and cannot be inherited.

Example


// In this example a singleton class has subclasses and it generates an error
class Airplane
{
  singleton;
}
class F16
{
	isA Airplane;
}
      

Load the above code into UmpleOnline

 

Another Example


//I this example the singleton class does not have a subclass and is correct
class Airplane
{
  
}
class TheAirplane
{
  singleton;
}
class F16
{
	isA Airplane;
}
      

Load the above code into UmpleOnline

 

W044 Attribute Duplicated in Superclass

Umple semantic warning reported when an attribute in a class is a duplicate of an attribute in a superclass.

The purpose of this warning is to alert the developer that they have to resolve the issue by changing the name of the duplicated attribute in either the superclass or subclass, or else remove one of them entirely. This warning will soon be changed to an error.

Example

// This example generates the warning message
class A {
  attr;
}

class B {
  isA A;
  attr;
}


      

Load the above code into UmpleOnline

 

Another Example

//This example solves the problem
class A {
  attr;
}

class B {
  isA A;
  differentAttr;
}


      

Load the above code into UmpleOnline

 

W045 Initialized Value in Key

Umple semantic warning reported when an attribute in the key is given an initial value

If an attribute is given an initial value and is part of a key, then there is potential for keys of all instances of a class to be the same, meaning that they would be treated as equal and would have the same hash value. It is unlikely that a developer intends for this to be the case, so a warning is thrown to inform them of this behaviour.

Example

// This example generates the message
class X {
  Integer z = 1;
  key { z }
}


      

Load the above code into UmpleOnline

 

Another Example

// The following shows how to avoid the message
class X {
  Integer z;
  key { z  }
}


      

Load the above code into UmpleOnline

 

W046 Attribute Has Template Type

Umple syntactic warning reported when an attribute has a template type, characterized by brackets "<...>".

Template types do not follow Umple modelling conventions. Umple encourages users to take full advantage of associations in their modelling, which in almost all contexts replace the need for template types. Multivalued attributes can also be used.

Example

// This example generates the message

class A {
  depend java.util.List;
  List otherClassGroup;
}
class OtherClass {}


      

Load the above code into UmpleOnline

 

Another Example

// The following shows how to avoid the message using a multivalued attribute
class A {
  OtherClass[] otherClassGroup;
}
class OtherClass {}


      

Load the above code into UmpleOnline

 

Another Example

// The following shows how to avoid the message using an association
class A {
  0..1 -- * OtherClass;
}
class OtherClass {}


      

Load the above code into UmpleOnline

 

W047 Empty Key Statement

Umple semantic warning reported when a key statement has no elements inside of it

An empty key statement has no meaning, but Umple will detect the key statement and generate methods associated with having a key. This might lead the developer to think that they have defined a key when in fact the generated methods cannot differentiate between instances of the class in question. The warning is shown to notify the developer of the potential mistake.

Example

// This example generates the message
class A {
  id;
  key { }
}


      

Load the above code into UmpleOnline

 

Another Example

// The following shows how to avoid the message.
class A {
  id;
  key { id }
}


      

Load the above code into UmpleOnline

 

W049 Duplicated Method Name

Umple semantic warning reported when two methods have the same names and return types

You cannot have two methods that have the same names and return types. The warning is shown to notify the developer of the potential mistake.

Example

// This example generates the message
class A{
  void test1(){return("hello world")}
  void test1(){return("dlrow olleh")}
}



      

Load the above code into UmpleOnline

 

Another Example

// The following shows how to avoid the message.
class A{
  void test1(){}
  void test2(){}
}


      

Load the above code into UmpleOnline

 

W050 Target State Not Found

Umple semantic warning reported when the target state of a transition is not listed.

An end state (with no outgoing transitions) is generated. The purpose of the warning is to alert the developer that they may have a typographical error in the target state name.

Example

// This example generates the error message
class X {
  sm {
    s1 {
      e1 -> s2;
    }
  }
}


      

Load the above code into UmpleOnline

 

Another Example

// This example solves the problem
class X {
  sm {
    s1 {
      e1 -> s2;
    }
    s2 {}
  }
}


      

Load the above code into UmpleOnline

 

E051 Event Parameters Must Match

Umple semantic error reported when events with the same name have different parameters

When parameters are specified on a state machine event, all transitions with the same event name must have identical parameters. The reason for this is that there is only one event method generated.

Example

// This example generates the error message
class X {
  sm {
    s1 {
      e1(String s) -> s2;
    }
    s2 {
      e1(Float f) -> s2;
    }
  }
}


      

Load the above code into UmpleOnline

 

Another Example

// This example solves the problem
class X {
  sm {
    s1 {
      e1(String s) -> s2;
    }
    s2 {
      e1(String s) -> s2;
    }
  }
}


      

Load the above code into UmpleOnline

 

E052 State Machine Name Clash

Umple semantic error reported when a state machine name matches the name of another element such as an association or attribute

Since, in effect, a state machine defines a special kind of attribute (whose value is enumerated as one of the states and is controlled by events) it is not allowed to have an attribute or association with the same name as a state machine.

Example

// This example generates the message because the state machine a
// clashes with the attribute a
class X52assattnamestatemachine1 {
  a;
  a {
    s1 {}
    s2 {}
  }
}

      

Load the above code into UmpleOnline

 

Another Example

// The sample generates the message because the state machine a
// clashes with the association role name a
class X52assattnamestatemachine2 {
  1 - 0.1 B a;
  a {
    s1 {}
    s2 {}
  }
}
class B {}

      

Load the above code into UmpleOnline

 

E053 No Concurrency At Top Level

Umple semantic error reported when concurrent substates are placed at the top level of a state machine

A state machine must be in one top level state at all times. Concurrent substates can exist in any substate at any level, but not directly in a top level state. The second example below shows how this can be handled simply by adding a level of nesting.

If the intent is simply to create concurrent do activities, and alternative is to use Umple's active objects notation.

Example

// This example generates the message
class X53conctoplevel {
  sm {
    s1 {
      do {System.out.println("Reached s1");}
    }
    ||
    s2
    {
      do {System.out.println("Reached s1");}
    }
  }
}

      

Load the above code into UmpleOnline

 

Another Example

// The following shows how to avoid the message
class X53conctoplevel {
  sm {
    s0 {
      s1 {
        do {System.out.println("Reached s1");}
      }
      ||
      s2
      {
        do {System.out.println("Reached s1");}
      }
    }
  }
}

      

Load the above code into UmpleOnline

 

W054 Duplicate Events

Umple warning generated when there is a duplicate unguarded event that will never be reached

In the example below, the second transition e from s1 can never be triggered because when e occurs the first transition is taken.

Example


class X {
  sm {
    s1 {
      e-> s2;
      e-> s3;
    }
    s2 {}
    s3 {}
  }
}


      

Load the above code into UmpleOnline

 

W055 Duplicate Events Within Substates

Umple warning generated when there is a duplicate unguarded event that will never be reached, in the situation where there is a superstate and a substate with the same event

In the example below, the event e from the s1 superstate and the event e in the s1a substate are ambiguous. Current semantics is that the event in the superstate takes precedence, but this semantics may be changed..

Example


class X {
  sm {
    s1 {
      e-> s2;
      s1a {
        e-> s3;
      }
    }
    s2 {}
    s3 {}
  }
}


      

Load the above code into UmpleOnline

 

W071 Duplicate Method Different Type

Umple sematic warning reported when two methods have the same names but different types

In some programming languages like Java, you cannot have the same method names even the return types are different. The warning is shown to notify the developer of the potential mistake.

Example

// This example generates the message
class A{
  void test1(){return("hello world")}
  Integer test1(){return("dlrow olleh")}
}



      

Load the above code into UmpleOnline

 

Another Example

// The following shows how to avoid the message.
class A{
  void test2(){}
  Integer test1(){}
}


      

Load the above code into UmpleOnline

 

W072 Refactored Final State

Umple sematic warning when do activities, exit actions, outgoing transitions, and/or nested state machines are removed by the compiler from final states.

In Umple, final states are allowed to be empty, or they can contain entry actions.

Example

// The following shows how to generate the warning

class InvalidFinalState {
  status{
    on{
      turnoff -> off;
      powerOff-> FINAL;
    }
    
    off{
      turnOn -> on;  
    }

    final FINAL{
      entry/{entry();}
      do{exe();}
      reboot -> on;
      nestedSm {
        s1 {
          -> s2;
        }
        s2 {

        }
      }
      exit/{exit();}
    }
  }
}

      

Load the above code into UmpleOnline

 

Another Example

// The following shows how to avoid the warning

class X {
  status{
    on{
      turnoff -> off;
      powerOff-> FINAL;
    }    
    off{
      turnOn -> on;  
    }
    final FINAL{
      entry/{entry();}
    }
  }
}

      

Load the above code into UmpleOnline

 

Another Example

// The following shows how to avoid the warning

class X {
  status{
    on{
      turnoff -> off;
      powerOff-> FINAL;
    }    
    off{
      turnOn -> on;  
    }
    final FINAL{

    }
  }
}

      

Load the above code into UmpleOnline

 

E073 Duplicate Parallel State Machine Name

Umple semantic error reported when parallel state machines in the same composite state have the same name.

In Umple, parallel state machines within the same composite state must have different names.

Example

// The following example generates the error
// "s1" has two parallel state machines that are named "t1"

class X {
  sm{
    s1{
      t1{
        goT2-> t2;
      }
      t2{ }
      ||
      t1{
        goT4-> t4;
      }
      t4{}
    }
  }
}

      

Load the above code into UmpleOnline

 

Another Example

// The following example shows how to avoid the error

class X {
  sm{
    s1{
      t1{
        goT2-> t2;
      }
      t2{ }
      ||
      t3{
        goT4-> t4;
      }
      t4{}
    }
  }
}

      

Load the above code into UmpleOnline

 

WE1xx Identifier Invalid

Umple syntactic error or warning reported when an identifier does not have the correct syntax

In Umple, identifiers used for classes, association role names, types, attributes, state machines, states, events and other elements must be alphanumeric. In addition, class and interface names should start with a capital letter (or _), and other elements should start with a lower case letter. The exact error message you received will tell you which identifier has the problem. The examples below will generate these messages.

Example

// Class with non-alphanumeric name (100)
class @ {}


      

Load the above code into UmpleOnline

 

Another Example

// Warnings from attribute starting with upper case letter (131)
class X {
  Attrib;
}

class Y {}


      

Load the above code into UmpleOnline

 

Another Example

// Attribute name with special characters (130)
class X {
  na$me;
}


      

Load the above code into UmpleOnline

 

Another Example

// Attribute name with special characters that looks like an association (132)
// If this is supposed to be an association, put spaces before and after the -- and *
class X {
  1--*Y;
}

class Y {}


      

Load the above code into UmpleOnline

 

Another Example

// Attribute type with special characters that looks like an association (140)
// If this is supposed to be an association, put spaces before and after the --
class X {
  1--* Y;
}

class Y {}


      

Load the above code into UmpleOnline

 

Another Example

// State machine name with special characters (150)
class X {
  ed%4 {
    s1 {}
  }
}


      

Load the above code into UmpleOnline

 

Another Example

// State  name with special characters (152)
class X {
  ed4 {
    s*1 {}
  }
}


      

Load the above code into UmpleOnline

 

E112 Duplicate Constants in Interface

Umple semantic error reported when an interface is given two or more constants with the same name.

Constants in an attribute must have distinct names. The solution to this error is to rename or delete one of the constants.

Example

// The following example shows how to generate this error.
interface X {
  const A="dog";
  const A="cat";
}

      

Load the above code into UmpleOnline

 

W141 Value Type Mismatch

Umple syntactic warning reported when an attempt is made to initiate an attribute with a value that does not match the type of the attribute

Numbers must be initialized with numbers, strings with strings in double quotes, and Booleans with true or false. For Dates the value format is a string "yyyy-mm-dd"; for Times the format is "hh:mm:ss".

Note that for an initialization value with no type specified will result in the attribute having its type inferred from the vbalue. This is demonstrated in the third example.

Example

// The following will generate this warning on every line of the class
class X {
  Date d = "20130708";
  Integer i = "abc";
  String s = 123;
  Boolean b = 1;
  Time t = "120000";
}


      

Load the above code into UmpleOnline

 

Another Example

// The following shows how to solve the above problem
class X {
  Date d = "2013-07-08";
  Integer i = 7;
  String s = "123";
  Boolean b = true;
  Time t = "12:00:00";
}

      

Load the above code into UmpleOnline

 

Another Example

// The following shows how to solve the above problem not even showing the type at all
class X {
  d = "2013-07-08";
  i = 7;
  s = "123";
  b = true;
  t = "12:00:00";
  m = 2.3;
}

      

Load the above code into UmpleOnline

 

E180 Duplicate Association Name Class Hierarchy

Umple semantic error reported when a subclass has an association that is not a specialization named the same as a superclass association

A subclass can not have an association with the same role name as an association of its superclass, unless it is a valid specialization.

Example

class Person {
	* -> * Person friends;
}

class Student {
	isA Person;
	* -> * Dog friends;
}

class Dog {
}
      

Load the above code into UmpleOnline

 

E200 Trait Identifier Invalid

Umple syntactic error related to identifiers of traits

In Umple, identifiers used for traits must be alphanumeric. It means that must start with an alpha character, or _ .

Example

//This example shows an error in the name of trait
trait T@ {
	//traits elements
}
      

Load the above code into UmpleOnline

 

Another Example

//This example shows an error in the name of trait
trait 1T {
	//traits elements
}
      

Load the above code into UmpleOnline

 

Another Example

//This example shows a valid name for the trait
trait Color {
	//traits elements
}
      

Load the above code into UmpleOnline

 

Another Example

//This example shows a valid name of traits
trait Equality {
	//traits elements
}
      

Load the above code into UmpleOnline

 

W201 Trait Name Syntax

Umple syntactic warning related to identifiers of traits

In Umple, identifiers used for traits, classes and interfaces should start with a capital letter (or "_"), and other elements should start with a lower case letter.

Example

//This example shows a warning in the name of traits because they start with lower cases.
trait color {
	//traits elements
}

trait equality{
	//traits elements
}


      

Load the above code into UmpleOnline

 

Another Example

//This example shows a valid name for the trait
trait Color {
	//traits elements
}
      

Load the above code into UmpleOnline

 

Another Example

//This example shows a valid name of traits
trait Equality {
	//traits elements
}
      

Load the above code into UmpleOnline

 

E202 Trait not defined

Umple semantic error resulting from a trait not being defined

In Umple, when traits are used inside of classes or traits they have to be defined. The Umple compiler does not allow the use of traits that are not defined in the system.

Example

//In  this example, trait "T" uses trait "T1" which is not available. 
interface I{
	//elements
}

class A {
	isA I;
	isA T; 
}

trait T{
  isA T1;
}

      

Load the above code into UmpleOnline

 

Another Example

//In  this example, the error has been resolved just by defining trait T1. 
interface I{
	//elements
}

class A {
	isA I;
	isA T; 
}

trait T{
  isA T1;
}

trait T1{
	//elements
}

      

Load the above code into UmpleOnline

 

E203 Not having an unique identifier

Umple semantic error related to not using traits which do not have unique identifiers

In Umple, all elements which are capable of being reused should have unique identifiers. Traits, as reusable elements in Umple also have to follow the same rule. Identifiers of traits should be unique in the system. The conflict happens among classes, interfaces, and traits. Therefore, These three elements always should have unique identifiers.

Example

//In  this example, Identifier of trait "I" is not unique;. 
class A{
	isA I;
}

class I {
  //elements
}

trait I{
  //elements
}

      

Load the above code into UmpleOnline

 

Another Example

//In  this example, Identifier of trait "T" is unique
class A{
	isA T;
}

class I {
  //elements
}

trait T{
  //elements
}

      

Load the above code into UmpleOnline

 

E204 Self Inheritance

Umple semantic error related to self inheritance

In Umple, traits cannot be used in an explicit or implicit cyclic way. It means that a trait cannot use itself and it also cannot be used in a cyclic hierarchy. This error happens when a trait extends itself.

Example

// In this example, there is a explicit use of a trait inside of itself.
class A{
	isA T;
}

trait T{
  isA T;
}
      

Load the above code into UmpleOnline

 

E206 Cycle in Traits

Umple semantic error related to a cycle of trait use

In Umple, traits cannot be used in an explicit or implicit cyclic way. This means that a trait cannot use itself and it also cannot be used in a cyclic hierarchy. This error happens when a hierarchy is created completely based on traits. Moreover, this issue generally arises because of invalid design or error in typing a trait name.

Example

// In this example, there is a cycle created in a hierarchy.
class A{
	isA T;
}



trait T{
  isA T1;
}
trait T1{
	isA T;
}

      

Load the above code into UmpleOnline

 

E208 Required Methods Not Available

Umple semantic error related to not having required methods of traits in classes

Traits need to have required methods in order to provide the functionality they have designed to provide. These required methods can provide special functionality or be way of accessing states (attributes) in host classes. This error is raised when a required method is not available.

Example

// In this example, the required method "FinalResult()" in Trait "T" is not satisfied by class "A"
class A{
	isA T;
}

trait T{
	Integer FinalResult();	
	void calculate(){
		//method FinalResult() will be used here;	
	}	
}

      

Load the above code into UmpleOnline

 

Another Example

// In this example, the require method "FinalResult()" in Trait "T" is satisfied by class "A"
class A{
	isA T;	
	internal Integer x;	
	Integer FinalResult(){
		return x/100;
	}
}

trait T{
	Integer FinalResult();	
	void calculate(){
		//method FinalResult() will be used here;	
	}	
}

      

Load the above code into UmpleOnline

 

E210 Conflict in Methods

Umple semantic error related to having two methods with the same signature but different implementation

Traits can be used in serveral hierarchies without any priority. It means that classes can be composed of several traits and also a trait can be composed of other traits. This brings cases in which two methods with the same signature come from either different traits or a different hierarchy path. If those methods come from two different traits, it is obvious that there is a conflict because those have been implemented for different purposes. On the other hand, if two methods come from two different paths but the source of those methods the same trait, then there is no conflict. However, there is a case in which the source is the same but one of the methods is overridden by traits somewhere in the path. In this case, there is a conflict because now functionality is not unique. The Umple compiler detects these cases and raises this error.

Example

// In this example, there is a conflict in class "A" on the method "test()"
class A{
	isA T1;
	isA T2;
} 
trait T1 { 
	void test(){
	//special implementation by T1
	}
} 
trait T2 { 
	void test(){
	//special implementation by T2
	}
}


      

Load the above code into UmpleOnline

 

Another Example

// In this example, there is a conflict in trait "T" on the method "test()"
class A{
	isA T;
}
trait T{
	isA T1;
	isA T2;
}
trait T1{
	void test(){
	//special implementation by T1	
	}
}
trait T2{
	void test(){
	//special implementation by T2	
	}
}

      

Load the above code into UmpleOnline

 

Another Example

// In this example, there is a no conflict in class "A"
class A{
	isA T1;
	isA T2;
} 
trait T1 { 
	isA M;
} 
trait T2 { 
	isA M;
}
trait M{
	void test(){
	//special implementation by M
	}
}



      

Load the above code into UmpleOnline

 

Another Example

// In this example, there is a conflict in class "A" because method "test" is overridden in trait "T2"
class A{
	isA T1;
	isA T2;
} 
trait T1 { 
	isA M;
} 
trait T2 { 
	isA M;
	void test(){
	//special implementation by T2
	}
}
trait M{
	void test(){
	//special implementation by M
	}
}



      

Load the above code into UmpleOnline

 

E211 Two or More Modifications

Umple semantic error related to two or more modifications of provided methods of traits

When traits are used inside classes or traits, it is possible to add or remove provided methods. This feature is used to resolve conflicts and also when we do not need some provided methods or just need one of them. Logically, it is not correct to add a method twice or add and then remove a method. These problems are detected by the Umple compiler.

Example

// In this example, there are two modifications ("add") for the method "show()" when trait "T2" is used inside of trait "T1"
class A{
	isA T1;
}
trait T1{
	isA T2 <+show(),+show()>;
}
trait T2{
	void show(){
	//implementation
	}
}

      

Load the above code into UmpleOnline

 

Another Example

// In this example, there are two modifications ("add" and "remove") for the method "show()" when trait "T2" is used inside of trait "T1"
class A{
	isA T1;
}
trait T1{
	isA T2 <-show(),+show()>;
}
trait T2{
	void show(){
	//implementation
	}
}

      

Load the above code into UmpleOnline

 

E212 Methods Not Available

Umple semantic error related to modification of unavailable methods in traits

When traits are used inside classes or traits, it is possible to add or remove provided methods and also to change visibility and their names. This feature is used to resolve conflicts when we do not need some provided methods, just need one of them, need different visibilty, or need a different name. Logically, it is not correct to do these operations on methods which are not available. These problems are detected by the Umple compiler.

Example

// In this example, there is an error because trait "T1" tries to remove method "show()" from trait "T2" while it is not available in trait "T2".
class A{
	isA T1;
}
trait T1{
	isA T2 <-show()>;
}
trait T2{
}

      

Load the above code into UmpleOnline

 

Another Example

// In this example, there is an error because trait "T1" tries to add just method "show()" from trait "T2" to itself while it is not available in trait "T2".
class A{
	isA T1;
}
trait T1{
	isA T2 <+show()>;
}
trait T2{

}

      

Load the above code into UmpleOnline

 

Another Example

// In this example, there is an error in class "A" because it tries to change visibility of method "test()" which is not available in trait T. Consider that the method "test()" defined in trait "T" is a required method.
class A{
	isA T;
}
trait T{
	void test();
}

      

Load the above code into UmpleOnline

 

E213 Removing While Renaming

Umple semantic error related to removing a method from a trait while changing its name

When traits are used inside of classes or traits, it is possible to add or remove provided methods and also to change their visibility and names. This feature is used to resolve conflicts. In fact, it is used when we do not need some provided methods, we just need one of them, we need different visibilty, or we need a different name. Logically, it is not correct to remove a method while renaming it because the second operation is not going to happen.

Example

// In this example, there is an error because class "A" tries to remove method "show(String)" while it tries to change its name. This is a contradiction.
class A{
	isA T1<+show(Integer), -show(String) as t >;
}
trait T1{
	void show(String str){
	//Implementation
	}
	void show(Integer inData){
	//Implementation
	}
	void show(String str,Integer inData){
	//Implementation
	}
}

      

Load the above code into UmpleOnline

 

E214 Two Identical Parameter Names

Umple semantic error related to having two identical template parameter names

When defining traits, it is possible to define template parameters for traits. The names of these parameters should be unique in order to let the compiler perform the correct binding for them. Therefore, when there are two or more template parameters, the Umple compiler detects it as an error.

Example

// In this example, there is an error because class "A" tries to remove method "show(String)" while it tries to change its name. This is a contradiction.
class A{
	isA T1<+show(Integer), -show(String) as t >;
}
trait T1{
	void show(String str){
	//Implementation
	}
	void show(Integer inData){
	//Implementation
	}
	void show(String str,Integer inData){
	//Implementation
	}
}

      

Load the above code into UmpleOnline

 

E215 Template Parameter Not Available

Umple semantic error related to binding a template parameter of a trait which is not available

When using traits, we can bind values for template parameters. In the process of binding, we can just refer to parameters which are available. The Umple compiler detects cases in which there are template parameters not defined a trait.

Example

// In this example, there is an error because class "A" tries to remove method "show(String)" while it tries to change its name. This is a contradiction.
class A{
	isA T1<+show(Integer), -show(String) as t >;
}
trait T1{
	void show(String str){
	//Implementation
	}
	void show(Integer inData){
	//Implementation
	}
	void show(String str,Integer inData){
	//Implementation
	}
}

      

Load the above code into UmpleOnline

 

E216 Twice Binding of a Parameter

Umple semantic error related to binding a template parameter twice

When using traits, we can bind values for template parameters. In the process of binding, we can bind two values for a template parameters. This bring a case in which there is no clear binding. The Umple compiler detects this case and prevents the system from being complied.

Example

// In this example, there is an error because there is two bindings for template parameter "X" in class "A"
class A{
	isA T< X = B , X = C >;
}
Class B{
	//elements
}
Class C{
	//elements
}
trait T{
	//elements
}

      

Load the above code into UmpleOnline

 

E217 Conflict in Types of Attributes

Umple semantic error related to having an attribute from a trait with different types

We can define template parameters for traits and use them with different bindings in several hierarchy paths. If types of some attributes are based on template parameters, there is a case in which those are bound with different values. In a case that a trait is going to be used in a diamond form of hierarchy, this can result in a conflict. Note that if the types are the same, then there is no conflict.

Example

// In this example, there is a conflict because in trait "T" there will be two attributes with the same name "data" but with different types which are "B" and "C".
class A{
	isA T;
}
class B{
	//elements
}
class C{
	//elements
}
trait T{
	isA T1;
	isA T2;
}
trait T1{
	isA Share;
}
trait T2{
	isA Share;
}
trait Share {
	Type data;
}

      

Load the above code into UmpleOnline

 

W218 Conflict in Attributes

Umple semantic error related to having an attribute with the same name in a traits and a class

When classes uses traits, all attributes in traits are flattened in classes. Therefore, if there are attributes with the same name, they might create a conflict. The Umple compiler considers this as a warning because it is the developers responsibilty to decide about the nature of the conflict. Sometimes, developers indicate exactly the same attributes and therefore there is no need to consider the conflict as an error. However, generally, if there are some attributes in host classes which traits need to use them, traits define them as required methods (needed accessors). In this case, host classes need to have accessors for those attributes. In the case of this warning, the Umple compiler just removes one of those attributes and proceeds.

Example

// In this example, there is a warning because in class "A" there will be two attributes with the name called "name".

class A{
	isA T;
	name;
}
trait T{
	name;
}


      

Load the above code into UmpleOnline

 

Another Example

// In this example, there is a warning because in trait "T" there will be two attributes with the name called "name".
class A{
	isA T;
}
trait T{
	isA T1;
	name;
}
trait T1{
	name;
}


      

Load the above code into UmpleOnline

 

E219 No Binding for Parameters

Umple semantic error related to having two same template parameter names

When defining traits, it is possible to define template parameters for traits. It means when traits with template parameters are going to be used by classes or traits, they must bind values for the parameters. If there is no binding for a parameter, the Umple compiler raises an error and shows which parameter doesn't have a value.

@@example @@source manualexamples/E219NoBindingParameters.ump @@endexample @@example @@source manualexamples/E219NoBindingParameters1.ump @@endexample

E220 Two Methods With the Same Name

Umple semantic error related to changing name of a provided method in traits to one which already exists

When changing the name of provided methods in traits, it is necessary to be sure that there are no other methods with the same names that come from other traits. If the changed name already exists inside of a class, in this case there is no problem becase methods of classes have priority over ones coming from traits. In this case, the method from traits will be disregarded. Otherwise, there is a conflict on the name of methods. The Umple compiler detects this case and raises the error

Example

// In this example, there is an error because in class "A" there will be two methods with the name "ShowInConsole".
class A{
	isA T;
}
trait T{
	isA T1;
	void show(){/*T*/}
}
trait T1{
	void ShowInConsole(){/*T1*/}
}

      

Load the above code into UmpleOnline

 

Another Example

// In this example, there is an error because in class "A" there will be two methods with the name "ShowInConsole".
class A{
	isA T;
	isA T1;
}
trait T{
	void show(){/*T*/}
}
trait T1{
	void ShowInConsole(){/*T1*/}
}

      

Load the above code into UmpleOnline

 

Another Example

// In this example, there is an error because in class "A" method "ShowInConslole" has high priority.
class A{
	isA T;
	isA T1;
	void ShowInConsole(){
	//Implementation 
	}  
}
trait T{
	void show(){
	//Implementation
	}
}
trait T1{
	void ShowInScreen(){
	//Implementation
	}
}

      

Load the above code into UmpleOnline

 

W901 Deprecated Keyword Constant

Umple warning reported when deprecated keyword "constant" is used.

The keyword "constant" is still supported in Umple interfaces due to legacy reasons. However, there is no guarantee that this keyword will be supported in the future. The keyword "const" should be used instead.

Example

// This causes the warning
interface Y {
  constant A=5;
}

      

Load the above code into UmpleOnline

 

Another Example

// This does not cause the warning
interface Y {
  const A=5;
}

      

Load the above code into UmpleOnline

 

W1002-3 Unexpected Embedded Code

Umple warning reported when embedded code is found in a native language like Java, PHP or C++, yet 'strictness' has been set indicating this should not occur.

If strictness is set to 'modelOnly', this means that the developer intends to only include classes, associations, state machines and other modeling elements, but not embedded code in another programming language, not even method bodies.

If strictness is set to 'noExtraCode', it is the same as the above, except that method bodies are allowed.

This warning is issued when strictness has been set to one of the above, yet Umple has encountered sytax that interprets as either a method body or some other code in a class that it cannot parse, and is assuming it is native code to be passed to the native compiler.

This warning can often happen when the programmer/modeler wrote Umple code with a syntax error, so Umple thinks it is not Umple, but some other language. Here are some things to try in order to resolve this warning:

Example

// The following example shows how to generate this warning.
strictness modelOnly;
class X {
  public static void main() {
    System.out.println("Hello World");
  }
}

      

Load the above code into UmpleOnline

 

E1004-5 Messages not as Expected

Umple errors reported when an expected message is not found or a disallowed message is found.

The strictness clause with 'expected' can be used to indicate that a certain message is expected. An error occurs when the expected warning or error does not actually occur.

Similarly, the strictness clause with 'disallowed' can be used to indicate that a certain message is not expected. An error occurs when the expected warning or error does occur.

W1006 State Machine Not Parsed

Umple semantic warning reported when a state machine could not be fully parsed and is treated as 'extra code'.

In Umple, elements of a class not recognized as valid Umple are assumed to be elements of the target programming language that are embedded in the Umple. However, this warning is raised when the Umple compiler has reason to believe that the developer might have been trying to specify a state machine, because the segment of code starts with something like sm {.

Since that sequence is not found in target languages, and since it is easy to make a mistake specifying states, substates, or events, this message is generated. If you encounter this message and indeed intended to specify a state machine, look carefully at the state machine code. Make sure the curly brackets match; make sure there are semicolons after transitions (unless the transitions have an action). If you are still stuck, comment out segments until you can narrow down the problem.

@@example @@source manualexamples/W1006StateMachineNotParsed1.ump @@endexample

W1007 Element Not Parsed

Umple semantic warning reported when a when Umple finds an un-parsable element in a class, which is likely a malformed attribute or association declaration.

Umple emits such elements 'as is' as 'extra code' in its generated code, in case they are some part of the base language that Umple cannot understand

Example

// The following will generate two such warnings
class X {
  blah blah blah;
  1 - * X;
}

      

Load the above code into UmpleOnline

 

W1008 Method Not Parsed

Umple semantic warning reported when a method could not be fully parsed and is treated as 'extra code'. The method will still be emitted and can be called, but Umple cannot analyse it.

In Umple, elements of a class not recognized as valid Umple are assumed to be elements of the target programming language that are embedded in the Umple. However, this warning is raised when the Umple compiler has reason to believe that the developer might have been trying to specify a method, but omitted some aspect.

Note that currently, Java main methods generate this warning. It can be safely ignored in that context, and the warning will eventually be removed.

Example

// This example generates the warning because there is a missing return type
class X {
  m() {}
}


      

Load the above code into UmpleOnline

 

W1011 Invalid Association Class Key

Umple semantic warning reported when an Association Class key is missing a required member.

For Association Classes with explicit keys, each class that participates in the relationship should be declared as a member of that key.

Example

// This example generates the warning because one participating class is missing from the key
class Passenger {}

class Flight {}

associationClass Booking {
  Integer number;
  * Passenger passenger;
  * Flight flight;
  key {number, flight}
}


      

Load the above code into UmpleOnline

 

Another Example

// This example shows how to remove the warning by completing the key
class Passenger {}

class Flight {}

associationClass Booking {
  Integer number;
  * Passenger passenger;
  * Flight flight;
  key {number, flight, passenger}
}


      

Load the above code into UmpleOnline

 

E15xx Parsing Error

Umple error messages reported when the Umple parser can't interpret the code.

These messages occurs in several contexts:

E1510 Use File Missing

Umple error messages reported when a use statement refers to a file that cannot be loaded.

The argument to a use statement must be a valid .ump file found in the same directory as the file with the use statement, or in its parent directory, or in a subdirectory named lib.

Check the spelling of the filename, and check file permissions.

W20xx Error in Embedded Code

Umple warning issued when a base language compiler encounters a non-umple error

Under development: Umple can have code in any programming language embedded in method bodies or other constructs. This warning is issued when the compiler for the embedded language reports an error. This can occur of the -c option is supplied to the Umple compiler, telling it to invoke the base language compiler after the Umple is generated.

Page Being Developed

You most likely encountered an error or warning in UmpleOnline, and clicking on the message displayed this page. The web page explaining that message has not yet been created. In the meantime, you can search the manual or browse the links on the left.

W9999 Feature Under Development

Umple warning reported a feature is used that is not yet fully implemented in Umple

Features are often added to the syntax of Umple before they are added to the semantics and code generation. This is to ensure that adding the feature will not break existing code. If you receive this warning, then it means you are using such a feature. No code is yet generated from this feature, or else the generated code is incomplete.