Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/**
*
*
* Copyright (c) 2006, 2008, 2011 IBM Corporation, Zeligsoft Inc., 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:
* IBM - Initial API and implementation
* Zeligsoft - Bugs 244946, 248869
* Axel Uhl (SAP AG) - Bug 342644
*
*
*
* $Id: CollectionUtil.java,v 1.10 2011/05/01 10:56:50 auhl Exp $
*/
package org.eclipse.ocl.util;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.ocl.Environment;
import org.eclipse.ocl.EvaluationEnvironment;
import org.eclipse.ocl.expressions.CollectionKind;
import org.eclipse.ocl.internal.OCLPlugin;
import org.eclipse.ocl.internal.l10n.OCLMessages;
import org.eclipse.ocl.types.CollectionType;
/**
* Utility methods for working with OCL collection values.
*
* @author Christian W. Damus (cdamus)
*/
public class CollectionUtil {
// not instantiable
private CollectionUtil() {
super();
}
/**
* Implementation of the OCL
* Collection::includes(object : T) : Boolean
* operation.
*
* @param self the source collection
* @param object an object
* @return whether the collection includes the object
*/
public static boolean includes(Collection> self, Object object) {
return self.contains(object);
}
/**
* Implementation of the OCL
* Collection::excludes(object : T) : Boolean
* operation.
*
* @param self the source collection
* @param object an object
* @return whether the collection does not include the object
*/
public static boolean excludes(Collection> self, Object object) {
return !includes(self, object);
}
/**
* Implementation of the OCL
* Collection::count(object : T) : Integer
* operation.
*
* @param self the source collection
* @param object an object
* @return the number of occurrences of the object in the collection
*/
public static int count(Collection> self, Object object) {
int count = 0;
for (Object next : self) {
if (ObjectUtil.equal(next, object)) {
count++;
}
}
return count;
}
/**
* Implementation of the OCL
* Collection::includesAll(c : Collection(T)) : Boolean
* operation.
*
* @param self the source collection
* @param c another collection
* @return whether the source collection includes all of the elements
* of the other
*/
public static boolean includesAll(Collection> self, Collection> c) {
for (Object next : c) {
if (!includes(self, next)) {
return false;
}
}
return true;
}
/**
* Implementation of the OCL
* Collection::excludesAll(c : Collection(T)) : Boolean
* operation.
*
* @param self the source collection
* @param c another collection
* @return whether the source collection does not contain any of the
* elements of the other
*/
public static boolean excludesAll(Collection> self, Collection> c) {
for (Object next : c) {
if (includes(self, next)) {
return false;
}
}
return true;
}
/**
* Implementation of the OCL
* Collection::isEmpty() : Boolean
* operation.
*
* @param self the source collection
* @return whether the collection does not have any elements
*/
public static boolean isEmpty(Collection> self) {
return self.isEmpty();
}
/**
* Implementation of the OCL
* Collection::notEmpty() : Boolean
* operation.
*
* @param self the source collection
* @return whether the collection has any elements
*/
public static boolean notEmpty(Collection> self) {
return !self.isEmpty();
}
/**
* Implementation of the OCL
* Collection::sum() : T
* operation.
*
* @param self the source collection
* @return the sum of the collection's elements
*/
// Assumes the elements of the collection are all Integer or
// all Double.
public static Object sum(Collection> self) {
if (self.isEmpty()) {
return null; // undefined
}
Iterator> it = self.iterator();
Object object = it.next();
// two cases: Integer and Double
if (object instanceof Integer) {
int currVal = 0;
for (it = self.iterator(); it.hasNext();) {
currVal += ((Integer) it.next()).intValue();
}
return new Integer(currVal);
} else if (object instanceof Double) {
double currVal = 0.0;
for (it = self.iterator(); it.hasNext();) {
currVal += ((Double) it.next()).doubleValue();
}
return new Double(currVal);
} else {
IllegalArgumentException error = new IllegalArgumentException(
OCLMessages.SumOperator_ERROR_);
OCLPlugin.throwing(CollectionUtil.class, "sum", error);//$NON-NLS-1$
throw error;
}
}
/**
* Implementation of the OCL
*
*
Set::=(set : Set(T)) : Boolean
*
OrderedSet::=(set : OrderedSet(T)) : Boolean
*
Bag::=(bag : Bag(T)) : Boolean
*
Sequence::=(s : Sequence(T)) : Boolean
*
* operations.
*
* @param self the source collection
* @param c another collection of the same kind
* @return whether collections are equal
*/
public static boolean equals(Collection> self, Collection> c) {
if (self.size() != c.size()) {
// collections of different sizes cannot be equal
return false;
} else if (self instanceof Bag> && c instanceof Bag>) {
return ((Bag>) self).equals(c);
} else if (self instanceof List> && c instanceof List>) {
return ((List>) self).equals(c);
} else if (self instanceof LinkedHashSet> && c instanceof LinkedHashSet>) {
// OrderedSet
// LinkedHashSet.equals() doesn't care about order but we do
int size1 = self.size();
int size2 = c.size();
if (size1 != size2) {
return false;
}
Iterator> it1 = self.iterator();
Iterator> it2 = c.iterator();
while (it1.hasNext()) {
Object o1 = it1.next();
Object o2 = it2.next();
if (!o1.equals(o2)) {
return false;
}
}
return true;
} else if (self instanceof Set> && c instanceof Set>) {
return ((Set>) self).equals(c);
} else {
// incompatible OCL types
return false;
}
}
/**
* Computes the hash of a collection, accounting for the similar hashing of
* primitive numeric values that OCL considers equal but Java does not.
*
* @param c a collection
*
* @return its hash
*/
public static int hashCode(Collection> c) {
int result = 1;
for (Object next : c) {
result = 37 * result + ObjectUtil.hashCode(next);
}
return result;
}
/**
* Implementation of the OCL
*
*
Set::intersection(set : Set(T)) : Set(T)
*
Set::intersection(bag : Bag(T)) : Set(T)
*
Bag::intersection(set : Set(T)) : Set(T)
*
Bag::intersection(bag : Bag(T)) : Set(T)
*
* operations.
*
* @param self the source set or bag
* @param c another set or bag
* @return the intersection of the source set or bag with the other set or bag
*/
public static Collection intersection(
Collection extends E> self, Collection extends E> c) {
int size1 = self.size();
int size2 = c.size();
// if either collection is empty, then so is the result
if (size1 == 0 || size2 == 0) {
if (self instanceof Set> || c instanceof Set>) {
return Collections.emptySet();
} else {
return BagImpl.emptyBag();
}
}
Collection result = null;
if (self instanceof Set> || c instanceof Set>) {
// if either argument is a set, so is the result
if (size1 == 0 || size2 == 0) {
return Collections.emptySet();
}
result = createNewSet();
} else {
// both arguments are bags, so is the result
if (size1 == 0 || size2 == 0) {
return BagImpl.emptyBag();
}
result = createNewBag();
}
// loop over the smaller collection and add only elements
// that are in the larger collection
if (self.size() > c.size()) {
for (E e : c) {
if (includes(self, e)) {
result.add(e);
}
}
} else {
for (E e : self) {
if (includes(c, e)) {
result.add(e);
}
}
}
return result;
}
/**
* Implementation of the OCL
*
*
Set::union(set : Set(T)) : Set(T)
*
Set::union(bag : Bag(T)) : Bag(T)
*
Bag::union(set : Set(T)) : Bag(T)
*
Bag::union(bag : Bag(T)) : Bag(T)
*
Sequence::union(s : Sequence(T)) : Sequence(T)
*
* operations.
*
* @param self the source collection
* @param c another collection
* @return the union of the source collection with the other
*/
public static Collection union(
Collection extends E> self, Collection extends E> c) {
// if either argument is empty, then the union is the other,
// except the source is a set and the other is a bag in which
// case the result has to be a bag
if (self.isEmpty()) {
if (self instanceof Bag || c instanceof Bag) {
return createNewBag(c);
} else {
return createNewCollection(c);
}
} else if (c.isEmpty()) {
if (self instanceof Bag || c instanceof Bag) {
return createNewBag(self);
} else {
return createNewCollection(self);
}
}
Collection result = null;
if (self instanceof Bag> || c instanceof Bag>) {
result = createNewBag(self);
} else if (self instanceof List> || c instanceof List>) {
result = createNewSequence(self);
} else {
result = createNewSet(self);
}
result.addAll(c);
return result;
}
/**
* Implementation of the OCL
*
*
Set::flatten() : Set(T2)
*
Bag::flatten() : Bag(T2)
*
Sequence::flatten() : Sequence(T2)
*
* operations.
*
* @param self the source collection
* @return the flattened collection
*/
public static Collection> flatten(Collection> self) {
// Note: As OCL 2.3 (OMG 10-11-42) section A.2.5.8 fails to specify how to
// flatten an OrderedSet, we choose to flatten it into an OrderedSet
// represented by a LinkedHashSet.
Collection> result = self;
for (;;) {
if (result.isEmpty()) {
break;
}
Iterator> it = result.iterator();
Object object = it.next();
// if the element type is not a collection type, the result is the
// current collection.
if (!(object instanceof Collection>)) {
break;
}
Collection