/* * 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.support; import com.google.common.base.Function; import com.google.common.collect.Iterables; import org.obiba.magma.Timestamped; import org.obiba.magma.Timestamps; import org.obiba.magma.Value; import org.obiba.magma.type.DateTimeType; import javax.validation.constraints.NotNull; import java.util.Arrays; import java.util.Collection; import java.util.stream.Collectors; import java.util.stream.StreamSupport; public class UnionTimestamps implements Timestamps { private final Iterable<Timestamps> timestamps; public UnionTimestamps(Iterable<? extends Timestamped> timestampeds) { timestamps = Iterables.transform(timestampeds, Timestamped.ToTimestamps); } public UnionTimestamps(Collection<Timestamps> timestamps) { this.timestamps = timestamps; } @NotNull @Override public Value getCreated() { return getTimestamp(ExtractCreatedFunction.INSTANCE, true); } @NotNull @Override public Value getLastUpdate() { return getTimestamp(ExtractLastUpdateFunction.INSTANCE, false); } /** * Extracts all the timestamp values, sorts them and returns either the earliest value or the latest value depending * on the {@code earliest} argument. * * @param extractTimestampFunction the function used to extract the timestamp to work with (either created or * lastUpdate) * @param earliest whether to return the earliest value or the latest value * @return the earliest/latest timestamp from the set of timestamps. This method never returns null. */ private Value getTimestamp(Function<Timestamps, Value> extractTimestampFunction, boolean earliest) { Iterable<Value> created = Iterables.transform(timestamps, extractTimestampFunction); Value[] values = Iterables.toArray(getNonNullValues(created), Value.class); if (values.length > 0) { Arrays.sort(values); return values[earliest ? 0 : values.length - 1]; } else { return DateTimeType.get().nullValue(); } } /** * Filters Value instances that are null or that isNull() returns true out of {@code values}. * * @param values * @return */ private Iterable<Value> getNonNullValues(Iterable<Value> values) { return StreamSupport.stream(values.spliterator(), false) // .filter(value -> value != null && !value.isNull()) // .collect(Collectors.toList()); } private static final class ExtractLastUpdateFunction implements Function<Timestamps, Value> { @SuppressWarnings("TypeMayBeWeakened") private static final ExtractLastUpdateFunction INSTANCE = new ExtractLastUpdateFunction(); @Override public Value apply(Timestamps from) { return from == null ? null : from.getLastUpdate(); } } private static final class ExtractCreatedFunction implements Function<Timestamps, Value> { @SuppressWarnings("TypeMayBeWeakened") private static final ExtractCreatedFunction INSTANCE = new ExtractCreatedFunction(); @Override public Value apply(Timestamps from) { return from == null ? null : from.getCreated(); } } }