Permalink
Fetching contributors…
Cannot retrieve contributors at this time
executable file 1178 lines (936 sloc) 32 KB
/*
Copyright: All contributers to the Umple Project
This file is made available subject to the open source license found at:
http://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;
Boolean distributeOn=true;
Boolean distributeForced=false;
Boolean distributed=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<String,String> generatedCode = new HashMap<String,String>();
Map<String,Analyzer> analyzers = new HashMap<String,Analyzer>();
// 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<File> linkedFiles = new ArrayList<File>();
// 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.
1 -> * UmpleTrait;
// The Umple Templates contained within the model.
1 -> * UmpleTemplate;
// The State Machines contained within the model.
1 -> * StateMachine stateMachineDefinitions;
// The Umple interfaces contained within the model.
1 -> * UmpleInterface;
// Right now, a model can only have 1 diagram
1 -> * Filter;
}
/*
* A Diagram represents a subset of the available model and is used
* to help isolate certain aspects of the system.
* It will be used by the code generation process to "strip" the model
* piror to generation so that all generators will support Diagrams
*
* Right now, no implementation, just setting up the model
*/
class Filter
{
name;
Integer superCount = -1;
Integer subCount = 0;
Integer associationCount = -1;
String[] values;
String[] filterValues;
}
/*
* 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;
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;}
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;
// 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<String,Position> implementationPositions = new HashMap<String,Position>();
//the method assertions
1 -> * UmpleAssertion;
}
/*
* The assertion within the method or class.
*/
class UmpleAssertion {
name;
type;
level;
action;
assertCode;
}
/*
* Test Case at the Class level .
*/
class UmpleTestCase {
name;
1 -- * UmpleAssertion;
}
/*
* 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<String> names = new TreeSet<String>();
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 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;
}
}
/*
* 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
{
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
{
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<String,String> codes = new HashMap<String,String>();
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;
}
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;
}
/*
* 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;
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 isDefaultInterfaceRemoteRMI=false;
// Specifies whether or not in the filter
Boolean filteredin = 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 cass level
1 -- 0..* UmpleTestCase;
// 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;
* 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;
//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; } }
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 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;
//--- 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; } }
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;
1 -> * StateMachineTemplateSignature;
1 -> * StateMachineModifier;
}
class MethodTemplateSignature{
modifier;
1 -> 1 Method;
alias;
}
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;
CodeBlock codeblock = new CodeBlock();
after constructor { codeblock.setCode(normalizeValue(aType,aValue)); }
before setType { codeblock.setCode(normalizeValue(aType,getValue())); }
after setType { setValue(getValue()); }
// 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;
// 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(); }
}
/*
* 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;
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;
}
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}
}
use UmpleVersion.ump;
use UmpleDiagram.ump;
use StateMachine.ump;
use Umple_Code.ump;
use UmpleEnumeration_Code.ump;
use Mixset.ump;