JavaScript is disabled so the dynamic features of this page will not work. To use UmpleOnline, turn Javascript on. Otherwise you can download the command-line Umple compiler or use Eclipse.
/*
Copyright: All contributers to the Umple Project
This file is made available subject to the open source license found at:
https://umple.org/license
The main Umple metamodel.
*/
namespace cruise.umple.compiler;
external interface Runnable {}
external Position{}
external Token{}
external RuleBasedParser{}
/*
* Class UmpleModel is the central class describing the system being compiled.
*
* The model contains everything that was derived from an Umple file (.ump) when it was parsed such as
* the classes, attributes, associations, state machines, methods, etc that were in it.
*
* Put another way, when an Umple file (.ump) is parsed an Umple model is populated with everything that was parsed from that file.
*
* Because of this it is absolutely critical to understand the model since it is basically the "root" of everything.
*/
class UmpleModel
{
depend java.io.*;
depend cruise.umple.analysis.*;
depend cruise.umple.util.*;
depend cruise.umple.compiler.exceptions.*;
depend cruise.umple.parser.*;
depend cruise.umple.parser.analysis.*;
depend java.util.zip.*; // new
isA Runnable;
// The Umple file (.ump) that was used to populate the model.
UmpleFile umpleFile;
// Variables used for distributed code control
Boolean distributeOn=true;
Boolean distributeForced=false;
Boolean distributed=false;
// Variables used to advise not to bother trying to compile various language
// because the code doesn't contain coherent or complete code.
// These are set to true when various @@@skip directives are found in comments
Boolean skipcompile=false;
Boolean skipjavacompile=false;
Boolean skippythoncompile=false;
Boolean skipcppcompile=false;
Boolean skiprubycompile=false;
Boolean skipphpcompile=false;
Integer distributePattern=0;
String distributeTechnology="RMI";
defaultPackage = null;
GenerateTarget[] generates;
Boolean shouldGenerate = true;
Glossary glossary = new Glossary();
String defaultNamespace = null;
String code = null;
UmpleClass mainClass = null;
Boolean debugMode = false;
ParseResult lastResult = null;
public static final String[] validLanguages = findValidLanguages();
Map generatedCode = new HashMap();
Map analyzers = new HashMap();
// The core list of all requirement in this Model s found while parsing
Map allRequirements = new HashMap();
// The core list of all requirement implementation annotations found while parsing.
* -> * ReqImplementation reqImplementations;
// data for default class positioning
internal Coordinate levelOffset = new Coordinate(200,100,0,0);
internal Coordinate initialOffset = new Coordinate(50,30,0,0);
internal Coordinate classSize = new Coordinate(0,0,109,45);
internal int maxYLevels = 5;
// Top level blocks code contained within a model.
// extraCodes will be generated in a single file
lazy CodeBlock[] extraCodes;
// data for default association positioning
internal Coordinate offsetFromEdge = new Coordinate(10,30,0,0);
internal int reflexiveSegmentLength = 15;
internal List linkedFiles = new ArrayList();
// Whether tracer output should be generated if needed
// These are set to false when tracer classes are created by generators
Boolean generateConsole = true;
Boolean generateFile = true;
Boolean generateString = true;
Boolean generateLog4j = true;
// The Umple Enumerations contained within the model
1 -> * UmpleEnumeration enums;
// The Associations contained within the model.
1 -> * Association;
// The Umple Classes contained within the model.
1 -> * UmpleClass;
// The Umple Traits contained within the model.
mixset Trait {
1 -> * UmpleTrait;
}
// The Umple Templates contained within the model.
1 -> * UmpleTemplate;
// The State Machines contained within the model.
mixset StateMachine {
1 -> * StateMachine stateMachineDefinitions;
}
// The Umple interfaces contained within the model.
1 -> * UmpleInterface;
// Suboptions that might be added by the suboption command;
lazy String[] availableSuboptions;
before addGenerate(GenerateTarget) {
for (String so : availableSuboptions) {
aGenerate.addSuboption(so);
}
}
}
/*
* An UmpleElement is one of the top-level items found in an Umple model
* Currently it has one subclass, UmpleClassifier
*/
class UmpleElement
{
depend cruise.umple.parser.Position;
// The name of the Umple element.
name;
// The position(s) of the element in the source code, used in debugging
// may have multiple positions in the case of mixins
1 -> 0..* Position positions;
1 -> 0..* Position endPositions; // Kept aligned with positions
// The modifier associated with the Umple element.
modifier = null;
Boolean hasMainMethod = false;
String[] namespaces;
NameSpace nameSpace = new NameSpace("",new Position("", 0, 0, 0));
packageName = "";
// The code associated with the Umple element.
internal ExtraCode extraCode = new ExtraCode();
// Specifies whether or not the Umple element is internal.
Boolean isInternal = false;
// Specifies the position of this Umple element (ex. The UmpleOnline diagram).
Coordinate coordinates = new Coordinate(-1,-1,-1,-1);
// Specifies the display color of this element
String displayColor = "";
before setPackageName { if (aPackageName == null) { return false; } }
// Methods to distinguish the subclass types
boolean isUmpleClass() {return false;}
boolean isUmpleInterface() {return false;}
mixset Trait {
boolean isUmpleTrait() {return false;}
}
}
/*
* A method in an Umple class or interface
* Umple Methods are coded by the programmer in the language(s) of their choice
*/
class Method
{
depend cruise.umple.parser.Position;
// Specifies whether or not the Method is abstract.
Boolean isAbstract = false;
// Specifies whether this is a constructor for the Umple class.
Boolean isConstructor = false;
// Specifies whether or not the method is queued.
Boolean isQueued = false;
// The modifier associated with the method.
modifier;
// The name of the method.
name;
// Throws exceptions
String[] exceptions;
lazy Position position;
lazy Position codePosition;
lazy Position endPosition;
// The type of the method.
type;
// Specifies whether or not the method is implemented.
Boolean isImplemented;
//This supposed to show from where this method came.
//fTrait means it comes from traits.
//fAuto means it comes from auto generation mechanism.
//fAutoAPI means it comes from auto generation mechanism to represent API methods at the model level.
source {none,fTrait,fAuto,fAutoAPI}
// The method parameters.
1 -> 0..* MethodParameter;
// The body of the method (such as the code within).
1 -> 0..1 MethodBody;
// The comments associated with the method (such as the Javadoc above it).
1 -> * Comment;
//The requirement ids implemented within the method.
1 -> * ReqImplementation;
// Specifies, for fAutoAPI methods, if the method was generated
Boolean wasGenerated = false;
}
/*
* The contents of a method, such as the code within it.
*/
class MethodBody
{
depend java.util.*;
depend cruise.umple.parser.Position;
// The code within the method body.
extraCode = {codeblock.getCode() != null ? codeblock.getCode() : ""}
CodeBlock codeblock;
Map implementationPositions = new HashMap();
//the method assertions
1 -> * UmpleAssertion;
0..1 -- * UmpleTestCase;
}
/*
* The assertion within the method or class.
*/
class UmpleAssertion {
name;
type;
level;
action;
assertCode;
int locOrder;
boolean isTimed = false;
}
/*
* Test Case at the Class level .
*/
class UmpleTestCase {
name;
int locOrder;
boolean isTimed = false;
boolean isOverride = false;
boolean isConcrete = false;
String concreteLang = "";
0..1 -- * UmpleAssertion;
0..1 -- * TestAction;
0..1 -- * TestInit;
Map bodyCode = new HashMap();
}
// test action statements
class TestAction{
name;
actionCode;
type;
int locOrder;
}
class TestParameter {
String value;
String type;
String name;
}
class TestSequence {
name;
String[] tests = null;
//0..1 -- 1 UmpleClass;
}
//initialization statements in test that holds
// identifier objectname (parameters);
class TestInit{
identifier;
objectName;
code;
0..1 -- * TestParameter;
}
/*
* Represents a constant.
*/
class Constant
{
// The name of the constant.
name;
// The type of the constant.
type;
// The modifier of the constant.
modifier;
// The value of the constant.
value;
//Issue 322 - by default set internal to false
Boolean isInternal = false;
// Commented out to prevent conflict with extending UmpleVariable
// Previously, this extends would be overwritten, but Issue 1159 changes it to cause error 34
// class UniqueIdentifier { }
}
/*
* Represents a parameter in a method and its various forms.
*/
class MethodParameter
{
isA UmpleVariable;
// Specifies whether or not the method parameter is auto unique.
Boolean isAutounique; // TODO: should default to false, but constructors would need updating
// Specifies whether or not the method parameter is a list.
Boolean isList = false;
// Specifies whether or not the method parameter is derived.
Boolean isDerived = false;
// Specifies whether or not the method parameter is lazy.
Boolean isLazy = false;
// Specifies whether or not the method parameter is ivar.
Boolean isIvar = false;
}
/*
* ConstraintVariables encapsulate that data of one element in a ConstraintTree, making up the nodes of that tree.
* For example: a<3
* has the structure: ConstraintTree
* ConstraintOperator(<)
* / \
* ConstraintTree ConstraintNumberLiteral(3)
* ConstraintAttribute(a)
* where all the "Constraint" classes inherit from ConstraintVariable
*/
class ConstraintVariable
{
/*
* ConstraintTrees are a redundant class that are necessary because of lone constraints, i.e. [true] has to be handled, and does not contain an operator
* If lone constraints didn't exist then the ConstraintTree class could be condensed into ConstraintOperator. One nice religation of responsibilities is that ConstraintTrees take care of the ! and () symbols, leaving the ConstraintOperator class to be more pure
*/
class ConstraintTree
{
depend cruise.umple.compiler.*;
depend cruise.umple.parser.Token;
depend java.util.*;
ConstraintVariable root = null;
ConstraintOperator requestor = null;
TreeSet names = new TreeSet();
boolean shouldDisplayBrackets = false;
boolean displayNegation = false;
boolean displayBrackets = { shouldDisplayBrackets||(displayNegation&&numberOfElements>1) }
int numberOfElements = 0;
key { root }
/*
* TraceConstraint objects ensure that the attribute being traced will be treated as a parameter and not a member variable
*/
class TraceConstraint
{
1 -> * UmpleVariable variables;
}
/*
* The Preconditions are constraints on methods, restricting the method so that it does not process if the constraint is not satisfied.
*/
class Precondition
{
* -> 1 Method ; // The method precondition belongs to
// The method's bodies ("" for the untagged one) whose block declares this precondition
String[] bodyLanguages;
}
/*
* The Preconditions are constraints on methods, throughing an exception if the constraint is not sastisfied after the method has computed.
*/
class Postcondition
{
depend cruise.umple.parser.Position;
* -> 1 Method ; // The method postcondition belongs to
lazy Position position;
// The method's bodies ("" for the untagged one) whose block declares this postcondition
String[] bodyLanguages;
}
}
/*
* ConstraintOperators encapsulate the branching of the constraint tree, where the branches occur at the operators, for example
* [a<3&&b!="loved"]
* the basic structure will look like
* ConstraintOperator(&&)
* / \
* ConstraintOperator(<) ConstraintOperator(!=)
* / \ / \
* ConstraintAttribute(a) ConstraintNumberLiteral(3) ConstraintAttribute(b) ConstraintLiteral("loved")
* With the extra complication that ConstraintTrees parent everything that are not ConstraintLiterals
*/
class ConstraintOperator
{
value;
1 -> 0..2 ConstraintVariable subConstraints;
ConstraintVariable left = { numberOfSubConstraints()>0?getSubConstraint(0):null }
ConstraintVariable right = { numberOfSubConstraints()>1?getSubConstraint(1):null }
key { left, right, value }
}
/*
* ConstraintLiterals encapulate raw data literals, such as strings, numbers and booleans, that do not have an model variable associated.
* This will be a leaf in the constraint tree.
*/
class ConstraintLiteral
{
value;
/* Number literals are the special case of literals, where the value they contained is garanteed to be a number. */
class ConstraintNumberLiteral
{
}
key { value }
}
/*
* This super class contains all subclasses that have elements with names
*/
class ConstraintNamed
{
abstract;
/*
* The reason d'etre of this super class, it ensures that subclasses have getName methods
*/
public abstract String getName();
/*
* ConstraintAttributes encapsulate the attribute for the constraint, this will be a leaf on the constraint tree
*/
class ConstraintAttribute
{
Attribute attribute;
index = -1;
key { attribute }
}
/*
* ConstraintAttributes encapsulate the association for the constraint, this will be a leaf on the constraint tree.
*/
class ConstraintAssociation
{
AssociationVariable association;
index = -1;
numberOf = false;
key { association }
}
/*
* ConstraintMethodParameters are there for Preconditions and Postconditions, they encapsulate the MethodParameter that the constraint is refering to
* This will be a leaf on the constraint tree.
*/
class ConstraintMethodParameter
{
MethodParameter parameter;
key { parameter }
}
/*
* ConstraintUnassignedNames are names that were not recognized by the analysis, for example ConstraintMethodParameters are originally ConstraintUnassignedNames,
* but are caught when they are added to the Precondition or Postcondition and a ConstraintMethodParameter is added instead of the ConstraintUnassignedName.
*/
class ConstraintUnassignedName
{
value;
key { value }
}
/*
* ConstraintStates encapsulate the state data in a statemachine expression such as [sm is in state st], this is a leaf in the constraint tree/
*/
class ConstraintState
{
mixset StateMachine {
State state;
key { state }
}
}
/*
* ConstraintStateMachines encapsulate the statemachine data in a statemachine expression such as [sm is in state st], this is a leaf in the constraint tree.
*/
class ConstraintStateMachine
{
mixset StateMachine {
StateMachine stateMachine;
key { stateMachine }
}
}
/*
* ConstraintPort encapsulate the statemachine data in a port watch expression
*/
class ConstraintPort
{
Port port;
key { port }
}
}
}
/*
* A block of code in an arbitrary language to be injected into generated code
* Please update the method 'public CodeBlock(CodeBlock another)' if you add new attributes.
*/
class CodeBlock
{
depend java.util.*;
internal HashMap codes = new HashMap();
// The languages whose code was written in the model ("" is the untagged body), each mapped to the
// indentation of the code's first line in the source and to where the code starts there (see
// setAuthoredCode, getFirstLineIndent and getAuthoredPosition)
internal HashMap authoredIndents = new HashMap();
internal HashMap authoredPositions = new HashMap();
// The guards, as untagged code, of the guarded trait actions composed into the Python code with
// superCall, by the placeholder that stands for each condition there (see pythonTraitCode)
internal HashMap pythonTraitGuards = new HashMap();
// The trait code without a Python version composed into the Python code with superCall, by the
// placeholder line that stands for it there; the generator renders it as any other code slot
internal HashMap pythonTraitBlocks = new HashMap();
public static String languageUsed = "";
lazy String name;
}
/*
* A block of code that can be injected into one or more methods, constructor, etc.
*/
class CodeInjection
{
depend cruise.umple.parser.Position;
depend cruise.umple.util.*;
type;
operation;
operationSource = "generated";
lazy String[] parameters;
CodeBlock snippet;
lazy constraintParameterName;
* -> 1 UmpleClassifier;
1 -> 0..1 ConstraintTree;
lazy Position position;
lazy Position codePosition;
Boolean isInternal = false;
// Written with around; one without code labels has type before, which Java splits at around_proceed:
Boolean isAround = false;
}
class ExtraCode
{
internal CodeBlock[] code;
}
/*
*
* A key in a class is a set of attributes associations used to uniquely identify an object
*/
class Key
{
Boolean isDefault = false;
Boolean isInternal = false;
String[] members;
}
/*
* Represents an enumeration
*/
class UmpleEnumeration
{
depend cruise.umple.parser.Position;
name;
String[] enumValues;
1 -> 0..1 Position;
1 -> * ReqImplementation;
}
/*
* Represents an Umple classifier: a Class or Interface
*/
class UmpleClassifier
{
abstract;
isA UmpleElement;
depend cruise.umple.parser.Token;
// The methods contained within the Umple Classifier.
1 -> 0..* Method;
* -> * Depend;
// Specifies whether or not the Umple class or implemented classes are distributable with RMI technology.
Boolean isDistributable = false;
String distributeTechnology="RMI";
UmpleModel sourceModel;
// The constants contained within the Umple Classifier.
1 -> 0..* Constant;
1 -> 0..* ModelConstraint;
* -> 0..1 Token extendsToken;
}
/*
* Represents a interface.
* Like a class, but can't have any concrete methods, attributes or associations.
*/
class UmpleInterface
{
isA UmpleClassifier;
* -> 0..* UmpleInterface extendsInterface;
// The comments associated with the Umple Interface (such as the Javadoc above it).
1 -> * Comment;
//The requirement ids implemented within the Umple Interface.
1 -> * ReqImplementation;
0..1 -- * UmpleTestCase;
before setPackageName { if (aPackageName == null) { return false; } }
before addDepend { if (depends.contains(aDepend)) { return false; } }
boolean isUmpleInterface() {return true;}
}
/*
* An UmpleClass can contain attributes, associations, state machines and methods.
* It can also have various other information such as a key (to identify uniqueness),
* code to inject into generated code, and comments. It can be tagged with various
* patterns, such as 'singleton', meaning that there can only be one instance,
* and abstract, meaning it can't have any instances.
*/
class UmpleClass
{
depend cruise.umple.util.*;
isA UmpleClassifier;
Boolean hasProxyPattern = false;
Boolean needsDefaultInterface=false;
Boolean isDistributed = false;
Boolean isInternalSerializable = false;
Boolean isDefaultInterfaceRemoteRMI=false;
// dependency handling attributes
Integer level = 0;
Boolean isInitialized = false;
// Specifies whether or not the Umple class is an abstract class.
Boolean isAbstract = false;
// Specifies whether or not the Umple class is a singleton.
Boolean isSingleton = false;
Association[] associations;
// List of candidate methods that were not added to the class
Method[] unimplementedMethods;
Key key = new Key();
// Specifies whether or not the Umple class is immutable.
internal Boolean iAmImmutable = false;
internal Boolean ancestorIsImmutable = false;
1 -> * CodeInjection;
// Enumerations that belong to the Umple Class
1 -> * UmpleEnumeration enums;
//The possible Preconditions related to the Umple Class
1 -> 0..* Precondition preConds;
//The possible Preconditions related to the Umple Class
1 -> 0..* Postcondition postConds;
//Umple Test Case at the class level
0..1 -- 0..* UmpleTestCase;
// class test sequence for testcases
0..1 -- 0..* TestSequence;
// class test initialization: inits at the top level
0..1 -- 0..* TestInit;
// The possible Constraints related to the Umple Class
1 uClass -> 0..* ConstraintTree;
// The Umple Class's super class (if there is one).
* subclasses -- 0..1 UmpleClass extendsClass;
//isStatic if the inner class is static
// The inner classes contained within the Umple class.
0..1 outerClass -- 0..* UmpleClass innerClasses;
boolean isStatic = false;
//disable methods from being auto-generated by Umple.
String[] disableAutogeneratedMethodList = new ArrayList();
* subClasses -- * UmpleTrait extendsTraits;
* subClasses -- * UmpleTemplate extendsTemplates;
* -> 0..* UmpleInterface parentInterface;
1 -> 0..1 UniqueIdentifier;
// The attributes contained within the Umple class.
1 -- * Attribute;
// The associations contained within the Umple class.
0..1 -- * AssociationVariable;
// The comments associated with the Umple Class (such as the Javadoc above it).
1 -> * Comment;
//The requirement ids implemented within the class.
1 -> * ReqImplementation;
//This is used to assign inheritance parameters.
1 -> * GeneralTPApplied;
before addDepend { if (depends.contains(aDepend)) { return false; } }
//---before setImmutable { if (!canBeImmutable()) { return false; } }
before addAssociationVariable { if (!immutabilityAssociationRulesSatisfied(aAssociationVariable, this.isImmutable())) { return false; } }
before setExtendsClass { if (!enforceImmutabilityInheritanceRules(aExtendsClass)) { return false; } }
mixset StateMachine {
before addStateMachine { if (isImmutable()) { return false; } }
}
boolean isUmpleClass() {return true;}
}
/*
* An UmpleTrait can contain attributes, associations, state machines and methods.
* It can also have various other information such as a key (to identify uniqueness),
* code to inject into generated code, and comments. It can be tagged with various
* patterns.
*/
class UmpleTrait {
depend cruise.umple.util.*;
isA UmpleClassifier;
// Specifies whether or not the Umple class is an abstract class.
Boolean isAbstract = false;
// Specifies whether or not the Umple trait is a singleton.
Boolean isSingleton = false;
Association[] associations;
// List of candidate methods that were not added to the Trait
Method[] unimplementedMethods;
Key key = new Key();
// Specifies whether or not the Umple trait is immutable.
internal Boolean iAmImmutable = false;
internal Boolean ancestorIsImmutable = false;
1 -> * CodeInjection;
//The possible Preconditions related to the Umple Trait
1 -> 0..* Precondition preConds;
//The possible Preconditions related to the Umple Trait
1 -> 0..* Postcondition postConds;
// The possible Constraints related to the Umple Trait
1 uTrait -> 0..* ConstraintTree;
// The Umple Trait's super Traits (if there are ones).
* subTraits -- 0..* UmpleTrait extendsTraits;
1 -> 0..1 UniqueIdentifier;
// The attributes contained within the Umple trait.
0..1 -- * Attribute;
// The associations contained within the Umple trait.
0..1 -- * AssociationVariable;
// The comments associated with the Umple Trait (such as the Javadoc above it).
1 -> * Comment;
// The requirement associated with the Umple Trait (such as the Javadoc above it).
1 -> * ReqImplementation;
//The template parameters which are specified when traits are defined.
1 -> * GeneralTemplateParameter;
//This is used to assign inheritance parameters.
1 -> * GeneralTPApplied;
//This is used to assign required interfaces
1 -> * UmpleInterface requiredInterfaces;
//trait test cases
0..1 -- * UmpleTestCase;
//--- before addDepend { if (depends.contains(aDepend)) { return false; } }
//--- before setImmutable { if (!canBeImmutable()) { return false; } }
//--- before addAssociationVariable { if (!immutabilityAssociationRulesSatisfied(aAssociationVariable, this.isImmutable())) { return false; } }
//--- before setExtendsTrait { if (!enforceImmutabilityInheritanceRules(aExtendsClass)) { return false; } }
mixset StateMachine {
before addStateMachine { if (isImmutable()) { return false; } }
}
boolean isUmpleTrait() {return true;}
}
//This class is used to specify parameters for traits.
//TODO : when can also apply this to support formal template concepts for classes.
class GeneralTemplateParameter {
name;
type;
String[] interfacesAndClass;
defaultValue = "";
}
//This class is used to assign parameters in classes and traits.
class GeneralTPApplied {
depend cruise.umple.parser.Position;
inheritanceName;
String[] parameters;
1 -> 0..1 Position positions;
1 -> * MethodTemplateSignature;
mixset StateMachine {
1 -> * StateMachineTemplateSignature;
1 -> * StateMachineModifier;
}
}
class MethodTemplateSignature{
modifier;
1 -> 1 Method;
alias;
}
mixset StateMachine {
class StateMachineTemplateSignature{
modifier;
srcStateMachine;
desStateMachine;
String[] srcStates;
String[] desStates;
0..1 -> 0..1 MethodTemplateSignature;
alias;
}
class StateMachineModifier{
modifier;
srcStateMachine;
alias;
}
//This is used to remove and rename a state.
class StateModifier{
isA StateMachineModifier;
String[] srcStates;
}
//This is used to remove an event or a transition.
class EventModifier{
isA StateModifier;
0..1 -> 0..1 Method;
0..1 -> 0..1 Guard;
// Token guardToken = null;
}
//This is used to extend a state with a state machine.
class ExtendStateByStateMachine{
isA StateMachineModifier;
String[] desStates;
}
}
/*
* A depend relationship indicates a package on which this class depends
*/
class Depend
{
name;
Boolean isInternal = false;
key { name }
}
/*
* A combination of Class and Association (as defined in UML)
* An AssociationClass is a full-fledged class, but at the same time
* It associates two other classes that would otherwise have a many-many
* relationship. Instances of the AssociationClass represent data
* held by the links between those two classes.
*/
class AssociationClass
{
isA UmpleClass;
1 -> 0..2 Association associatedTo;
}
/*
* Superclass for tracking member variables in all target languages
* TODO: Code smell because we have both an association variable and also an association
* This class should go and instead AssociationEnd should be the member variable
*/
class UmpleVariable
{
// The name of the Umple variable.
name;
// The type of the Umple variable.
type;
// The modifier associated with the Umple variable.
modifier; // potential enum, 'settable'
// The value of the Umple variable.
value;
before setName { if (aName == null) { throw new RuntimeException("Name must be set, cannot be null"); } }
before getModifier { if (modifier == null) { return "settable"; } }
after constructor {
if (type==""){
type= "String";
}
}
class UniqueIdentifier { }
}
/*
* Represents an attribute.
* An attribute is more abstract than an instance variable / property in that
* it can be derived, and have various other modifiers such as being
* initialized, lazy (does not appear in constructor and must be initialized
* after construction), etc.
*/
class Attribute
{
depend cruise.umple.parser.Position;
isA UmpleVariable;
// Specifies whether or not the method parameter is auto unique.
// TODO: should default to false, but constructors would need updating
Boolean isAutounique;
// Specifies whether or not the attribute is unique.
Boolean isUnique = false;
// Specifies whether or not the method parameter is a list.
Boolean isList = false;
// Specifies whether or not the method parameter is derived.
Boolean isDerived = false;
// Specifies whether or not the method parameter is internalTransient.
Boolean isInternalTransient = false;
CodeBlock codeblock = new CodeBlock();
after constructor { codeblock.setCode(normalizeValue(aType,aValue)); }
before setType { codeblock.setCode(normalizeValue(aType,getValue())); }
after setType { setValue(getValue()); }
mixset Trace {
before delete {
if (traceRecords == null) {
traceRecords = new ArrayList();
}
}
}
// Specifies whether or not the method parameter is lazy.
Boolean isLazy = false;
Boolean isRefinement = false;
// Specifies whether or not the method parameter is ivar.
Boolean isIvar = false;
//This supposed to show from where this method came.
//fTrait means it comes from traits.
//
source {none,fTrait}
// The comments associated with the attribute (such as the Javadoc above it).
1 -> * Comment;
//The requirement ids implemented within the attribute.
1 -> * ReqImplementation;
// In case this attribute needs to have error handling preformed
1 -> 0..1 Position;
1 -> 0..1 Position endPosition;
}
/*
* Represents an association, typically between two Umple classes (1-1, 1-*, *-1, etc).
* An association in UML/Umple represents a relationship that exists at run time
* where instances of one class reference the other, and (if bidirectional) instance
* of the other class reference the first cass.
* The number of references is governed by the Multiplicity at each AssociationEnd
*/
class Association
{
depend cruise.umple.parser.Position;
// The name of the association.
name = null;
Boolean isLeftNavigable;
Boolean isRightNavigable;
Boolean isLeftComposition;
Boolean isRightComposition;
Coordinate[] positions;
0..1 -- 2 AssociationEnd ends;
Position tokenPosition = null;
Position tokenEndPosition = null;
internal Boolean immutable = false;
Boolean named = { name != null && !"".equals(name) }
// code for specialized associations
// the 0..1 parent -- * specializedAssociations is the code to handle the following:
// parent denotes which association this one is tightening
// specializedAssociations is a list of associations that have specialized this "parent" one
0..1 specializedFrom -- * Association specializedAssociations;
Boolean isSpecialized = false;
Boolean isSpecialization = false;
// name of the class this association shares with its parent
commonClassName = "";
//The source of association
//None: origial
//fTrait: from traits
source {none,fTrait}
before getName { if (!isNamed()) { return this.deriveName(); } }
after constructor { this.setLeftAndRight(); }
// Issue 2098: enable implementsReq to be placed before a top-level association block
1 -> * ReqImplementation;
}
/*
* An association end represents one logical end of an association
*
* See also AssociationVariable
* TODO: Code smell referenceToClassName is a duplication, can access via the association
* Create a derived attribute otherend (the other AssociationEnd)
*/
class AssociationEnd
{
roleName;
className;
modifier; // potential enum 'internal'
referenceToClassName;
Multiplicity multiplicity;
Boolean isDefaultRoleName = false;
String priority = "";
// relevant to specializations
String superClassName = "";
Boolean needsCommonCode = false;
Boolean needsSuperCode = false;
Boolean mulChangedToOne = false;
Boolean mulChangedToN = false;
Boolean reqSetCode = false;
key { multiplicity, roleName, className, modifier, referenceToClassName }
//modifier { Settable, Immutable, Internal, Defaulted, Constant }
before getRoleName { if (roleName == null) { return ""; } }
before getClassName { if (className == null) { return ""; } }
before getModifier { if (modifier == null || "".equals(modifier)) { return "internal"; } }
before getReferenceToClassName { if (referenceToClassName == null) { return ""; } }
}
/*
* An association variable represents one of the variables used to represent
* an association. In a two-directional association (navigable) there would
* be one of these in each associated class.
*
* See also AssociationEnd
*
* TODO: Code smell. Should be replaced by the 'otherEnd' of the AssociationEnd
*/
class AssociationVariable
{
isA UmpleVariable;
Multiplicity multiplicity;
immutable Boolean isNavigable;
Boolean isComposition = false;
String priority = "";
0..1 self relatedAssociation;
// specialized from this association variable
AssociationVariable specializedFromVariable = null;
// code relevant to specialization of associations
Boolean isSpecialized = false; // is it ever specialized?
Boolean isSpecialization = false; // is it a specialization of another?
commonClassName = "";
superClassName = "";
int relevantEnd = 0; // 0 to ensure that everything doesn't break
Boolean needsSuperCode = false;
Boolean needsCommonCode = false;
Boolean mulChangedToOne = false;
String scName = "";
Boolean mulChangedToN = false;
Boolean reqSetCode = false;
// The comments associated with the association (such as the Javadoc above it).
1 -> * Comment;
//The requirement ids implemented within the association variable.
1 -> * ReqImplementation;
before setUmpleClass { if ((aUmpleClass != null) && !aUmpleClass.immutabilityAssociationRulesSatisfied(this, aUmpleClass.isImmutable())) { return false; } }
before setRelatedAssociation { if(!canBeRelatedAssociation(aNewRelatedAssociation)) { return false; }}
}
/*
* A multplicity constrains the number of linked objects at one end of an
* association
*
* TODO: extract derived attributes from Umple_Code.ump (getLowerBound etc.)
*/
class Multiplicity
{
depend cruise.umple.util.*;
lazy bound; // used when minimum=maximum;
lazy minimum;
lazy maximum;
parserable = { getBound() != null ? getBound() : ( (getMinimum() == null || getMinimum().equals("0")) && (getMaximum() == null || getMaximum().equals("*")) ? "*" : ""+ getMinimum() + ".." + getMaximum()) }
key { bound, minimum, maximum }
}
// TODO: Code smell: This duplicates the structure of the class from UmpleClass
// This is a problem for model-to-model transformations
// Should be abolished
class GeneratedElement
{
depend java.util.*;
}
/*
* Represents a class that is generated from an Umple class, such as a Java or Cpp class.
*/
class GeneratedClass
{
isA GeneratedElement;
// Generated classes come from an Umple model (which comes from an Umple file), hence many generated classes to one model.
* -> 1 UmpleModel model;
// Generated classes are translated from an Umple class, hence the relation.
0..1 -> 1 UmpleClass uClass;
// Generated classes may have a parent class/super class.
0..1 -> 0..1 GeneratedClass parentClass;
}
//class GeneratedInterface
//{
// isA GeneratedElement;
// //code = null;
// * -> 1 UmpleModel model;
// 0..1 -> 1 UmpleInterface uInterface;
//}
/*
* A point in cartesian coordinates, used in representing the layout of a
* diagram in Umple
*/
class Point
{
Integer x;
Integer y;
key { x, y }
}
/*
* A Coordinate is used in the layout of classes
* It represents the shape of a class box in a diagram
*/
class Coordinate
{
Integer x;
Integer y;
Integer width;
Integer height;
status {Explicit, Undefined, Defaulted}
after constructor { updateStatus(); }
after setX { if(wasSet) updateStatus(); }
after setY { if(wasSet) updateStatus(); }
after setWidth { if(wasSet) updateStatus(); }
after setHeight { if(wasSet) updateStatus(); }
key { x, y, width, height }
}
/*
* Represents a comment, such as those found around classes, methods, attributes and associations.
*/
class Comment
{
depend java.util.*;
// The text associated with the comment.
text;
Boolean annotation = false;
}
/*
* Represents a requirement, such as those found around
* classes, methods, attributes, associations, stateMachines, states, etc.
* If multiple occurrences of a requirement are found, their statements are concatenated
* and a single instance is created.
* If the language of two occurrences differs (and neither is blank) the the latter occurrences
* is ignored with warning 401
* All instances of this class are tracked in the instance of Model
* with the map allRequirements, whose key is the identifier
*/
class Requirement{
depend java.util.*;
depend cruise.umple.parser.Token;
// A unique identifier for this requirement
// Alphanumeric, with -, . and _ allowed
// TODO: add an Umple 'key' statement for this.
identifier;
// The content of the requirement, expressed in the language
statement;
// Structured user story elements
who;
when;
what;
why;
// Structured EARS clauses, null when absent: Where , while ,
// when , if , then the shall
lazy earsWhere;
lazy earsWhile;
lazy earsWhen;
lazy earsIf;
lazy earsSystem;
lazy earsShall;
// The requirements language used to express this requirement
// can be blank, then 'text' is assumed
// Other languages can be added e.g. GRL = Goal Requirement Language
language;
// List of tokens where the requirement was found
// Used when reporting errors regarding missing implementations
// and when reporting where a requirement is located in the code
* -> * Token reqToken;
// Identifiers of other use cases whose steps are incorporated into this one
// Corresponds to the UML include relationship between use cases
String[] includedUseCases;
// Identifiers of use cases that this use case specializes
// Corresponds to UML generalization between use cases
String[] parentUseCases;
// Ordered structured use case steps such as userStep/systemResponse
1 -- * UseCaseStep;
// Quality classes defined within this requirement
// format: `req [quality|Quality] {({...})*}`
1 -- * QualityClass;
}
class QualityClass
{
name;
// Reserved for {}; currently expected empty and will do nothing on it. If it is not empty, warning will occur
content;
}
class UseCaseStep
{
enum UseCaseStepType
{
userStep,
systemResponse
}
id;
UseCaseStepType stepType;
content;
// Condition under which the step is taken, written like a state machine guard
// Null when the step is unconditional
lazy condition;
}
/*
* Represents an implementation of a requirement
* Stored to allow for analysis of matching requirement
* and reporting on what features implement what requirement
* all instances of this class are tracked in the instance of the model
* with the association allReqImplementations
* Note that there can be multiple instances of this class for each identifier
* because, for example, multiple methods may be needed to implement a given requirement
*/
class ReqImplementation {
depend cruise.umple.parser.Token;
depend java.util.*;
// unique identifier that should match the identifier of a Requirement
identifier;
// Because the QualityClass maybe not accessible in the parse stage, so only store its name first
lazy qualityClassName;
// bound during post-parse if qualityClassName matches a QualityClass in the Requirement
* -> 0..1 QualityClass;
// After analysis of the code, this will identify the requirement if there is one
// If there are zero requirements it would indicate a mismatch (warning 402)
// A requirement can have many implementing features.
* -- 0..1 Requirement;
// The location in the code where the implementation was found, so we can
// report warning 402 if we find no matching requirement
// and so we can output a requirements document that enables the reader to find each implementation
* -> 1 Token reqToken;
// the class, attribute, state machine, state, association, mixset etc. that the
// implementation corresponds to, e.g. 'class Person'
lazy implementingFeature;
}
class UmpleTemplate {
depend cruise.umple.util.*;
isA UmpleClass;
}
/*
* Represents the generation target, such as what the generated output language will be.
*/
class GenerateTarget
{
// The target language, such as Java, Cpp, Php or Ruby.
language;
path;
Boolean override = false;
Boolean overrideAll = false;
lazy String[] suboptions;
before getPath{if(path == null) path = ""; }
key{language}
public Boolean tarHasSubOption(String subOption){
return suboptions.contains(subOption);
}
}
//added for issue 1315 warning 31
class NameSpace
{
depend cruise.umple.parser.Position;
immutable value;
immutable Position position;
Integer timesUsed = 0;
before setTimesUsed{if(aTimesUsed <0) return false; }
}
// UmpleObject is used to initialize classes
class UmpleObject {
type;
name;
0..1 -- * ObjectElement;
//* -- 0..1 UmpleClass;
}
// object element is any element with type value and name, such as attribute or Umple element.
class ObjectElement {
type;
name;
value;
}
class Port {
depend cruise.umple.parser.Position;
direction { IN{} OUT{} BOTH{} }
type { END{} RELAY{} SERVICE{} CUSTOM{} }
name;
modifier;
boolean conjugated;
int multiplicity;
boolean replicated;
String signalType;
before setUmpleClass { if (aUmpleClass != null && aUmpleClass.isImmutable()) { return false; } }
1 -> 0..1 Position;
1 -> 0..1 Position endPosition;
}
use UmpleVersion.ump;
use UmpleDiagram.ump;
//use stateMachine/StateMachine.ump;
use Umple_Code.ump;
use UmpleEnumeration_Code.ump;
mixset Mixset{
use mixset/Mixset.ump;
}
mixset FeatureModel {
use feature/FeatureModel.ump;
}
Restore Earlier Version
UmpleOnline saves versions of this model on the
server while you edit it. Select a version to see what it contained, then restore
it if you want it back.