All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eobjects.analyzer.beans.dategap.TimeLine Maven / Gradle / Ivy

/**
 * AnalyzerBeans
 * Copyright (C) 2014 Neopost - Customer Information Management
 *
 * This copyrighted material is made available to anyone wishing to use, modify,
 * copy, or redistribute it subject to the terms and conditions of the GNU
 * Lesser General Public License, as published by the Free Software Foundation.
 *
 * This program 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 this distribution; if not, write to:
 * Free Software Foundation, Inc.
 * 51 Franklin Street, Fifth Floor
 * Boston, MA  02110-1301  USA
 */
package org.eobjects.analyzer.beans.dategap;

import java.io.Serializable;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.NavigableSet;
import java.util.SortedSet;
import java.util.TreeSet;

/**
 * Represents a timeline of some entity. A timeline contains several intervals.
 * 
 * 
 */
public class TimeLine implements Serializable {

	private static final long serialVersionUID = 1L;

	private NavigableSet intervals = new TreeSet();

	public TimeLine() {
	}

	public void addInterval(TimeInterval i) {
		intervals.add(i);
	}

	/**
	 * Gets the intervals registered in this timeline
	 * 
	 * @return
	 */
	public SortedSet getIntervals() {
		return Collections.unmodifiableSortedSet(intervals);
	}

	/**
	 * Gets a set of intervals without any overlaps
	 * 
	 * @return
	 */
	public SortedSet getFlattenedIntervals() {
		return getFlattenedIntervals(intervals);
	}

	private SortedSet getFlattenedIntervals(SortedSet intervals) {
		SortedSet result = new TreeSet();
		for (TimeInterval interval : intervals) {
			for (Iterator it = result.iterator(); it.hasNext();) {
				TimeInterval ti = it.next();
				if (ti.overlapsWith(interval)) {
					it.remove();
					interval = TimeInterval.merge(ti, interval);
				}
			}
			result.add(interval);
		}

		return result;
	}

	/**
	 * Gets a set of intervals representing the times where there are more than
	 * one interval overlaps.
	 * 
	 * @param includeSingleTimeInstanceIntervals
	 *            whether or not to include intervals if only the ends of two
	 *            (or more) intervals are overlapping. If, for example, there
	 *            are two intervals, A-to-B and B-to-C. Should "B-to-B" be
	 *            included because B actually overlaps?
	 * 
	 * @return
	 */
	public SortedSet getOverlappingIntervals(boolean includeSingleTimeInstanceIntervals) {
		SortedSet result = new TreeSet();
		for (TimeInterval interval1 : intervals) {
			for (TimeInterval interval2 : intervals) {
				if (interval1 != interval2) {
					TimeInterval overlap = interval1.getOverlap(interval2);
					if (overlap != null) {
						result.add(overlap);
					}
				}
			}
		}

		result = getFlattenedIntervals(result);

		if (!includeSingleTimeInstanceIntervals) {
			for (Iterator it = result.iterator(); it.hasNext();) {
				TimeInterval timeInterval = it.next();
				if (timeInterval.isSingleTimeInstance()) {
					it.remove();
				}
			}
		}

		return result;
	}

	/**
	 * Gets a set of intervals representing the times that are NOT represented
	 * in this timeline.
	 * 
	 * @return
	 */
	public SortedSet getTimeGapIntervals() {
		SortedSet flattenedIntervals = getFlattenedIntervals();
		SortedSet gaps = new TreeSet();

		TimeInterval previous = null;
		for (TimeInterval timeInterval : flattenedIntervals) {
			if (previous != null) {
				long from = previous.getTo();
				long to = timeInterval.getFrom();
				TimeInterval gap = new TimeInterval(from, to);
				gaps.add(gap);
			}
			previous = timeInterval;
		}

		return gaps;
	}

	/**
	 * Gets the first date in this timeline
	 * 
	 * @return
	 */
	public Date getFrom() {
		TimeInterval first = intervals.first();
		if (first != null) {
			return new Date(first.getFrom());
		}
		return null;
	}

	/**
	 * Gets the last date in this timeline
	 * 
	 * @return
	 */
	public Date getTo() {
		Long to = null;
		for (TimeInterval interval : intervals) {
			if (to == null) {
				to = interval.getTo();
			} else {
				to = Math.max(interval.getTo(), to);
			}
		}
		if (to != null) {
			return new Date(to);
		}
		return null;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy