/*
Copyright (C) 2008-2010 by Claas Wilke (claas.wilke@tu-dresden.de)
This file is part of the OCL 2 Java Code Generator of Dresden OCL.
Dresden OCL 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 OCL 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 OCL. If not, see <http://www.gnu.org/licenses/>.
*/
package org.dresdenocl.tools.codegen.ocl2java.types.util;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import org.dresdenocl.tools.codegen.ocl2java.types.OclInvalidException;
/**
* <p>
* Represents utility class to provide operations of OCL Ordered Sets in Java.
* </p>
*
* @author Claas Wilke
*/
public class OclOrderedSets {
/**
* <p>
* Returns the set of elements, consisting of all elements of self, followed
* by object.
* </p>
*
* @param self
* The {@link List} representing self.
* @param object
* The object to be appended.
* @return The set of elements, consisting of all elements of self, followed
* by object.
*/
public static <T extends Object> List<T> append(List<T> self, T object) {
List<T> result;
/* OCL Collections cannot be null. */
if (self == null) {
result = new ArrayList<T>();
}
else {
result = new ArrayList<T>(self);
}
// end else.
if (!result.contains(object)) {
result.add(object);
}
return result;
}
/**
* <p>
* Returns the set of elements, consisting of all elements of self, followed
* by object.
* </p>
*
* @param self
* The array representing self.
* @param object
* The object to be appended.
* @return The set of elements, consisting of all elements of self, followed
* by object.
*/
public static <T extends Object> List<T> append(T[] self, T object) {
List<T> result;
/* OCL Collections cannot be null. */
if (self == null) {
result = new ArrayList<T>();
}
else {
result = new ArrayList<T>(Arrays.asList(self));
}
// end else.
if (!result.contains(object)) {
result.add(object);
}
return result;
}
/**
* <p>
* Returns the Bag that contains all the elements from self.
* </p>
*
* @param self
* The {@link List} representing self.
* @return The Bag that contains all the elements from self.
*/
public static <T extends Object> List<T> asBag(List<T> self) {
/* First ensure that List is an ordered set. */
return OclCollections.asBag(OclCollections.asOrderedSet(self));
}
/**
* <p>
* Returns the Bag that contains all the elements from self.
* </p>
*
* @param self
* The array representing self.
* @return The Bag that contains all the elements from self.
*/
public static <T extends Object> List<T> asBag(T[] self) {
/* First ensure that List is an ordered set. */
return OclCollections.asBag(OclCollections.asOrderedSet(self));
}
/**
* <p>
* Returns an OrderedSet that contains all the elements from self, with
* duplicates removed, in an order dependent on the particular concrete
* collection type.
* </p>
*
* @param self
* The {@link List} representing self.
* @return An OrderedSet that contains all the elements from self, with
* duplicates removed, in an order dependent on the particular
* concrete collection type.
*/
public static <T extends Object> List<T> asOrderedSet(List<T> self) {
return OclCollections.asOrderedSet(self);
}
/**
* <p>
* Returns an OrderedSet that contains all the elements from self, with
* duplicates removed, in an order dependent on the particular concrete
* collection type.
* </p>
*
* @param self
* The array representing self.
* @return An OrderedSet that contains all the elements from self, with
* duplicates removed, in an order dependent on the particular
* concrete collection type.
*/
public static <T extends Object> List<T> asOrderedSet(T[] self) {
return OclCollections.asOrderedSet(self);
}
/**
* <p>
* Returns the Sequence that contains all the elements from self, in an
* order dependent on the particular concrete collection type.
* </p>
*
* @param self
* The {@link List} representing self.
* @return The Sequence that contains all the elements from self, in an
* order dependent on the particular concrete collection type.
*/
public static <T extends Object> List<T> asSequence(List<T> self) {
/* First ensure that List is an ordered set. */
return OclCollections.asSequence(OclCollections.asOrderedSet(self));
}
/**
* <p>
* Returns the Sequence that contains all the elements from self, in an
* order dependent on the particular concrete collection type.
* </p>
*
* @param self
* The array representing self.
* @return The Sequence that contains all the elements from self, in an
* order dependent on the particular concrete collection type.
*/
public static <T extends Object> List<T> asSequence(T[] self) {
/* First ensure that List is an ordered set. */
return OclCollections.asSequence(OclCollections.asOrderedSet(self));
}
/**
* <p>
* Returns the Set containing all the elements from self, with duplicates
* removed.
* </p>
*
* @param self
* The {@link List} representing self.
* @return The Set containing all the elements from self, with duplicates
* removed.
*/
public static <T extends Object> Set<T> asSet(List<T> self) {
return OclCollections.asSet(self);
}
/**
* <p>
* Returns the Set containing all the elements from self, with duplicates
* removed.
* </p>
*
* @param self
* The array representing self.
* @return The Set containing all the elements from self, with duplicates
* removed.
*/
public static <T extends Object> Set<T> asSet(T[] self) {
return OclCollections.asSet(self);
}
/**
* <p>
* Returns the i-th element of self.
* </p>
*
* @param self
* The {@link List} representing self.
* @param i
* The index of the object to return (<strong>Indexes in OCL
* start with 1!</strong>).
* @return The i-th element of self.
*/
public static <T extends Object> T at(List<T> self, Integer i) {
/* OCL Collections cannot be null. */
if (self == null || self.size() == 0) {
throw new OclInvalidException(
"Cannot invoke at() on empty OrderedSets.");
}
// no else.
if (i < 1 || i > self.size()) {
throw new OclInvalidException("Index must lay between 1 and "
+ self.size() + " but was " + i + ".");
}
// no else.
return self.get(i - 1);
}
/**
* <p>
* Returns the i-th element of self.
* </p>
*
* @param self
* The array representing self.
* @param i
* The index of the object to return (<strong>Indexes in OCL
* start with 1!</strong>).
* @return The i-th element of self.
*/
public static <T extends Object> T at(T[] self, Integer i) {
/* OCL Collections cannot be null. */
if (self == null) {
return at(new ArrayList<T>(), i);
}
else {
return at(new ArrayList<T>(Arrays.asList(self)), i);
}
// end else.
}
/**
* <p>
* Returns the first element in self.
* </p>
*
* @param self
* The {@link List} representing self.
* @return The first element in self.
*/
public static <T extends Object> T first(List<T> self) {
/* OCL Collections cannot be null. */
if (self == null || self.size() == 0) {
throw new OclInvalidException(
"Cannot invoke operation first() on an empty OrderedSet.");
}
// no else.
/* First ensure that self is an ordered set. */
return OclCollections.asOrderedSet(self).get(0);
}
/**
* <p>
* Returns the first element in self.
* </p>
*
* @param self
* The array representing self.
* @return The first element in self.
*/
public static <T extends Object> T first(T[] self) {
/* OCL Collections cannot be null. */
if (self == null || self.length == 0) {
throw new OclInvalidException(
"Cannot invoke operation first() on an empty OrderedSet.");
}
// no else.
/* First ensure that self is an ordered set. */
return OclCollections.asOrderedSet(self).get(0);
}
/**
* <p>
* Returns the index of object in the OrderedSet (<strong>Indexes in OCL
* start with 1!</strong>).
* </p>
*
* @param self
* The {@link List} representing self.
* @param object
* The object to be indexed.
* @return The index of object in the OrderedSet.
*/
public static <T extends Object> Integer indexOf(List<T> self, T object) {
/* OCL Collections cannot be null. */
if (self == null || self.size() == 0 || !self.contains(object)) {
throw new OclInvalidException(
"The given object is not contained in self.");
}
// no else.
/* First ensure that self is an ordered set. */
return OclCollections.asOrderedSet(self).indexOf(object) + 1;
}
/**
* <p>
* Returns the index of object in the OrderedSet (<strong>Indexes in OCL
* start with 1!</strong>).
* </p>
*
* @param self
* The array representing self.
* @param object
* The object to be indexed.
* @return The index of object in the OrderedSet.
*/
public static <T extends Object> Integer indexOf(T[] self, T object) {
/* OCL Collections cannot be null. */
if (self == null) {
return indexOf(new ArrayList<T>(), object);
}
else {
return indexOf(Arrays.asList(self), object);
}
// end else.
}
/**
* <p>
* Returns the set consisting of self with object inserted at position
* index.
* </p>
*
* @param self
* The {@link List} representing self.
* @param index
* The index where to add the object (<strong>Indexes in OCL
* start with 1!</strong>).
* @param object
* The object to be inserted.
* @return The set consisting of self with object inserted at position
* index.
*/
public static <T extends Object> List<T> insertAt(List<T> self,
Integer index, T object) {
List<T> result;
/* OCL Collections cannot be null. */
if (self == null) {
result = new ArrayList<T>();
}
else {
result = new ArrayList<T>(self);
}
// end else.
if (index < 1 || index > result.size() + 1) {
throw new OclInvalidException("Index must lay between 1 and "
+ (result.size() + 1) + " but was " + index + ".");
}
// no else.
/* First ensure that self is an ordered set. */
result = OclCollections.asOrderedSet(result);
if (!result.contains(object)) {
result.add(index - 1, object);
}
return result;
}
/**
* <p>
* Returns the set consisting of self with object inserted at position
* index.
* </p>
*
* @param self
* The array representing self.
* @param index
* The index where to add the object (<strong>Indexes in OCL
* start with 1!</strong>).
* @param object
* The object to be inserted.
* @return The set consisting of self with object inserted at position
* index.
*/
public static <T extends Object> List<T> insertAt(T[] self, Integer index,
T object) {
/* OCL Collections cannot be null. */
if (self == null) {
return insertAt(new ArrayList<T>(), index, object);
}
else {
return insertAt(new ArrayList<T>(Arrays.asList(self)), index,
object);
}
// end else.
}
/**
* <p>
* Returns the last element in self.
* </p>
*
* @param self
* The {@link List} representing self.
* @return The last element in self.
*/
public static <T extends Object> T last(List<T> self) {
/* OCL Collections cannot be null. */
if (self == null || self.size() == 0) {
throw new OclInvalidException(
"Cannot invoke operation first() on an empty OrderedSet.");
}
// no else.
/* First ensure that self is an ordered set. */
List<T> resultList = OclCollections.asOrderedSet(self);
return resultList.get(resultList.size() - 1);
}
/**
* <p>
* Returns the last element in self.
* </p>
*
* @param self
* The array representing self.
* @return The last element in self.
*/
public static <T extends Object> T last(T[] self) {
/* OCL Collections cannot be null. */
if (self == null || self.length == 0) {
throw new OclInvalidException(
"Cannot invoke operation last() on an empty OrderedSet.");
}
// no else.
return self[self.length - 1];
}
/**
* <p>
* Returns the ordered set consisting of object, followed by all elements in
* self.
* </p>
*
* @param self
* The {@link List} representing self.
* @param object
* The object to be prepended.
* @return The ordered set consisting of object, followed by all elements in
* self.
*/
public static <T extends Object> List<T> prepend(List<T> self, T object) {
List<T> result;
result = new ArrayList<T>();
result.add(object);
/* OCL Collections cannot be null. */
if (self == null) {
return result;
}
else {
for (T element : self) {
if (!result.contains(element)) {
result.add(element);
}
// no else.
}
return result;
}
}
/**
* <p>
* Returns the ordered set consisting of object, followed by all elements in
* self.
* </p>
*
* @param self
* The array representing self.
* @param object
* The object to be prepended.
* @return The ordered set consisting of object, followed by all elements in
* self.
*/
public static <T extends Object> List<T> prepend(T[] self, T object) {
List<T> result;
/* OCL Collections cannot be null. */
if (self == null) {
result = prepend(new ArrayList<T>(), object);
}
else {
result = prepend(new ArrayList<T>(Arrays.asList(self)), object);
}
// end else.
return result;
}
/**
* <p>
* Returns the ordered set of elements with same elements but with the
* opposite order.
* </p>
*
* @param self
* The {@link List} representing self.
* @return The ordered set of elements with same elements but with the
* opposite order.
*/
public static <T extends Object> List<T> reverse(List<T> self) {
List<T> result;
result = new ArrayList<T>();
/* OCL Collections cannot be null. */
if (self != null) {
for (T element : self) {
if (!result.contains(element)) {
result.add(0, element);
}
// no else.
}
// end for.
}
// no else.
return result;
}
/**
* <p>
* Returns the ordered set of elements with same elements but with the
* opposite order.
* </p>
*
* @param self
* The array representing self.
* @return The ordered set of elements with same elements but with the
* opposite order.
*/
public static <T extends Object> List<T> reverse(T[] self) {
/* OCL Collections cannot be null. */
if (self == null) {
return new ArrayList<T>();
}
else {
return reverse(Arrays.asList(self));
}
}
/**
* <p>
* Returns the sub-set of self starting at number lower, up to and including
* element number upper.
* </p>
*
* @param self
* The {@link List} representing self.
* @param lower
* The lower index (<strong>Indexes in OCL start with
* 1!</strong>).
* @param lower
* The upper index (<strong>Indexes in OCL start with
* 1!</strong>).
* @return The sub-set of self starting at number lower, up to and including
* element number upper.
*/
public static <T extends Object> List<T> subOrderedSet(List<T> self,
Integer lower, Integer upper) {
/* OCL Collections cannot be null. */
if (self == null || self.size() == 0) {
throw new OclInvalidException(
"Cannot invoke subOrderedSet() on empty OrderedSets.");
}
else {
self = new ArrayList<T>(self);
}
// end else.
/* First ensure that self is an ordered set. */
List<T> result;
result = OclCollections.asOrderedSet(self);
if (lower < 1 || lower > result.size()) {
throw new OclInvalidException("Index lower must lay between 1 and "
+ result.size() + " but was " + lower + ".");
}
// no else.
if (upper < 1 || upper > result.size()) {
throw new OclInvalidException("Index upper must lay between 1 and "
+ result.size() + " but was " + upper + ".");
}
// no else.
if (lower > upper) {
throw new OclInvalidException(
"Index lower must be equal or less than upper.");
}
// no else.
result = result.subList(lower - 1, upper);
return result;
}
/**
* <p>
* Returns the sub-set of self starting at number lower, up to and including
* element number upper.
* </p>
*
* @param self
* The array representing self.
* @param lower
* The lower index (<strong>Indexes in OCL start with
* 1!</strong>).
* @param lower
* The upper index (<strong>Indexes in OCL start with
* 1!</strong>).
* @return The sub-set of self starting at number lower, up to and including
* element number upper.
*/
public static <T extends Object> List<T> subOrderedSet(T[] self,
Integer lower, Integer upper) {
/* OCL Collections cannot be null. */
if (self == null) {
return subOrderedSet(new ArrayList<T>(), lower, upper);
}
else {
return subOrderedSet(new ArrayList<T>(Arrays.asList(self)), lower,
upper);
}
// end else.
}
}