/* * Copyright (c) 2017 OBiBa. All rights reserved. * * This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.obiba.magma; import java.io.Serializable; import java.util.Comparator; import java.util.List; import javax.annotation.Nullable; import javax.validation.constraints.NotNull; import org.obiba.magma.type.BinaryType; import org.obiba.magma.type.LocaleType; import com.google.common.collect.ImmutableList; import com.google.common.collect.Ordering; /** * A {@code Value} instance that holds a sequence of other {@code Value} instances (its elements). The {@code ValueType} * of the sequence is the same as its elements. That is, if the elements have a value type {@code BooleanType}, then * this {@code ValueSequence} instance also has {@code BooleanType} as its value type. */ public class ValueSequence extends Value { private static final long serialVersionUID = -1965362009370797808L; ValueSequence(@NotNull ValueType valueType, @Nullable Iterable<Value> values) { super(valueType, (Serializable) values); } @Override public boolean isSequence() { return true; } @NotNull @Override public ValueSequence asSequence() { return this; } @NotNull @Override public Value copy() { return getValueType().sequenceOf(getValue()); } @NotNull @Override @SuppressWarnings("unchecked") public Iterable<Value> getValue() { return (Iterable<Value>) super.getValue(); } /** * Returns a copy of this {@link ValueSequence} with the {@link Value}s sorted in the natural order provided that the * {@code ValueSequence} was constructed with an {@link Iterable} value that is also of the type {@link List}. If the * {@code Iterable} value is not of type {@code List} then this method will have no effect. Note that some * {@link ValueType}s such as {@link BinaryType} and {@link LocaleType} do not have a natural sort order and * {@code ValueSequence}s of those types will not be modified by this method. */ public ValueSequence sort() { return getValueType().sequenceOf(Ordering.natural().immutableSortedCopy(getValue())); } /** * Returns a copy of this {@link ValueSequence} with the {@link Value}s sorted based on the specific * {@link Comparator} implementation. * * @param comparator Custom Comparator which will be used to sort the ValueSequence. */ public ValueSequence sort(Comparator<Value> comparator) { return getValueType().sequenceOf(Ordering.from(comparator).immutableSortedCopy(getValue())); } /** * The length of this sequence * * @return */ public int getSize() { return getValues().size(); } /** * The size is the sum of the size of the values in the sequence. * * @return */ @Override public long getLength() { long size = 0; for(Value val : getValues()) { size += val.getLength(); } return size; } /** * Returns an ordered view of the values. * * @return */ @NotNull public List<Value> getValues() { return isNull() ? ImmutableList.<Value>of() : ImmutableList.copyOf(getValue()); } /** * Returns the {@code i}th element of the sequence * * @param i * @return * @throws IndexOutOfBoundsException when {@code i >=} {@code #getSize()} */ public Value get(int i) { return getValues().get(i); } /** * Returns true if this sequence contains the specified {@code Value} * * @param value * @return */ public boolean contains(@NotNull Value value) { return getValues().contains(value); } /** * Get the first position of a {@link Value} in the sequence. * * @param value * @return -1 if not found */ public int indexOf(@NotNull Value value) { return getValues().indexOf(value); } /** * Get the last position of a {@link Value} in the sequence. * * @param value * @return -1 if not found */ public int lastIndexOf(@NotNull Value value) { return getValues().lastIndexOf(value); } }