Skip to content

Commit 755931b

Browse files
committed
FUML15-28 Added tests to demonstrate associations with non-owned ends.
- Updated creation of feature values for structural features to skip association ends.
1 parent 025ea7c commit 755931b

7 files changed

Lines changed: 127 additions & 71 deletions

File tree

org.modeldriven.fuml/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<artifactId>fuml</artifactId>
66
<packaging>jar</packaging>
77
<name>FUML Reference Implementation</name>
8-
<version>1.4.2a</version>
8+
<version>1.4.3-SNAPSHOT</version>
99
<description>This open source software is a reference implementation, consisting of software and related files, for the OMG specification called the Semantics of a Foundational Subset for Executable UML Models (fUML). The reference implementation is intended to implement the execution semantics of UML activity models, accepting an XMI file from a conformant UML model as its input and providing an execution trace of the selected activity model(s) as its output. The core execution engine, which is directly generated from the normative syntactic and semantic models for fUML, may also be used as a library implementation of fUML in other software.</description>
1010
<url>http:/fuml.modeldriven.org</url>
1111
<licenses>

org.modeldriven.fuml/src/main/java/fuml/semantics/simpleclassifiers/StructuredValue.java

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import fuml.syntax.classification.ClassifierList;
1919
import fuml.syntax.classification.InstanceSpecification;
2020
import fuml.syntax.classification.InstanceValue;
21+
import fuml.syntax.classification.Property;
2122
import fuml.syntax.classification.Slot;
2223
import fuml.syntax.classification.StructuralFeature;
2324
import fuml.syntax.commonstructure.NamedElement;
@@ -103,20 +104,20 @@ public fuml.semantics.simpleclassifiers.FeatureValueList getMemberValues(Classif
103104
};
104105

105106
public void createFeatureValues() {
106-
// Create empty feature values for all structural features of the types
107-
// of this structured value and all its supertypes (including private
108-
// features that are not inherited).
107+
// Create empty feature values for all non-association-end structural
108+
// features of the types of this structured value and all its supertypes
109+
// (including private features that are not inherited).
109110

110111
this.addFeatureValues(new FeatureValueList());
111112
}
112113

