/* Copyright (C) 2009 by Claas Wilke (claaswilke@gmx.net) This file is part of the Model Bus Plug-in of Dresden OCL2 for Eclipse. Dresden OCL2 for Eclipse is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Dresden OCL2 for Eclipse is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with Dresden OCL2 for Eclipse. If not, see <http://www.gnu.org/licenses/>. */ package org.dresdenocl.modelinstancetype.types.base; import java.util.Collection; import java.util.LinkedList; import org.dresdenocl.essentialocl.expressions.CollectionKind; import org.dresdenocl.essentialocl.types.BagType; import org.dresdenocl.essentialocl.types.CollectionType; import org.dresdenocl.essentialocl.types.OrderedSetType; import org.dresdenocl.essentialocl.types.SequenceType; import org.dresdenocl.essentialocl.types.SetType; import org.dresdenocl.modelinstancetype.types.IModelInstanceCollection; import org.dresdenocl.modelinstancetype.types.IModelInstanceElement; import org.dresdenocl.pivotmodel.Type; /** * <p> * Implements the interface {@link IModelInstanceCollection} abstractly for * <code>IModelInstance</code> {@link Collection}s. * </p> * * @author Claas Wilke */ public abstract class AbstractModelInstanceCollection<T extends IModelInstanceElement> extends AbstractModelInstanceElement implements IModelInstanceCollection<T> { /* * (non-Javadoc) * * @seeorg.dresdenocl.modelbus.modelinstance.types.impl. * AbstractModelInstanceElement#getName() */ public String getName() { StringBuffer resultBuffer; resultBuffer = new StringBuffer(); /* Probably return the element's name. */ if (this.myName != null) { resultBuffer.append(this.myName); } /* Else probably return the element's id. */ else if (this.myId != null) { resultBuffer.append(this.myId); } /* Else construct a name of all implemented types. */ else { if (this.isOrdered()) { if (this.isUnique()) { resultBuffer.append("MIOrderedSet"); } else { resultBuffer.append("MISet"); } } else { if (this.isUnique()) { resultBuffer.append("MISequence"); } else { resultBuffer.append("MIBag"); } } resultBuffer.append("["); boolean firstElement; firstElement = true; for (T element : this.getCollection()) { if (firstElement) { firstElement = false; } else { resultBuffer.append(", "); } if (element instanceof IModelInstanceElement) { resultBuffer.append(((IModelInstanceElement) element) .getName()); } else { resultBuffer.append(element.toString()); } } resultBuffer.append("]"); } // end else. return resultBuffer.toString(); } /* * (non-Javadoc) * * @seeorg.dresdenocl.modelbus.modelinstance.types.base. * AbstractModelInstanceElement#equals(java.lang.Object) */ @Override public boolean equals(Object object) { boolean result; if (object == null) { result = false; } else if (this == object) { result = true; } if (object instanceof AbstractModelInstanceCollection<?>) { AbstractModelInstanceCollection<?> other; other = (AbstractModelInstanceCollection<?>) object; /* * This should not happen. But anyway, null == null results in * false. */ if (this.isUndefined() || other.isUndefined()) { result = false; } else { result = true; /* Check if both collections are ordered. */ result &= this.isOrdered() == other.isOrdered(); /* Check if both collections are unique. */ result &= this.isUnique() == other.isUnique(); /* Check if both collections have the same type. */ result &= this.getType().equals(other.getType()); /* Compare collections depends on the type of collection. */ if (this.getType() instanceof BagType) { if (this.getCollection().size() == other.getCollection() .size()) { /* * Check that both collections contain the same amount * of each element. */ LinkedList<Object> copy = new LinkedList<Object>( this.getCollection()); for (Object element : other.getCollection()) { if (copy.contains(element)) { copy.remove(element); } else { result = false; } } // end for. result &= copy.isEmpty(); } else { result = false; } } else if (this.getType() instanceof OrderedSetType) { /* Collections should have the same order. */ result &= this.getCollection() .equals(other.getCollection()); } else if (this.getType() instanceof SequenceType) { /* Collections should have the same order. */ result &= this.getCollection() .equals(other.getCollection()); } else if (this.getType() instanceof SetType) { /* Collections should contain the same elements. */ result &= this.getCollection().containsAll( (other.getCollection())); } else { result &= this.getCollection() .equals(other.getCollection()); } } } else { result = false; } return result; } /* * (non-Javadoc) * * @seeorg.dresdenocl.modelbus.modelinstance.types.base. * AbstractModelInstanceElement#hashCode() */ @Override public int hashCode() { int result; int prime = 31; result = 0; if (this.isOrdered()) { result += 1231; } else { result += 1237; } if (this.isUnique()) { result = prime * result + 1231; } else { result = prime * result + 1237; } if (this.getCollection() == null) { result = prime * result; } else { result = prime * result + this.getCollection().hashCode(); } if (this.myType == null) { result = prime * result; } else { result = prime * result + this.myType.hashCode(); } return result; } /* * (non-Javadoc) * * @seeorg.dresdenocl.modelbus.modelinstance.types.base. * AbstractModelInstanceElement#hashCode() */ /* * (non-Javadoc) * * @see * org.dresdenocl.modelinstancetype.types.IModelInstanceCollection * #isOrdered() */ public boolean isOrdered() { boolean result; /* Only ordered sets and sequences are ordered. */ CollectionType collectionType = (CollectionType) this.myType; if (collectionType.getKind() == CollectionKind.SEQUENCE || collectionType.getKind() == CollectionKind.ORDERED_SET) { result = true; } else { result = false; } return result; } /* * (non-Javadoc) * * @see org.dresdenocl.modelinstancetype.types.IModelInstanceElement * #isUndefined() */ public boolean isUndefined() { return (this.getCollection() == null); } /* * (non-Javadoc) * * @see * org.dresdenocl.modelinstancetype.types.IModelInstanceElement#isKindOf * (org.dresdenocl.pivotmodel.Type) */ public boolean isKindOf(Type type) { return this.getType().conformsTo(type); } /* * (non-Javadoc) * * @see * org.dresdenocl.modelinstancetype.types.IModelInstanceCollection * #isUnique() */ public boolean isUnique() { boolean result; CollectionType collectionType = (CollectionType) this.myType; /* Only ordered sets and sets are unique. */ if (collectionType.getKind() == CollectionKind.ORDERED_SET || collectionType.getKind() == CollectionKind.SET) { result = true; } else { result = false; } return result; } }