001: // This file is part of KeY - Integrated Deductive Software Design
002: // Copyright (C) 2001-2007 Universitaet Karlsruhe, Germany
003: // Universitaet Koblenz-Landau, Germany
004: // Chalmers University of Technology, Sweden
005: //
006: // The KeY system is protected by the GNU General Public License.
007: // See LICENSE.TXT for details.
008: // This file is part of KeY - Integrated Deductive Software Design
009: // Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany
010: // Universitaet Koblenz-Landau, Germany
011: // Chalmers University of Technology, Sweden
012: //
013: // The KeY system is protected by the GNU General Public License.
014: // See LICENSE.TXT for details.
015: //
016: // This file is part of KeY - Integrated Deductive Software Design
017: // Copyright (C) 2001-2004 Universitaet Karlsruhe, Germany
018: // Universitaet Koblenz-Landau, Germany
019: // Chalmers University of Technology, Sweden
020: //
021: // The KeY system is protected by the GNU General Public License.
022: // See LICENSE.TXT for details.
023: package de.uka.ilkd.key.casetool;
024:
025: import java.util.Iterator;
026: import java.util.LinkedList;
027:
028: import tudresden.ocl.check.OclTypeException;
029: import tudresden.ocl.check.types.*;
030:
031: public class UMLOCLClassifier implements Any {
032:
033: private String name;
034: private String fullName;
035: private HashMapOfFeatures features;
036: private HashMapOfClassifier super types;
037: private HashMapOfAssociations associations;
038:
039: private UMLOCLClassifier() {
040: }
041:
042: public UMLOCLClassifier(String name, String fullName) {
043: this .name = name;
044: this .fullName = fullName;
045: this .features = new HashMapOfFeatures();
046: this .super types = new HashMapOfClassifier();
047: this .associations = new HashMapOfAssociations();
048: }
049:
050: /** add a behavioural feature (operation) or a structural
051: * feature (attribute) to this classifier
052: */
053: public void addFeature(String key, UMLOCLFeature feature) {
054: features.putFeature(key, feature);
055: }
056:
057: public void addAssociation(String key, UMLOCLAssociation assoc) {
058: associations.putAssociation(key, assoc);
059: }
060:
061: public UMLOCLFeature getFeature(String key) {
062: return features.getFeature(key);
063: }
064:
065: public HashMapOfFeatures features() {
066: return features;
067: }
068:
069: public HashMapOfAssociations getAssociations() {
070: return associations;
071: }
072:
073: public UMLOCLAssociation getAssociation(String s) {
074: if (this .getAssociations().containsKey(s)) {
075: return (UMLOCLAssociation) this .associations.get(s);
076: }
077:
078: // search for the association in the supertypes
079: Iterator it = super types.values().iterator();
080: UMLOCLClassifier c;
081: while (it.hasNext()) {
082: c = (UMLOCLClassifier) it.next();
083: if (c.getAssociations().containsKey(s)) {
084: return (UMLOCLAssociation) c.associations.get(s);
085: }
086: }
087: return null;
088: }
089:
090: public void addSupertype(String key, UMLOCLClassifier super type) {
091: super types.putClassifier(key, super type);
092: }
093:
094: public HashMapOfClassifier getSupertypes() {
095: return super types;
096: }
097:
098: public boolean conformsTo(Type t) {
099: if (t instanceof UMLOCLClassifier) {
100: if (this .getName().equals(((UMLOCLClassifier) t).getName()))
101: return true;
102: else
103: return super types.containsKey(((UMLOCLClassifier) t)
104: .getName());
105: }
106: return false;
107: }
108:
109: public boolean hasState(String stateName) {
110: return false;
111: }
112:
113: public Type navigateQualified(String name, Type[] qualifiers) {
114: // ??? this check is from an example in the Dresden package ???
115: if (qualifiers != null)
116: for (int i = 0; i < qualifiers.length; i++)
117: System.out.println(qualifiers[i]);
118: if (qualifiers != null && qualifiers.length > 0)
119: throw new OclTypeException("Feature \"" + name
120: + "\" of type " + this
121: + " cannot be accessed with qualifier");
122:
123: Type ret = null;
124: ret = Basic.navigateAnyQualified(name, this , qualifiers);
125: if (ret != null) {
126: return ret;
127: }
128: if (getFeature(name) != null)
129: ret = getFeature(name).getType();
130: else if (getAssociation(name) != null) {
131: ret = getAssociation(name).getTarget();
132: if (getAssociation(name).getTargetMultiplicity().getMax() != 1) {
133: ret = new Collection(Collection.SET, ret);
134: }
135: }
136: if (ret == null) {
137: throw new OclTypeException(this .name + " has no feature "
138: + name);
139: }
140: return ret;
141: }
142:
143: /**
144: * @param params an array of Type (null is not allowed)
145: */
146: public Type navigateParameterized(String name, Type[] params) {
147:
148: assert params != null : "param should not be null";
149:
150: if (params.length == 1 && params[0] != null
151: && params[0] instanceof OclType) {
152: if (name.equals("oclIsKindOf")
153: || name.equals("oclIsTypeOf"))
154: return Basic.BOOLEAN;
155: else if (name.equals("oclAsType"))
156: return ((OclType) params[0]).getType();
157: }
158:
159: String nameString = new String(name + "(");
160: Iterator it;
161: LinkedList candidates = new LinkedList();
162: for (int i = 0; i < params.length; i++) {
163: if (params[i] instanceof UMLOCLClassifier) {
164: if (i < params.length - 1) {
165: nameString = nameString
166: + ((UMLOCLClassifier) params[i]).getName()
167: + ",";
168: } else {
169: nameString = nameString
170: + ((UMLOCLClassifier) params[i]).getName();
171: }
172: } else {
173: String s = new String();
174: if (params[i] == Basic.INTEGER) {
175: s = "int";
176: } else if (params[i] == Basic.BOOLEAN) {
177: s = "boolean";
178: } else if (params[i] == Basic.REAL) {
179: s = "double";
180: } else if (params[i] == Basic.STRING) {
181: s = "java.lang.String";
182: }
183:
184: if (i < params.length - 1) {
185: nameString = nameString + s + ",";
186: } else {
187: nameString = nameString + s;
188: }
189: }
190: }
191: nameString = nameString + ")";
192:
193: it = features().keySet().iterator();
194: while (it.hasNext()) {
195: String key = it.next().toString();
196: if (features.get(key) instanceof UMLOCLBehaviouralFeature) {
197: if (key.substring(0, key.indexOf('(')).equals(name)) {
198: candidates.addLast((UMLOCLFeature) features
199: .get(key));
200: }
201: }
202: }
203: boolean fits = false;
204:
205: it = candidates.iterator();
206: while (it.hasNext()) {
207: UMLOCLBehaviouralFeature tbf = (UMLOCLBehaviouralFeature) it
208: .next();
209: Type[] featureParams = tbf.getParameters();
210: fits = (params.length == featureParams.length);
211: for (int i = 0; fits && i < params.length; i++) {
212: if (!params[i].conformsTo(featureParams[i]))
213: fits = false;
214: }
215: if (fits) {
216: return tbf.getType();
217: }
218: }
219:
220: return null;
221: }
222:
223: public boolean equals(Object o) {
224: if (!(o instanceof UMLOCLClassifier)) {
225: return false;
226: }
227: return this .getFullName().equals(
228: ((UMLOCLClassifier) o).getFullName());
229: }
230:
231: public int hashCode() {
232: return this .getFullName().hashCode();
233: }
234:
235: public String getName() {
236: return name;
237: }
238:
239: public String getFullName() {
240: return fullName;
241: }
242:
243: public String toString() {
244: return name;
245: }
246:
247: }
|