/******************************************************************************* * Copyright (c) 2010, 2014 Willink Transformations and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * E.D.Willink - Initial API and implementation *******************************************************************************/ package org.eclipse.ocl.pivot.internal.values; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.Set; import org.eclipse.emf.ecore.EClass; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.ocl.pivot.ids.CollectionTypeId; import org.eclipse.ocl.pivot.ids.IdResolver; import org.eclipse.ocl.pivot.ids.TypeId; import org.eclipse.ocl.pivot.values.CollectionValue; import org.eclipse.ocl.pivot.values.InvalidValueException; import org.eclipse.ocl.pivot.values.OrderedSetValue; import org.eclipse.ocl.pivot.values.SequenceValue; import org.eclipse.ocl.pivot.values.SetValue; import org.eclipse.ocl.pivot.values.UniqueCollectionValue; import org.eclipse.ocl.pivot.values.ValuesPackage; // // Note that it is not necessary to adjust set uniqueness for OCL value equivalence // since Value.equals realises OCL equivalence, and so Collection operations that // inherently use Object.equals automatically observe OCL uniqueness. // /** * @generated NOT */ public class SetValueImpl extends CollectionValueImpl implements SetValue { /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ @Override protected EClass eStaticClass() { return ValuesPackage.Literals.SET_VALUE; } public static @NonNull Set<Object> createSetOfEach(@Nullable Object @NonNull [] boxedValues) { Set<Object> result = new HashSet<Object>(); for (Object boxedValue : boxedValues) { result.add(boxedValue); } return result; } public static class Accumulator extends SetValueImpl implements SetValue.Accumulator { public Accumulator(@NonNull CollectionTypeId typeId) { super(typeId, new HashSet<Object>()); } @Override @SuppressWarnings("unchecked") public boolean add(@Nullable Object value) { return ((Collection<Object>)elements).add(value); } } public SetValueImpl(@NonNull CollectionTypeId typeId, @NonNull Collection<? extends Object> boxedValues) { super(typeId, boxedValues); assert checkElementsAreUnique(elements); } @Override public @NonNull UniqueCollectionValue asUniqueCollectionValue() { return this; } @Override public @NonNull SetValue asSetValue() { return this; } @Override public @NonNull Set<Object> asUnboxedObject(@NonNull IdResolver idResolver) { Set<Object> unboxedValues = new HashSet<Object>(); for (Object boxedValue : elements) { unboxedValues.add(idResolver.unboxedValueOf(boxedValue)); } return unboxedValues; } @Override public boolean equals(Object obj) { if (!(obj instanceof SetValue)) { return false; } int thisSize = elements.size(); Collection<? extends Object> thoseElements = ((SetValue)obj).getElements(); int thatSize = thoseElements.size(); if (thisSize != thatSize) { return false; } if (thoseElements instanceof Set<?>) { return thoseElements.containsAll(elements); } else { return elements.containsAll(thoseElements); } } @Override public @NonNull SetValue excluding(@Nullable Object value) { Set<Object> result = new HashSet<Object>(); if (value == null) { for (Object element : elements) { if (element != null) { result.add(element); } } } else { for (Object element : elements) { if (!value.equals(element)) { result.add(element); } } } if (result.size() < elements.size()) { return new SetValueImpl(getTypeId(), result); } else { return this; } } @Override public @NonNull SetValue excludingAll(@NonNull CollectionValue values) { Set<Object> result = new HashSet<Object>(); for (Object element : elements) { boolean reject = false; if (element == null) { for (Object value : values) { if (value == null) { reject = true; break; } } } else { for (Object value : values) { if ((value != null) && value.equals(element)) { reject = true; break; } } } if (!reject) { result.add(element); } } if (result.size() < elements.size()) { return new SetValueImpl(getTypeId(), result); } else { return this; } } @Override public @NonNull SetValue flatten() { Set<Object> flattened = new HashSet<Object>(); if (flatten(flattened)) { return new SetValueImpl(getTypeId(), flattened); } else { return this; } } // @Override // public @NonNull CollectionTypeId getCollectionTypeId() { // return TypeId.SET; // } // @Override // protected @NonNull Set<? extends Object> getElements() { // return (Set<? extends Object>) elements; // } @Override public @NonNull String getKind() { return TypeId.SET_NAME; } @Override public @NonNull SetValue including(@Nullable Object value) { assert !(value instanceof InvalidValueException); Set<Object> result = new HashSet<Object>(elements); result.add(value); return new SetValueImpl(getTypeId(), result); } @Override public @NonNull SetValue includingAll(@NonNull CollectionValue values) { Set<Object> result = new HashSet<Object>(elements); for (Object value : values) { result.add(value); } return new SetValueImpl(getTypeId(), result); } @Override public boolean isOrdered() { return false; } @Override public boolean isUnique() { return true; } @Override public @NonNull SetValue minus(@NonNull UniqueCollectionValue set) { Set<Object> result = new HashSet<Object>(elements); result.removeAll(set.asCollection()); return new SetValueImpl(getTypeId(), result); } @Override public @NonNull OrderedSetValue sort(@NonNull Comparator<Object> comparator) { List<Object> values = new ArrayList<Object>(elements); Collections.sort(values, comparator); return new SparseOrderedSetValueImpl(getOrderedSetTypeId(), values); } @Override public @NonNull SetValue symmetricDifference(@NonNull UniqueCollectionValue set) { Set<Object> result = new HashSet<Object>(elements); for (Object e : set.iterable()) { if (result.contains(e)) { result.remove(e); } else { result.add(e); } } return new SetValueImpl(getTypeId(), result); } @Override public SequenceValue toSequenceValue() { return new SparseSequenceValueImpl(getSequenceTypeId(), SparseSequenceValueImpl.createSequenceOfEach(elements)); } @Override public void toString(@NonNull StringBuilder s, int lengthLimit) { s.append(TypeId.SET_NAME); super.toString(s, lengthLimit); } }