fixed Bug#307281
Signed-off-by: Karsten Thoms <karsten.thoms@itemis.de>
diff --git a/plugins/org.eclipse.xtend.typesystem.uml2/src/org/eclipse/xtend/typesystem/uml2/profile/MultipleStereotypeType.java b/plugins/org.eclipse.xtend.typesystem.uml2/src/org/eclipse/xtend/typesystem/uml2/profile/MultipleStereotypeType.java
index a909bf7..ced31f0 100644
--- a/plugins/org.eclipse.xtend.typesystem.uml2/src/org/eclipse/xtend/typesystem/uml2/profile/MultipleStereotypeType.java
+++ b/plugins/org.eclipse.xtend.typesystem.uml2/src/org/eclipse/xtend/typesystem/uml2/profile/MultipleStereotypeType.java
@@ -30,8 +30,12 @@
public final class MultipleStereotypeType extends StereotypeType {
List<StereotypeType> stereotypes;
- public MultipleStereotypeType(TypeSystem typeSystem, List<StereotypeType> stereotypes, boolean actualTypeAwareComparison) {
- super(typeSystem, computeName(stereotypes), null, actualTypeAwareComparison);
+ public MultipleStereotypeType(TypeSystem typeSystem, List<StereotypeType> stereotypes) {
+ this(typeSystem, stereotypes, null);
+ }
+
+ public MultipleStereotypeType(TypeSystem typeSystem, List<StereotypeType> stereotypes, Type umlType) {
+ super(typeSystem, computeName(stereotypes), null, umlType);
this.stereotypes = stereotypes;
}
diff --git a/plugins/org.eclipse.xtend.typesystem.uml2/src/org/eclipse/xtend/typesystem/uml2/profile/ProfileMetaModel.java b/plugins/org.eclipse.xtend.typesystem.uml2/src/org/eclipse/xtend/typesystem/uml2/profile/ProfileMetaModel.java
index 2cd96a7..8126612 100644
--- a/plugins/org.eclipse.xtend.typesystem.uml2/src/org/eclipse/xtend/typesystem/uml2/profile/ProfileMetaModel.java
+++ b/plugins/org.eclipse.xtend.typesystem.uml2/src/org/eclipse/xtend/typesystem/uml2/profile/ProfileMetaModel.java
@@ -73,8 +73,6 @@
*/
public class ProfileMetaModel implements MetaModel {
- private boolean actualTypeAwareComparison = false;
-
public List<Profile> profiles = new ArrayList<Profile>(1);
private TypeSystem typeSystem;
@@ -160,7 +158,7 @@
private Map<String, Type> stereoTypes = null;
- private Map<Pair<String, Type>, StereotypeType> stereoTypesWithActualType = null;
+ private Map<Pair<String, Type>, StereotypeType> stereoTypesWithUmlType = null;
/**
* Initializes the metamodel. All stereotypes in the profile are mapped to
@@ -183,7 +181,7 @@
if (o instanceof Stereotype) {
final Stereotype st = (Stereotype) o;
final String typeName = getFullName(st);
- final Type t = new StereotypeType(getTypeSystem(), typeName, st, actualTypeAwareComparison);
+ final Type t = new StereotypeType(getTypeSystem(), typeName, st);
stereoTypes.put(typeName, t);
}
else if (o instanceof Enumeration) {
@@ -255,8 +253,8 @@
*
*/
public Type getType(final Object obj) {
- // Get actual type
- Type actualType = internalProfileMetaModel.getType(obj);
+ // Get actual UML type
+ Type umlType = internalProfileMetaModel.getType(obj);
if (obj instanceof Element) {
if (obj instanceof EnumerationLiteral) {
EnumerationLiteral el = (EnumerationLiteral) obj;
@@ -277,7 +275,7 @@
if (errorIfStereotypeMissing && !stereotypes.toString().equals("[]"))
throw new RuntimeException("Stereotype could not be loaded! Possible hint: '" + stereotypes);
else
- return actualType;
+ return umlType;
}
List<StereotypeType> types = new ArrayList<StereotypeType>(stereotypes.size());
@@ -289,20 +287,19 @@
StereotypeType stType = (StereotypeType) theType;
// Find out whether the actual type is more specific than any of the StereotypeTypes superTypes
- if(actualType != null && !actualType.isAssignableFrom(stType)) {
+ if(umlType != null && !umlType.isAssignableFrom(stType)) {
// Try to find a fitting combination in the cache
- Pair<String, Type> key = new Pair<String, Type>(getFullName(st), actualType);
- if(stereoTypesWithActualType == null) {
- stereoTypesWithActualType = new HashMap<Pair<String, Type>, StereotypeType>();
+ Pair<String, Type> key = new Pair<String, Type>(getFullName(st), umlType);
+ if(stereoTypesWithUmlType == null) {
+ stereoTypesWithUmlType = new HashMap<Pair<String, Type>, StereotypeType>();
}
- stType = stereoTypesWithActualType.get(key);
+ stType = stereoTypesWithUmlType.get(key);
// Create new StereotypeType and a reference to the actual type and put it into cache if not yet contained.
if(stType == null) {
- stType = new StereotypeType(getTypeSystem(), getFullName(st), st, actualTypeAwareComparison);
- stType.setActualType(actualType);
- stereoTypesWithActualType.put(key, stType);
+ stType = new StereotypeType(getTypeSystem(), getFullName(st), st, umlType);
+ stereoTypesWithUmlType.put(key, stType);
}
}
types.add(stType);
@@ -310,17 +307,17 @@
}
switch (types.size()) {
case 0:
- return actualType;
+ return umlType;
case 1:
return types.get(0);
// when more than one stereotype is applied we return a
// MultipleStereotypeType instance
// containing all applied stereotypes
default:
- return new MultipleStereotypeType(getTypeSystem(), types, actualTypeAwareComparison);
+ return new MultipleStereotypeType(getTypeSystem(), types, umlType);
}
} else {
- return actualType;
+ return umlType;
}
}
@@ -354,8 +351,4 @@
return namespaces;
}
- public void setActualTypeAwareComparison(boolean actualTypeAwareComparison) {
- this.actualTypeAwareComparison = actualTypeAwareComparison;
- }
-
}
diff --git a/plugins/org.eclipse.xtend.typesystem.uml2/src/org/eclipse/xtend/typesystem/uml2/profile/StereotypeType.java b/plugins/org.eclipse.xtend.typesystem.uml2/src/org/eclipse/xtend/typesystem/uml2/profile/StereotypeType.java
index ce313c3..3035b3e 100644
--- a/plugins/org.eclipse.xtend.typesystem.uml2/src/org/eclipse/xtend/typesystem/uml2/profile/StereotypeType.java
+++ b/plugins/org.eclipse.xtend.typesystem.uml2/src/org/eclipse/xtend/typesystem/uml2/profile/StereotypeType.java
@@ -32,7 +32,6 @@
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.internal.xtend.expression.parser.SyntaxConstants;
import org.eclipse.internal.xtend.type.baseimpl.PropertyImpl;
-import org.eclipse.uml2.uml.Class;
import org.eclipse.uml2.uml.Classifier;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.Generalization;
@@ -50,31 +49,44 @@
Stereotype stereoType;
- private Type actualType;
+ /**
+ * Represents the actual UML Type that the stereotype is applied to
+ */
+ private Type umlType;
- private final boolean actualTypeAwareComparison;
-
- public StereotypeType(TypeSystem typeSystem, String name, Stereotype stereoType, boolean actualTypeAwareComparison) {
- super(typeSystem, name);
- this.stereoType = stereoType;
- this.actualTypeAwareComparison = actualTypeAwareComparison;
+ public StereotypeType(TypeSystem typeSystem, String name, Stereotype stereoType) {
+ this(typeSystem, name, stereoType, null);
}
- @Override
+ public StereotypeType(TypeSystem typeSystem, String name, Stereotype stereoType, Type umlType) {
+ super(typeSystem, name);
+ this.stereoType = stereoType;
+ this.umlType = umlType;
+ }
+
+ @Override
public int hashCode() {
- if (!actualTypeAwareComparison) {
+ // We need to distinguish between the situation where a Stereotype's
+ // base Class is more general than the actual UML Type in #equals() /
+ // #hashCode(), too - doing not, leads to issues with extension caching
+ // If a UML Type is present the cache should be aware of that
+ if (umlType == null) {
return super.hashCode();
}
final int prime = 31;
int result = super.hashCode();
result = prime * result
- + ((actualType == null) ? 0 : actualType.hashCode());
+ + ((umlType == null) ? 0 : umlType.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
- if (!actualTypeAwareComparison) {
+ // We need to distinguish between the situation where a Stereotype's
+ // base Class is more general than the actual UML Type in #equals() /
+ // #hashCode(), too - doing not, leads to issues with extension caching
+ // If a UML Type is present the cache should be aware of that
+ if (umlType == null) {
return super.equals(obj);
}
if (this == obj) {
@@ -87,11 +99,11 @@
return false;
}
StereotypeType other = (StereotypeType) obj;
- if (actualType == null) {
- if (other.actualType != null) {
+ if (umlType == null) {
+ if (other.umlType != null) {
return false;
}
- } else if (!actualType.equals(other.actualType)) {
+ } else if (!umlType.equals(other.umlType)) {
return false;
}
return true;
@@ -253,13 +265,15 @@
if (superTypes == null) {
superTypes = new HashSet<Type>();
- EList<Class> extendedMetaclasses = stereoType.getExtendedMetaclasses();
- List<Classifier> all;
- if(actualType != null) {
- all = new ArrayList<Classifier>();
- } else {
- all = new ArrayList<Classifier>(extendedMetaclasses);
- }
+ List<Classifier> all = new ArrayList<Classifier>();
+ // If an actual UML Type is present at this state, any of the
+ // metaclasses a Stereotype extends is more general than the actual
+ // type of the UML Object that this Stereotype has been created for.
+ // E.g. ProfileMetaModel.getType(Object) has been called for a
+ // Property, but the Stereotype extends the Element metaclass.
+ if(umlType == null) {
+ all.addAll(stereoType.getExtendedMetaclasses());
+ }
all.addAll(stereoType.getSuperClasses());
for (Classifier classifier : all) {
String superTypeName = getFullName(classifier);
@@ -271,9 +285,10 @@
}
}
- // If an actual type has been set, add it to the list of superTypes in order to export its features
- if(actualType != null && !superTypes.contains(actualType)) {
- superTypes.add(actualType);
+ // If an actual UML type has been set, add it to the list of superTypes
+ // in order to export its features
+ if(umlType != null && !superTypes.contains(umlType)) {
+ superTypes.add(umlType);
}
}
return Collections.unmodifiableSet(superTypes);
@@ -340,13 +355,9 @@
return result.toString();
}
- void setActualType(Type actualType) {
- this.actualType = actualType;
- }
-
@Override
public String toString() {
- return (actualType != null ? MessageFormat.format("{0}[{1}]", super.toString(), actualType.getName()) : super.toString());
+ return (umlType != null ? MessageFormat.format("{0}[{1}]", super.toString(), umlType.getName()) : super.toString());
}
}