001: /*--------------------------------------------------------------------------*
002: | Copyright (C) 2006 Christopher Kohlhaas |
003: | |
004: | This program is free software; you can redistribute it and/or modify |
005: | it under the terms of the GNU General Public License as published by the |
006: | Free Software Foundation. A copy of the license has been included with |
007: | these distribution in the COPYING file, if not go to www.fsf.org |
008: | |
009: | As a special exception, you are granted the permissions to link this |
010: | program with every library, which license fulfills the Open Source |
011: | Definition as published by the Open Source Initiative (OSI). |
012: *--------------------------------------------------------------------------*/
013: package org.rapla.facade.internal;
014:
015: import java.util.ArrayList;
016: import java.util.Arrays;
017: import java.util.Collection;
018: import java.util.Comparator;
019: import java.util.Date;
020: import java.util.Iterator;
021: import java.util.List;
022: import java.util.SortedSet;
023: import java.util.TreeSet;
024: import java.lang.Math;
025:
026: import org.rapla.components.util.Assert;
027: import org.rapla.entities.domain.Period;
028: import org.rapla.facade.ClientFacade;
029: import org.rapla.facade.PeriodModel;
030: import org.rapla.facade.QueryModule;
031: import org.rapla.framework.RaplaException;
032:
033: class PeriodModelImpl implements PeriodModel {
034: //public static final String ROLE = PeriodModel.class.getName();
035: TreeSet m_periods = new TreeSet(new Comparator() {
036: public int compare(Object o1, Object o2) {
037: if (o1 instanceof Date) {
038: if (o2 instanceof Date)
039: return ((Date) o1).compareTo((Date) o2);
040: else
041:
042: return -1 * ((Period) o2).compareTo(o1);
043: } else {
044: return ((Period) o1).compareTo(o2);
045: }
046: }
047: });
048: QueryModule query;
049: Period defaultPeriod;
050:
051: PeriodModelImpl(ClientFacade query) throws RaplaException {
052: this .query = query;
053: update();
054: }
055:
056: public void update() throws RaplaException {
057: Period[] periodArray = getQuery().getPeriods();
058: m_periods.clear();
059: m_periods.addAll(Arrays.asList(periodArray));
060: }
061:
062: /** The PeriodModel listeners may not be thread safe.*/
063: public boolean isInvokedOnAWTEventQueue() {
064: return false;
065: }
066:
067: protected QueryModule getQuery() {
068: return query;
069: }
070:
071: /** returns the first matching period or null if no period matches.*/
072: public Period getPeriodFor(Date date) {
073: if (date == null)
074: return null;
075: SortedSet set = m_periods.tailSet(date);
076: if (!set.isEmpty()) {
077: Period period = (Period) set.first();
078: if (period.contains(date))
079: return period;
080: }
081: Iterator it = m_periods.tailSet(date).iterator();
082: while (it.hasNext()) {
083: Period period = (Period) it.next();
084: if (period.contains(date)) {
085: return period;
086: }
087: }
088: return null;
089: }
090:
091: static private long diff(Date d1, Date d2) {
092: long diff = d1.getTime() - d2.getTime();
093: if (diff < 0)
094: diff = diff * -1;
095: return diff;
096: }
097:
098: public Period getNearestPeriodForDate(Date date) {
099: return getNearestPeriodForStartDate(m_periods, date, null);
100: }
101:
102: public Period getNearestPeriodForStartDate(Date date) {
103: return getNearestPeriodForStartDate(date, null);
104: }
105:
106: public Period getNearestPeriodForStartDate(Date date, Date endDate) {
107: return getNearestPeriodForStartDate(getPeriodsFor(date), date,
108: endDate);
109: }
110:
111: public Period getNearestPeriodForEndDate(Date date) {
112: return getNearestPeriodForEndDate(getPeriodsFor(date), date);
113: }
114:
115: static private Period getNearestPeriodForStartDate(
116: Collection periodList, Date date, Date endDate) {
117: Period result = null;
118: long min_from_start = Long.MAX_VALUE, min_from_end = 0;
119: long from_start, from_end = 0;
120: Iterator it = periodList.iterator();
121: while (it.hasNext()) {
122: Period period = (Period) it.next();
123: if (period == null) { // EXCO: Why this test ?
124: continue;
125: }
126: from_start = diff(period.getStart(), date);
127: if (endDate != null) {
128: from_end = Math.abs(diff(period.getEnd(), endDate));
129: }
130: if (from_start < min_from_start
131: || (from_start == min_from_start && from_end < min_from_end)) {
132: min_from_start = from_start;
133: min_from_end = from_end;
134: result = period;
135: }
136: }
137: return result;
138: }
139:
140: static private Period getNearestPeriodForEndDate(
141: Collection periodList, Date date) {
142: Period result = null;
143: long min = -1;
144: Iterator it = periodList.iterator();
145: while (it.hasNext()) {
146: Period period = (Period) it.next();
147: if (min == -1) {
148: min = diff(period.getEnd(), date);
149: result = period;
150: }
151: if (diff(period.getEnd(), date) < min) {
152: min = diff(period.getStart(), date);
153: result = period;
154: }
155: }
156: return result;
157: }
158:
159: /** return all matching periods.*/
160: public List getPeriodsFor(Date date) {
161: ArrayList list = new ArrayList();
162: if (date == null)
163: return list;
164:
165: SortedSet set = m_periods.tailSet(date);
166: Iterator it = set.iterator();
167: while (it.hasNext()) {
168: Period period = (Period) it.next();
169: //System.out.println(m_periods[i].getStart() + " - " + m_periods[i].getEnd());
170: if (period.contains(date)) {
171: list.add(period);
172: }
173: }
174: return list;
175: }
176:
177: public int getSize() {
178: Assert.notNull(m_periods, "Componenet not setup!");
179: return m_periods.size();
180: }
181:
182: public Period[] getAllPeriods() {
183: return (Period[]) m_periods.toArray(Period.PERIOD_ARRAY);
184: }
185:
186: public Object getElementAt(int index) {
187: Assert.notNull(m_periods, "Componenet not setup!");
188: Iterator it = m_periods.iterator();
189: for (int i = 0; it.hasNext(); i++) {
190: Object obj = it.next();
191: if (i == index)
192: return obj;
193: }
194: return null;
195: }
196:
197: }
|