/* * Copyright 2013 Martin Smock <smock.martin@gmail.com> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package li.strolch.model.timevalue.impl; import java.io.Serializable; import java.util.Collection; import java.util.Iterator; import java.util.SortedSet; import java.util.TreeSet; import li.strolch.model.timevalue.ITimeValue; import li.strolch.model.timevalue.ITimeVariable; import li.strolch.model.timevalue.IValue; import li.strolch.model.timevalue.IValueChange; /** * @author Martin Smock <smock.martin@gmail.com> */ @SuppressWarnings("rawtypes") public class TimeVariable<T extends IValue> implements ITimeVariable<T>, Serializable { private static final long serialVersionUID = 1L; public SortedSet<ITimeValue<T>> container = new TreeSet<>(); @Override public ITimeValue<T> getValueAt(final Long time) { ITimeValue<T> tmp = null; for (ITimeValue<T> value : this.container) { if (value.getTime() <= time) { tmp = value; } else { break; } } return tmp; } @Override public void setValueAt(final Long time, final T targetValue) { ITimeValue<T> current = getValueAt(time); if (current != null && current.getTime().equals(time)) { current.setValue(targetValue); } else { this.container.add(new TimeValue<>(time, targetValue)); } } @Override public SortedSet<ITimeValue<T>> getFutureValues(final Long time) { TimeValue<T> picker = new TimeValue<>(time, null); return new TreeSet<>(this.container.tailSet(picker)); } @Override public Collection<ITimeValue<T>> getPastValues(final Long time) { TimeValue<T> picker = new TimeValue<>(time, null); return new TreeSet<>(this.container.headSet(picker)); } @Override public SortedSet<ITimeValue<T>> getValues() { return new TreeSet<>(this.container); } @Override public void applyChange(final IValueChange<T> change) { SortedSet<ITimeValue<T>> futureValues = getFutureValues(change.getTime()); for (ITimeValue<T> value : futureValues) { value.add(change.getValue()); } ITimeValue<T> initialValue = getValueAt(change.getTime()); if (initialValue == null) { ITimeValue<T> newValue = new TimeValue<>(change.getTime(), change.getValue()); this.container.add(newValue); } else if (initialValue.getTime().longValue() < change.getTime().longValue()) { ITimeValue<T> newValue = new TimeValue<>(change.getTime(), initialValue.getValue()); newValue.add(change.getValue()); this.container.add(newValue); } compact(); } @SuppressWarnings("unchecked") @Override public void compact() { if (this.container.size() < 2) { return; } Iterator<ITimeValue<T>> iterator = this.container.iterator(); ITimeValue<T> predecessor = iterator.next(); while (iterator.hasNext()) { ITimeValue<T> successor = iterator.next(); if (successor.getValue().matches(predecessor.getValue())) { iterator.remove(); } else { predecessor = successor; } } } @Override public void clear() { this.container.clear(); } @Override public ITimeVariable<T> getCopy() { TimeVariable<T> clone = new TimeVariable<>(); for (ITimeValue<T> timeValue : this.container) { clone.container.add(timeValue.getCopy()); } return clone; } }