/*
* Initial version copyright 2008 Lockheed Martin Corporation, except
* as stated in the file entitled Licensing-Information.
*
* All modifications copyright 2009-2017 Data Access Technologies, Inc.
*
* Licensed under the Academic Free License version 3.0
* (http://www.opensource.org/licenses/afl-3.0.php), except as stated
* in the file entitled Licensing-Information.
*/
package fUML.Semantics.Classes.Kernel;
import fUML.Syntax.Classes.Kernel.*;
public abstract class Value extends fUML.Semantics.Loci.LociL1.SemanticVisitor {
public abstract fUML.Syntax.Classes.Kernel.ValueSpecification specify();
public boolean equals(fUML.Semantics.Classes.Kernel.Value otherValue) {
// Test if this value is equal to otherValue. To be equal, this value
// must have the same type as otherValue.
// This operation must be overridden in Value subclasses to check for
// equality of properties defined in those subclasses.
ClassifierList myTypes = this.getTypes();
ClassifierList otherTypes = otherValue.getTypes();
boolean isEqual = true;
// Debug.println("[equals] Value...");
// Debug.println("[equals] this has " + myTypes.size() +
// "types, other has " + otherTypes.size() + ".");
if (myTypes.size() != otherTypes.size()) {
isEqual = false;
} else {
// Debug.println("[equals] " + myTypes.size() + " type(s).");
int i = 1;
while (isEqual & i <= myTypes.size()) {
// Debug.println("[equals] this type = " +
// myTypes.getValue(i-1).name);
boolean matched = false;
int j = 1;
while (!matched & j <= otherTypes.size()) {
// Debug.println("[equals] other type = " +
// otherTypes.getValue(j-1).name);
matched = (otherTypes.getValue(j - 1) == myTypes
.getValue(i - 1));
j = j + 1;
}
isEqual = matched;
i = i + 1;
}
}
return isEqual;
} // equals
public fUML.Semantics.Classes.Kernel.Value copy() {
// Create a new value that is equal to this value.
// By default, this operation simply creates a new value with empty
// properties.
// It must be overridden in each Value subclass to do the superclass
// copy and then appropriately set properties defined in the subclass.
return this.new_();
} // copy
protected abstract fUML.Semantics.Classes.Kernel.Value new_();
public abstract fUML.Syntax.Classes.Kernel.ClassifierList getTypes();
public boolean hasType(fUML.Syntax.Classes.Kernel.Classifier type) {
// Check if this object has the given classifier as a type.
ClassifierList types = this.getTypes();
boolean found = false;
int i = 1;
while (!found & i <= types.size()) {
found = (types.getValue(i - 1) == type);
i = i + 1;
}
return found;
} // hasType
public boolean isInstanceOf(fUML.Syntax.Classes.Kernel.Classifier classifier) {
// Check if this value has the given classifier as its type
// or as an ancestor of one of its types.
ClassifierList types = this.getTypes();
boolean isInstance = this.hasType(classifier);
int i = 1;
while (!isInstance & i <= types.size()) {
isInstance = this.checkAllParents(types.getValue(i-1), classifier);
i = i + 1;
}
return isInstance;
}
public boolean checkAllParents(fUML.Syntax.Classes.Kernel.Classifier type,
fUML.Syntax.Classes.Kernel.Classifier classifier) {
// Check if the given classifier matches any of the direct or indirect
// ancestors of a given type.
ClassifierList directParents = type.general;
boolean matched = false;
int i = 1;
while (!matched & i <= directParents.size()) {
Classifier directParent = directParents.getValue(i - 1);
if (directParent == classifier) {
matched = true;
} else {
matched = this.checkAllParents(directParent, classifier);
}
i = i + 1;
}
return matched;
}
public abstract String toString();
} // Value