/**
* This file is part of Archiv-Editor.
*
* The software Archiv-Editor serves as a client user interface for working with
* the Person Data Repository. See: pdr.bbaw.de
*
* The software Archiv-Editor was developed at the Berlin-Brandenburg Academy
* of Sciences and Humanities, Jägerstr. 22/23, D-10117 Berlin.
* www.bbaw.de
*
* Copyright (C) 2010-2013 Berlin-Brandenburg Academy
* of Sciences and Humanities
*
* The software Archiv-Editor was developed by @author: Christoph Plutte.
*
* Archiv-Editor 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.
*
* Archiv-Editor 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 Archiv-Editor.
* If not, see <http://www.gnu.org/licenses/lgpl-3.0.html>.
*/
package org.bbaw.pdr.ae.control.comparator;
import java.util.Comparator;
import java.util.TreeSet;
import org.bbaw.pdr.ae.metamodel.PdrDate;
import org.bbaw.pdr.ae.model.Aspect;
import org.bbaw.pdr.ae.model.TaggingRange;
import org.bbaw.pdr.ae.model.Time;
import org.bbaw.pdr.ae.model.TimeStm;
/**
* comparator for aspects by chronological order.
* <p>If comparator is set to ascending order, two aspects are put in order
* by comparing their earliest temporal informations. In descending mode,
* this comparator only cares about an aspect's latest temporal information.</p>
* @author Christoph Plutte, Jakob Höper
*/
public class AspectsByCronComparator implements Comparator<Aspect>
{
/** ascending flag. */
private boolean _ascending;
/**
* constructor defaulting to ascending order.
*/
public AspectsByCronComparator()
{
this._ascending = true;
}
/**
* constructor with ascending/descending flag
* @param ascending If set true, comparator will sort in ascending order.
*/
public AspectsByCronComparator(final boolean ascending)
{
this._ascending = ascending;
}
@Override
public final int compare(final Aspect a1, final Aspect a2)
{
int diff = 0;
PdrDate d1 = null;
PdrDate d2 = null;
if (this._ascending) {
d1 = getEarliest(a1);
d2 = getEarliest(a2);
} else {
d1 = getLatest(a1);
d2 = getLatest(a2);
}
/*if (a1.getTimeDim() != null && a1.getTimeDim().getTimeStms() != null)
{
for (int i = 0; i < a1.getTimeDim().getTimeStms().size(); i++)
{
if (a1.getTimeDim().getTimeStms().get(i).getTimes() != null)
{
for (int j = 0; j < a1.getTimeDim().getTimeStms().get(i).getTimes().size(); j++)
{
if (a1.getTimeDim().getTimeStms().get(i).getTimes().get(j) != null
&& a1.getTimeDim().getTimeStms().get(i).getTimes().get(j).getTimeStamp() != null)
{
d1 = a1.getTimeDim().getTimeStms().get(i).getTimes().get(j).getTimeStamp();
break;
}
}
if (d1 != null)
{
break;
}
}
}
if (a2.getTimeDim() != null && a2.getTimeDim().getTimeStms() != null)
{
for (int i = 0; i < a2.getTimeDim().getTimeStms().size(); i++)
{
if (a2.getTimeDim().getTimeStms().get(i).getTimes() != null)
{
for (int j = 0; j < a2.getTimeDim().getTimeStms().get(i).getTimes().size(); j++)
{
if (a2.getTimeDim().getTimeStms().get(i).getTimes().get(j) != null
&& a2.getTimeDim().getTimeStms().get(i).getTimes().get(j).getTimeStamp() != null)
{
d2 = a2.getTimeDim().getTimeStms().get(i).getTimes().get(j).getTimeStamp();
if (d1 != null)
{
return d1.compare(d2) * (this._ascending ? 1 : -1);
}
}
}
}
}
}
}
// FIXME: die hinterste taggingrange überschreibt alle vorangehenden. nicht optimal.
if (d2 == null)
{
if (a2.getRangeList() != null && a2.getRangeList().size() > 0)
{
for (TaggingRange tr : a2.getRangeList())
{
if (tr.getWhen() != null)
{
d2 = tr.getWhen();
break;
}
if (tr.getNotBefore() != null)
{
d2 = tr.getNotBefore();
break;
}
if (tr.getFrom() != null)
{
d2 = tr.getFrom();
break;
}
if (tr.getNotAfter() != null)
{
d2 = tr.getNotAfter();
break;
}
if (tr.getTo() != null)
{
d2 = tr.getTo();
break;
}
}
}
}
if (d1 == null)
{
if (a1.getRangeList() != null && a1.getRangeList().size() > 0)
{
for (TaggingRange tr : a1.getRangeList())
{
if (tr.getWhen() != null)
{
d1 = tr.getWhen();
break;
}
if (tr.getNotBefore() != null)
{
d1 = tr.getNotBefore();
break;
}
if (tr.getFrom() != null)
{
d1 = tr.getFrom();
break;
}
if (tr.getNotAfter() != null)
{
d1 = tr.getNotAfter();
break;
}
if (tr.getTo() != null)
{
d1 = tr.getTo();
break;
}
}
}
}*/
if (d1 != null && d2 != null) {
diff = d1.compare(d2);
} else if (d1 != null) {
diff = d1.getValue(); //-1;
} else if (d2 != null) {
diff = -d2.getValue(); //1;
}
return diff * (_ascending ? 1 : -1);
}
/**
* Returns whatever time is the earliest or latest that the given {@link Aspect} is about.
* If the aspect has {@link TimeStm} information, it is preferred over temporal
* information that might be extractable from the aspect's {@link TaggingRange}s.
* @param a
* @param earliest pass true if earliest date is desired, false if latest
* @return earliest or latest {@link PdrDate} mentioned, or null if no temporal information.
*/
private static PdrDate getEarliestOrLatest(Aspect a, boolean earliest) {
TreeSet<PdrDate> dates = new TreeSet<PdrDate>();
if (a.getTimeDim() != null && a.getTimeDim().getTimeStms() != null)
for (TimeStm stm : a.getTimeDim().getTimeStms())
if (stm.getTimes() != null)
for (Time t : stm.getTimes())
if (t.getTimeStamp() != null)
dates.add(t.getTimeStamp());
if (dates.size() > 0) return earliest ? dates.first() : dates.last();
// if no time statements in metadata, use markup data of notification text
if (a.getRangeList() != null)
for (TaggingRange tag : a.getRangeList()) {
PdrDate date = getEarliest(tag);
if (date != null)
dates.add(date);
}
if (dates.size() > 0) return earliest ? dates.first() : dates.last();
return null;
}
/**
* Returns whatever time is the earliest that the given {@link Aspect} is about.
* If the aspect has {@link TimeStm} information, it is preferred over temporal
* information that might be extractable from the aspect's {@link TaggingRange}s.
* @param a
* @return earliest {@link PdrDate} mentioned, or null if no temporal information.
*/
public static PdrDate getEarliest(Aspect a) {
return getEarliestOrLatest(a, true);
}
/**
* Returns whatever time is the latest that the given {@link Aspect} is about.
* If the aspect has {@link TimeStm} information, it is preferred over temporal
* information that might be extractable from the aspect's {@link TaggingRange}s.
* @param a
* @return latest {@link PdrDate} mentioned, or null if no temporal information.
*/
public static PdrDate getLatest(Aspect a) {
return getEarliestOrLatest(a, false);
}
/**
* Returns the earliest temporal meta-information encoded in a given
* {@link TaggingRange} as a {@link PdrDate}.
* @param tag {@link TaggingRange} object to look at.
* @return {@link PdrDate} storing the earliest time the given tag is about, or null if no
* temporal information is available.
* @see TaggingRange
* @see #getLatest(TaggingRange)
*/
public static PdrDate getEarliest(TaggingRange tag) {
TreeSet<PdrDate> dates = getTagDates(tag);
for (PdrDate date : dates)
if (date != null) return date;
return null;
}
/**
* Returns the latest temporal meta-information encoded in a given
* {@link TaggingRange} as a {@link PdrDate}.
* @param tag {@link TaggingRange} object to look at.
* @return {@link PdrDate} storing the latest time the given tag is about, or null if no
* temporal information is available.
* @see TaggingRange
* @see #getEarliest(TaggingRange)
*/
public static PdrDate getLatest(TaggingRange tag) {
TreeSet<PdrDate> dates = getTagDates(tag);
PdrDate date = dates.pollLast();
while (date == null)
date = dates.pollLast();
return date;
}
/**
* Returns all {@link PdrDate}-encoded temporal information held by the
* given {@link TaggingRange} in chronological order.
* @param tag
* @return
*/
private static TreeSet<PdrDate> getTagDates(TaggingRange tag) {
TreeSet<PdrDate> dates = new TreeSet<PdrDate>();
if (tag.getWhen() != null) dates.add(tag.getWhen());
if (tag.getNotAfter() != null) dates.add(tag.getNotAfter());
if (tag.getFrom() != null) dates.add(tag.getFrom());
if (tag.getNotAfter() != null) dates.add(tag.getNotAfter());
if (tag.getTo() != null) dates.add(tag.getTo());
return dates;
}
}