113114
public void addFeatureValues(FeatureValueList oldFeatureValues) {
114-
// Add feature values for all structural features of the types
115-
// of this structured value and all its supertypes (including private
116-
// features that are not inherited). If a feature has an old feature
117-
// value in the given list, then use that to initialize the values of
118-
// the corresponding new feature value. Otherwise leave the values of
119-
// the new feature value empty.
115+
// Add feature values for all non-association-end structural features
116+
// of the types of this structured value and all its supertypes
117+
// (including private features that are not inherited). If a feature
118+
// has an old feature value in the given list, then use that to initialize
119+
// the values of the corresponding new feature value. Otherwise leave the
120+
// values of the new feature value empty.
120121

121122
ClassifierList types = this.getTypes();
122123

@@ -127,20 +128,22 @@ public void addFeatureValues(FeatureValueList oldFeatureValues) {
127128
}
128129

129130
public void addFeatureValuesForType(Classifier type, FeatureValueList oldFeatureValues) {
130-
// Add feature values for all structural features of the given type and
131-
// all of its supertypes (including private features that are not
132-
// inherited). If a feature has an old feature value in the given list,
133-
// then use that to initialize the values of the corresponding new
134-
// feature value. Otherwise leave the values of the new feature value
131+
// Add feature values for all non-association-end structural features
132+
// of the given type and all of its supertypes (including private features
133+
// that are not inherited). If a feature has an old feature value in the
134+
// given list, then use that to initialize the values of the corresponding
135+
// new feature value. Otherwise leave the values of the new feature value
135136
// empty.
136137

137-
// Set feature values for the owned structural features of the given
138-
// type. (Any common structural values that have already been added
139-
// previously will simply have their values set again.)
138+
// Set feature values for the non-association end owned structural features
139+
// of the given type. (Any common structural values that have already been
140+
// added previously will simply have their values set again.)
140141
NamedElementList ownedMembers = type.ownedMember;
141142
for (int j = 0; j < ownedMembers.size(); j++) {
142143
NamedElement ownedMember = ownedMembers.getValue(j);
143-
if (ownedMember instanceof StructuralFeature) {
144+
if (ownedMember instanceof StructuralFeature &&
145+
!(ownedMember instanceof Property &&
146+
((Property)ownedMember).association != null)) {
144147
this.setFeatureValue((StructuralFeature) ownedMember,
145148
this.getValues(ownedMember, oldFeatureValues), 0);
146149
}

org.modeldriven.fuml/src/main/java/fuml/syntax/structuredclassifiers/Association.java

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,22 +29,7 @@ public void addOwnedEnd(fuml.syntax.classification.Property ownedEnd) {
2929
this.ownedEnd.addValue(ownedEnd);
3030
ownedEnd._setOwningAssociation(this);
3131

32-
this.memberEnd.addValue(ownedEnd);
33-
ownedEnd._setAssociation(this);
34-
35-
if (ownedEnd.typedElement.type != null) {
36-
this.endType.addValue(ownedEnd.typedElement.type);
37-
}
38-
39-
if (this.memberEnd.size() == 2) {
40-
Property opposite = this.memberEnd.get(0);
41-
ownedEnd._setOpposite(opposite);
42-
opposite._setOpposite(ownedEnd);
43-
} else if (this.memberEnd.size() > 2) {
44-
for (Property memberEnd : this.memberEnd) {
45-
memberEnd._setOpposite(null);
46-
}
47-
}
32+
this._addMemberEnd(ownedEnd);
4833
} // addOwnedEnd
4934

5035
public void addNavigableOwnedEnd(
@@ -54,5 +39,33 @@ public void addNavigableOwnedEnd(
5439

5540
this.navigableOwnedEnd.addValue(navigableOwnedEnd);
5641
} // addNavigableOwnedEnd
42+
43+
public void addMemberEnd(fuml.syntax.classification.Property memberEnd) {
44+
// Note: This operation should not be used for owned ends. The
45+
// operation addOwnedEnd should be used instead.
46+
47+
this.addMember(memberEnd);
48+
this._addMemberEnd(memberEnd);
49+
}
50+
51+
protected void _addMemberEnd(fuml.syntax.classification.Property memberEnd) {
52+
this.memberEnd.addValue(memberEnd);
53+
memberEnd._setAssociation(this);
54+
55+
if (memberEnd.typedElement.type != null) {
56+
this.endType.addValue(memberEnd.typedElement.type);
57+
}
58+
59+
if (this.memberEnd.size() == 2) {
60+
Property opposite = this.memberEnd.get(0);
61+
memberEnd._setOpposite(opposite);
62+
opposite._setOpposite(memberEnd);
63+
} else if (this.memberEnd.size() > 2) {
64+
for (Property end : this.memberEnd) {
65+
end._setOpposite(null);
66+
}
67+
}
68+
69+
}
5770

5871
} // Association

org.modeldriven.fuml/src/test/java/org/modeldriven/fuml/test/builtin/LinkReaderTestCase.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@ public static Test suite() {
2323

2424
public void setUp() throws Exception {
2525
this.clearExtents();
26-
}
26+
}
2727

28-
public void testLinkReader() throws Exception {
29-
log.info("testLinkReader");
30-
ParameterValueList output = this.testSuite.testLinkReader();
28+
public void runTest(int n) throws Exception {
29+
log.info("testLinkReader with " + n + " association-owned end(s)");
30+
ParameterValueList output = this.testSuite.testLinkReader(n);
3131
log.info("done");
3232

3333
assertNotNull(output);
@@ -67,4 +67,16 @@ public void testLinkReader() throws Exception {
6767
assertSame("value2b (feature)", featureOutput1, value2b);
6868
}
6969

70+
public void testLinkReaderWithNoOwnedEnds() throws Exception {
71+
this.runTest(0);
72+
}
73+
74+
public void testLinkReaderWithOneOwnedEnd() throws Exception {
75+
this.runTest(1);
76+
}
77+
78+
public void testLinkReaderWithTwoOwnedEnds() throws Exception {
79+
this.runTest(2);
80+
}
81+
7082
}

org.modeldriven.fuml/src/test/java/org/modeldriven/fuml/test/builtin/environment/ActivityFactory.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
* Initial version copyright 2008 Lockheed Martin Corporation, except
33
* as stated in the file entitled Licensing-Information.
44
*
5-
* All modifications copyright 2009-2017 Data Access Technologies, Inc.
5+
* Modifications:
6+
* Copyright 2009-2017 Data Access Technologies, Inc.
7+
* Copyright 2020 Model Driven Solutions, Inc.
68
*
79
* Licensed under the Academic Free License version 3.0
810
* (http://www.opensource.org/licenses/afl-3.0.php), except as stated

org.modeldriven.fuml/src/test/java/org/modeldriven/fuml/test/builtin/environment/ClassifierFactory.java

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
* Initial version copyright 2008 Lockheed Martin Corporation, except
33
* as stated in the file entitled Licensing-Information.
44
*
5-
* All modifications copyright 2009-2012 Data Access Technologies, Inc.
5+
* Modifications:
6+
* Copyright 2009-2012 Data Access Technologies, Inc.
7+
* Copyright 2020 Model Driven Solutions, Inc.
68
*
79
* Licensed under the Academic Free License version 3.0
810
* (http://www.opensource.org/licenses/afl-3.0.php), except as stated
@@ -34,7 +36,7 @@ public ClassifierFactory(org.modeldriven.fuml.test.builtin.environment.TestEnvir
3436
this.environment = environment;
3537
} // ClassifierFactory
3638

37-
public void createEnumerationType(String typeName, int numberOfLiterals) {
39+
public Enumeration createEnumerationType(String typeName, int numberOfLiterals) {
3840
Enumeration type = new Enumeration();
3941

4042
type.setName(typeName);
@@ -47,30 +49,36 @@ public void createEnumerationType(String typeName, int numberOfLiterals) {
4749
}
4850

4951
environment.addElement(type);
52+
53+
return type;
5054
} // createEnumerationType
5155

52-
public void createDataType(String name) {
56+
public DataType createDataType(String name) {
5357
DataType dataType = new DataType();
5458
dataType.setName(name);
5559
environment.addElement(dataType);
60+
return dataType;
5661
} // createDataType
5762

58-
public void createClass(String name) {
63+
public Class_ createClass(String name) {
5964
Class_ class_ = new Class_();
6065
class_.setName(name);
6166
environment.addElement(class_);
67+
return class_;
6268
} // createClass
6369

64-
public void createSignal(String name) {
70+
public Signal createSignal(String name) {
6571
Signal signal = new Signal();
6672
signal.setName(name);
6773
this.environment.addElement(signal);
74+
return signal;
6875
} // createSignal
6976

70-
public void createAssociation(String name) {
77+
public Association createAssociation(String name) {
7178
Association association = new Association();
7279
association.setName(name);
7380
environment.addElement(association);
81+
return association;
7482
} // createAssociation
7583

7684
public Property addAttribute(String classifierName, String attributeName,
@@ -130,14 +138,14 @@ public Property addAttribute(String classifierName, String attributeName,
130138
return attribute;
131139
} // addAttribute
132140

133-
public void addEnd(String associationName, String endName,
141+
public Property addEnd(String associationName, String endName,
134142
String endTypeName, boolean isComposite) {
135143
Classifier type = environment.getType(associationName);
136144

137145
if (type == null || !(type instanceof Association)) {
138146
Debug.println("[addEnd] " + associationName
139147
+ " not found or not an association.");
140-
return;
148+
return null;
141149
}
142150

143151
Association association = (Association) type;
@@ -147,7 +155,7 @@ public void addEnd(String associationName, String endName,
147155
if (endType == null) {
148156
Debug.println("[addEnd] " + endTypeName
149157
+ " not found or not a classifier.");
150-
return;
158+
return null;
151159
}
152160

153161
Property end = new Property();
@@ -165,16 +173,18 @@ public void addEnd(String associationName, String endName,
165173
}
166174

167175
association.addOwnedEnd(end);
168-
176+
association.addNavigableOwnedEnd(end);
177+
178+
return end;
169179
} // addEnd
170180

171-
public void addClassifierBehavior(String className, String behaviorName) {
181+
public Class_ addClassifierBehavior(String className, String behaviorName) {
172182
NamedElement element = this.environment.getElement(className);
173183

174184
if (element == null || !(element instanceof Class_)) {
175185
Debug.println("[addClassifierBehavior] " + className
176186
+ " not found or not a class.");
177-
return;
187+
return null;
178188
}
179189

180190
Class_ classifier = (Class_) element;
@@ -184,25 +194,26 @@ public void addClassifierBehavior(String className, String behaviorName) {
184194
if (element == null || !(element instanceof Behavior)) {
185195
Debug.println("[addClassifierBehavior] " + behaviorName
186196
+ " not found or not a behavior.");
187-
return;
197+
return null;
188198
}
189199

190200
Behavior behavior = (Behavior) element;
191201
this.environment.removeElement(element);
192202

193203
classifier.addOwnedBehavior(behavior);
194204
classifier.setClassifierBehavior(behavior);
195-
205+
206+
return classifier;
196207
} // addClassifierBehavior
197208

198-
public void addOperation(String className, String baseClassName,
209+
public Operation addOperation(String className, String baseClassName,
199210
String operationName, String methodName) {
200211
NamedElement element = this.environment.getElement(className);
201212

202213
if (element == null || !(element instanceof Class_)) {
203214
Debug.println("[addOperation] " + className
204215
+ " not found or not a class.");
205-
return;
216+
return null;
206217
}
207218

208219
Class_ classifier = (Class_) element;
@@ -216,7 +227,7 @@ public void addOperation(String className, String baseClassName,
216227
if (element == null || !(element instanceof Class_)) {
217228
Debug.println("[addOperation] " + baseClassName
218229
+ " not found or not a class.");
219-
return;
230+
return null;
220231
}
221232

222233
Class_ baseClass = (Class_) element;
@@ -226,7 +237,7 @@ public void addOperation(String className, String baseClassName,
226237
if (redefinedOperation == null) {
227238
Debug.println("[addOperation] " + operationName
228239
+ " is not an operation of " + baseClassName + ".");
229-
return;
240+
return null;
230241
}
231242

232243
operation.addRedefinedOperation(redefinedOperation);
@@ -240,7 +251,7 @@ public void addOperation(String className, String baseClassName,
240251
if (element == null || !(element instanceof Behavior)) {
241252
Debug.println("[addOperation] " + methodName
242253
+ " not found or not a behavior.");
243-
return;
254+
return null;
244255
}
245256

246257
Behavior behavior = (Behavior) element;
@@ -251,33 +262,35 @@ public void addOperation(String className, String baseClassName,
251262
}
252263

253264
classifier.addOwnedOperation(operation);
254-
265+
266+
return operation;
255267
} // addOperation
256268

257-
public void addGeneralization(String subtypeName, String supertypeName) {
269+
public Generalization addGeneralization(String subtypeName, String supertypeName) {
258270
Classifier subtype = this.environment.getType(subtypeName);
259271

260272
if (subtype == null) {
261273
Debug.println("[addGeneralization] " + subtypeName
262274
+ " not found or not a classifier.");
263-
return;
275+
return null;
264276
}
265277

266278
Classifier supertype = this.environment.getType(supertypeName);
267279

268280
if (supertype == null) {
269281
Debug.println("[addGeneralization] " + supertypeName
270282
+ " not found or not a classifier.");
271-
return;
283+
return null;
272284
}
273285

274286
Generalization generalization = new Generalization();
275287
generalization.setGeneral(supertype);
276288
subtype.addGeneralization(generalization);
289+
290+
return generalization;
277291
} // addGeneralization
278292

279-
protected fuml.syntax.classification.Operation getOperation(
280-
fuml.syntax.structuredclassifiers.Class_ class_, String operationName) {
293+
protected Operation getOperation(Class_ class_, String operationName) {
281294
for (int i = 0; i < class_.member.size(); i++) {
282295
NamedElement member = class_.member.getValue(i);
283296
if (member.name.equals(operationName)) {

0 commit comments

Comments
 (0)