/* 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; // 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(); Map allRequirements = new HashMap(); // 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; } /* * 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 -> * Requirement; // 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 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 { 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(); 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; 1 -> * Requirement; 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; 1 -> * Requirement; //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 -> * Requirement; //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; 1 -> * Requirement; // 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; 1 -> * Requirement; 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 and associations. */ class Requirement{ depend java.util.*; identifier; statement; language; } 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; }