Pull up TimeTrackerStateUsingJodaTime to TimeTrackerState
Now all zoom levels are based on the same superclass FEA: ItEr61S08TimeUnitConfigurablePlanning
This commit is contained in:
parent
0e8a61715f
commit
55e4c8a7c6
8 changed files with 260 additions and 463 deletions
|
|
@ -30,7 +30,7 @@ import org.joda.time.ReadablePeriod;
|
|||
* @author Óscar González Fernández <ogonzalez@igalia.com>
|
||||
* @author Lorenzo Tilve Álvaro <ltilve@igalia.com>
|
||||
*/
|
||||
public class DetailFiveTimeTrackerState extends TimeTrackerStateUsingJodaTime {
|
||||
public class DetailFiveTimeTrackerState extends TimeTrackerState {
|
||||
|
||||
private static final int NUMBER_OF_DAYS_MINIMUM = 50;
|
||||
public static final int FIRST_LEVEL_SIZE = 210;
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ import org.zkoss.ganttz.util.Interval;
|
|||
* @author Óscar González Fernández <ogonzalez@igalia.com>
|
||||
* @author Lorenzo Tilve Álvaro <ltilve@igalia.com>
|
||||
*/
|
||||
public class DetailFourTimeTrackerState extends TimeTrackerStateUsingJodaTime {
|
||||
public class DetailFourTimeTrackerState extends TimeTrackerState {
|
||||
|
||||
private static final int NUMBER_OF_WEEKS_MINIMUM = 40;
|
||||
|
||||
|
|
|
|||
|
|
@ -20,11 +20,12 @@
|
|||
|
||||
package org.zkoss.ganttz.timetracker.zoom;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.zkoss.ganttz.util.Interval;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.joda.time.Months;
|
||||
import org.joda.time.ReadablePeriod;
|
||||
import org.joda.time.Years;
|
||||
|
||||
|
||||
/**
|
||||
* Zoom level with years in the first level and semesters in the second level
|
||||
|
|
@ -33,6 +34,8 @@ import org.zkoss.ganttz.util.Interval;
|
|||
*/
|
||||
public class DetailOneTimeTrackerState extends TimeTrackerState {
|
||||
|
||||
public static final Period MINIMUN_PERIOD = PeriodType.YEARS.amount(4);
|
||||
|
||||
private static final int FIRST_LEVEL_ITEM_SIZE = 200;
|
||||
private static final int SECOND_LEVEL_ITEM_SIZE = 100;
|
||||
|
||||
|
|
@ -45,74 +48,6 @@ public class DetailOneTimeTrackerState extends TimeTrackerState {
|
|||
super(firstLevelModificator, secondLevelModificator);
|
||||
}
|
||||
|
||||
private Collection<DetailItem> buildCollectionDetailsFirstLevel(
|
||||
int initialYear, int endYear) {
|
||||
|
||||
Collection<DetailItem> detailsVector = new Vector<DetailItem>();
|
||||
|
||||
for (int i = initialYear; i <= endYear; i++) {
|
||||
DetailItem d = new DetailItem(FIRST_LEVEL_ITEM_SIZE, String
|
||||
.valueOf(i), new DateTime(i, 1, 1, 0, 0, 0, 0),
|
||||
new DateTime(i, 12, 31, 0, 0, 0, 0));
|
||||
detailsVector.add(d);
|
||||
}
|
||||
|
||||
return detailsVector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates secondary level DetailItems, adding currentDay tag to the
|
||||
* proper interval (Bank holidays function call pending).
|
||||
*/
|
||||
private Collection<DetailItem> buildCollectionDetailsSecondLevel(
|
||||
int initialYear, int endYear) {
|
||||
|
||||
Collection<DetailItem> detailsVector = new Vector<DetailItem>();
|
||||
|
||||
DateTime beginDate = new DateTime(initialYear, 1, 1, 0, 0, 0, 0);
|
||||
DateTime endDate = new DateTime(initialYear, 7, 1, 0, 0, 0, 0);
|
||||
|
||||
for (int i = initialYear; i <= endYear; i++) {
|
||||
|
||||
DetailItem d1 = new DetailItem(SECOND_LEVEL_ITEM_SIZE, "H1",
|
||||
beginDate, endDate);
|
||||
DetailItem d2 = new DetailItem(SECOND_LEVEL_ITEM_SIZE, "H2",
|
||||
endDate, endDate.plusMonths(6));
|
||||
|
||||
detailsVector.add(d1);
|
||||
detailsVector.add(d2);
|
||||
|
||||
beginDate = beginDate.plusYears(1);
|
||||
endDate = endDate.plusYears(1);
|
||||
|
||||
}
|
||||
|
||||
return detailsVector;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Collection<DetailItem> createDetailsForFirstLevel(
|
||||
Interval interval) {
|
||||
int[] pairYears = calculateInitialEndYear(interval.getStart(), interval
|
||||
.getFinish());
|
||||
return buildCollectionDetailsFirstLevel(pairYears[0], pairYears[1]);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Collection<DetailItem> createDetailsForSecondLevel(
|
||||
Interval interval) {
|
||||
int[] pairYears = calculateInitialEndYear(interval.getStart(), interval
|
||||
.getFinish());
|
||||
return buildCollectionDetailsSecondLevel(pairYears[0], pairYears[1]);
|
||||
}
|
||||
|
||||
public Interval getRealIntervalFor(Interval interval) {
|
||||
int[] pairYears = calculateInitialEndYear(interval.getStart(), interval
|
||||
.getFinish());
|
||||
return new Interval(year(pairYears[0]), year(pairYears[1] + 1));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ZoomLevel getZoomLevel() {
|
||||
return ZoomLevel.DETAIL_ONE;
|
||||
|
|
@ -123,4 +58,55 @@ public class DetailOneTimeTrackerState extends TimeTrackerState {
|
|||
return SECOND_LEVEL_ITEM_SIZE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IDetailItemCreator getDetailItemCreatorFirstLevel() {
|
||||
return new IDetailItemCreator() {
|
||||
@Override
|
||||
public DetailItem create(DateTime start) {
|
||||
int year = start.getYear();
|
||||
DateTime end = new LocalDate(year + 1, 1, 1)
|
||||
.toDateTimeAtStartOfDay();
|
||||
return new DetailItem(FIRST_LEVEL_ITEM_SIZE, start.getYear()
|
||||
+ "", start, end);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReadablePeriod getPeriodFirstLevel() {
|
||||
return Years.ONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IDetailItemCreator getDetailItemCreatorSecondLevel() {
|
||||
return new IDetailItemCreator() {
|
||||
|
||||
@Override
|
||||
public DetailItem create(DateTime dateTime) {
|
||||
return new DetailItem(SECOND_LEVEL_ITEM_SIZE,
|
||||
dateTime.getMonthOfYear() == 1 ? "H1" : "H2", dateTime,
|
||||
dateTime.plusMonths(6));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReadablePeriod getPeriodSecondLevel() {
|
||||
return Months.SIX;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LocalDate round(LocalDate date, boolean down) {
|
||||
return doYearRound(date, down);
|
||||
}
|
||||
|
||||
public static LocalDate doYearRound(LocalDate date, boolean down) {
|
||||
return new LocalDate(date.getYear() + (down?0:1), 1, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Period getMinimumPeriod() {
|
||||
return MINIMUN_PERIOD;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ import org.joda.time.ReadablePeriod;
|
|||
* @author Óscar González Fernández <ogonzalez@igalia.com>
|
||||
* @author Lorenzo Tilve Álvaro <ltilve@igalia.com>
|
||||
*/
|
||||
public class DetailSixTimeTrackerState extends TimeTrackerStateUsingJodaTime {
|
||||
public class DetailSixTimeTrackerState extends TimeTrackerState {
|
||||
|
||||
private static final int NUMBER_OF_DAYS_MINIMUM = 50;
|
||||
public static final int FIRST_LEVEL_SIZE = 672;
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ import org.zkoss.util.Locales;
|
|||
* @author Óscar González Fernández <ogonzalez@igalia.com>
|
||||
* @author Lorenzo Tilve Álvaro <ltilve@igalia.com>
|
||||
*/
|
||||
public class DetailThreeTimeTrackerState extends TimeTrackerStateUsingJodaTime {
|
||||
public class DetailThreeTimeTrackerState extends TimeTrackerState {
|
||||
|
||||
private static final int NUMBER_OF_MONTHS_MINIMUM = 20;
|
||||
|
||||
|
|
|
|||
|
|
@ -20,14 +20,11 @@
|
|||
|
||||
package org.zkoss.ganttz.timetracker.zoom;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.zkoss.ganttz.util.Interval;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.joda.time.Months;
|
||||
import org.joda.time.ReadablePeriod;
|
||||
import org.joda.time.Years;
|
||||
|
||||
/**
|
||||
* Zoom level with years in the first level and quarters in the second level
|
||||
|
|
@ -45,142 +42,55 @@ public class DetailTwoTimeTrackerState extends TimeTrackerState {
|
|||
super(firstLevelModificator, secondLevelModificator);
|
||||
}
|
||||
|
||||
public final double daysPerPixel() {
|
||||
@Override
|
||||
protected IDetailItemCreator getDetailItemCreatorFirstLevel() {
|
||||
return new IDetailItemCreator() {
|
||||
@Override
|
||||
public DetailItem create(DateTime dateTime) {
|
||||
return new DetailItem(FIRST_LEVEL_ITEM_SIZE, dateTime.getYear()
|
||||
+ "", dateTime, dateTime);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReadablePeriod getPeriodFirstLevel() {
|
||||
return Years.ONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IDetailItemCreator getDetailItemCreatorSecondLevel() {
|
||||
return new IDetailItemCreator() {
|
||||
@Override
|
||||
public DetailItem create(DateTime dateTime) {
|
||||
int quarterNumber = dateTime.getMonthOfYear() / 3 + 1;
|
||||
String quarterCaption = "Q" + quarterNumber;
|
||||
return new DetailItem(SECOND_LEVEL_ITEM_SIZE, quarterCaption,
|
||||
dateTime, dateTime.plusMonths(3));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReadablePeriod getPeriodSecondLevel() {
|
||||
return Months.THREE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LocalDate round(LocalDate date, boolean down) {
|
||||
return DetailOneTimeTrackerState.doYearRound(date, down);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Period getMinimumPeriod() {
|
||||
return DetailOneTimeTrackerState.MINIMUN_PERIOD;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double daysPerPixel() {
|
||||
return ((double) 365 / FIRST_LEVEL_ITEM_SIZE);
|
||||
}
|
||||
|
||||
public Interval getRealIntervalFor(Interval interval) {
|
||||
int[] pairYears = calculateInitialEndYear(interval.getStart(), interval
|
||||
.getFinish());
|
||||
int startQuarter = calculateInQuarterPeriodDateInYear(interval
|
||||
.getStart(), pairYears[0]);
|
||||
int endQuarter = calculateInQuarterPeriodDateInYear(interval
|
||||
.getFinish(), pairYears[1]);
|
||||
return new Interval(quarterAt(startQuarter - 1, year(pairYears[0])),
|
||||
quarterAt(endQuarter, year(pairYears[1])));
|
||||
}
|
||||
|
||||
private static Date quarterAt(int quarter, Date date) {
|
||||
int year = from(date).get(Calendar.YEAR);
|
||||
Calendar calendar = from(year(year));
|
||||
calendar.add(Calendar.MONTH, 3 * quarter);
|
||||
return calendar.getTime();
|
||||
}
|
||||
|
||||
static Calendar from(Date date) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(date);
|
||||
return calendar;
|
||||
}
|
||||
|
||||
private Collection<DetailItem> buildCollectionDetailsFirstLevel(
|
||||
Date initialDate, Date endDate, int initialYear, int endYear) {
|
||||
|
||||
Collection<DetailItem> detailsVector = new Vector<DetailItem>();
|
||||
|
||||
// Calculate the size of the first detail of the first level
|
||||
int quarter = calculateInQuarterPeriodDateInYear(initialDate,
|
||||
initialYear);
|
||||
detailsVector.add(new DetailItem((4 - (quarter - 1))
|
||||
* FIRST_LEVEL_ITEM_SIZE / 4, String.valueOf(initialYear),
|
||||
new DateTime(initialYear, 1, 1, 0, 0, 0, 0), new DateTime(
|
||||
initialYear, 1, 1, 0, 0, 0, 0)));
|
||||
|
||||
for (int i = (initialYear + 1); i < endYear; i++) {
|
||||
DetailItem d = new DetailItem(FIRST_LEVEL_ITEM_SIZE, String
|
||||
.valueOf(i), new DateTime(i, 1, 1, 0, 0, 0, 0),
|
||||
new DateTime(i, 12, 31, 0, 0, 0, 0));
|
||||
detailsVector.add(d);
|
||||
}
|
||||
|
||||
// Calculate the size of the last detail of the first level
|
||||
int endQuarter = calculateInQuarterPeriodDateInYear(endDate, endYear);
|
||||
detailsVector
|
||||
.add(new DetailItem(endQuarter * FIRST_LEVEL_ITEM_SIZE / 4,
|
||||
String.valueOf(endYear)));
|
||||
|
||||
return detailsVector;
|
||||
|
||||
}
|
||||
|
||||
|
||||
private Collection<DetailItem> buildCollectionDetailsSecondLevel(
|
||||
Date initialDate, Date endDate, int initialYear, int endYear) {
|
||||
|
||||
ArrayList<DetailItem> result = new ArrayList<DetailItem>();
|
||||
|
||||
DateTime tempDate = new DateTime(initialDate);
|
||||
DateTime beginInterval = new DateTime(tempDate.year().get(), tempDate
|
||||
.monthOfYear().get(), 1, 0, 0, 0, 0);
|
||||
|
||||
DateTime endInterval = beginInterval.plusMonths(3);
|
||||
int startDateQuarter = calculateInQuarterPeriodDateInYear(initialDate,
|
||||
initialYear);
|
||||
int quarterEndDate = calculateInQuarterPeriodDateInYear(endDate,endYear);
|
||||
|
||||
for (int j = initialYear; j <= endYear; j++) {
|
||||
final int initialQuarter = (j == initialYear) ? startDateQuarter - 1
|
||||
: 0;
|
||||
final int endQuarter = (j == endYear) ? quarterEndDate : 4;
|
||||
for (int i = initialQuarter; i < endQuarter; i++) {
|
||||
DetailItem quarter = new DetailItem(SECOND_LEVEL_ITEM_SIZE, "Q"
|
||||
+ (i + 1),
|
||||
beginInterval, endInterval);
|
||||
result.add(quarter);
|
||||
beginInterval = beginInterval.plusMonths(3);
|
||||
endInterval = endInterval.plusMonths(3);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param date
|
||||
* @param year
|
||||
* @return a number from 1(quarter until to 1st April) to 4(quarter until
|
||||
* 1st January of the next year) showing the quarter in which the
|
||||
* date is for the year
|
||||
*/
|
||||
private int calculateInQuarterPeriodDateInYear(Date date, int year) {
|
||||
Date[] quarters = createQuartersForYear(year);
|
||||
for (int i = 0; i < quarters.length; i++) {
|
||||
if (date.before(quarters[i])) {
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("date " + date + " is not in year "
|
||||
+ year);
|
||||
}
|
||||
|
||||
private static Date[] createQuartersForYear(int year) {
|
||||
Date yearDate = year(year);
|
||||
Date[] result = new Date[4];
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
result[i] = quarterAt(i + 1, yearDate);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Collection<DetailItem> createDetailsForFirstLevel(
|
||||
Interval interval) {
|
||||
int[] pairYears = calculateInitialEndYear(interval.getStart(), interval
|
||||
.getFinish());
|
||||
return buildCollectionDetailsFirstLevel(interval.getStart(), interval
|
||||
.getFinish(), pairYears[0], pairYears[1]);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Collection<DetailItem> createDetailsForSecondLevel(
|
||||
Interval interval) {
|
||||
int[] pairYears = calculateInitialEndYear(interval.getStart(), interval
|
||||
.getFinish());
|
||||
return buildCollectionDetailsSecondLevel(interval.getStart(), interval
|
||||
.getFinish(), pairYears[0], pairYears[1]);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ZoomLevel getZoomLevel() {
|
||||
return ZoomLevel.DETAIL_TWO;
|
||||
|
|
|
|||
|
|
@ -24,9 +24,16 @@ import java.util.ArrayList;
|
|||
import java.util.Calendar;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.List;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.Days;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.joda.time.Months;
|
||||
import org.joda.time.ReadablePeriod;
|
||||
import org.joda.time.Weeks;
|
||||
import org.joda.time.Years;
|
||||
import org.joda.time.base.BaseSingleFieldPeriod;
|
||||
import org.zkoss.ganttz.util.Interval;
|
||||
|
||||
/**
|
||||
|
|
@ -35,6 +42,13 @@ import org.zkoss.ganttz.util.Interval;
|
|||
*/
|
||||
public abstract class TimeTrackerState {
|
||||
|
||||
public static Date year(int year) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.clear();
|
||||
calendar.set(Calendar.YEAR, year);
|
||||
return calendar.getTime();
|
||||
}
|
||||
|
||||
protected static final long MILLSECONDS_IN_DAY = 1000 * 60 * 60 * 24;
|
||||
|
||||
// Pending to calculate interval dinamically
|
||||
|
|
@ -65,11 +79,13 @@ public abstract class TimeTrackerState {
|
|||
return result;
|
||||
}
|
||||
|
||||
protected abstract Collection<DetailItem> createDetailsForFirstLevel(
|
||||
Interval interval);
|
||||
protected static LocalDate asLocalDate(Date date) {
|
||||
return new LocalDate(date);
|
||||
}
|
||||
|
||||
protected abstract Collection<DetailItem> createDetailsForSecondLevel(
|
||||
Interval interval);
|
||||
public interface IDetailItemCreator {
|
||||
DetailItem create(DateTime dateTime);
|
||||
}
|
||||
|
||||
public Collection<DetailItem> getSecondLevelDetails(Interval interval) {
|
||||
if (getZoomLevel() == ZoomLevel.DETAIL_FIVE) {
|
||||
|
|
@ -99,49 +115,147 @@ public abstract class TimeTrackerState {
|
|||
return result;
|
||||
}
|
||||
|
||||
protected static int[] calculateInitialEndYear(Date initialDate,
|
||||
Date endDate) {
|
||||
public Collection<DetailItem> createDetails(Interval interval,
|
||||
ReadablePeriod period, IDetailItemCreator detailItemCreator) {
|
||||
DateTime current = asLocalDate(interval.getStart())
|
||||
.toDateTimeAtStartOfDay();
|
||||
DateTime end = asLocalDate(interval.getFinish())
|
||||
.toDateTimeAtStartOfDay();
|
||||
List<DetailItem> result = new ArrayList<DetailItem>();
|
||||
while (current.isBefore(end)) {
|
||||
result.add(detailItemCreator.create(current));
|
||||
current = current.plus(period);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int[] pairYears = new int[2];
|
||||
private final Collection<DetailItem> createDetailsForFirstLevel(
|
||||
Interval interval) {
|
||||
return createDetails(getRealIntervalFor(interval),
|
||||
getPeriodFirstLevel(), getDetailItemCreatorFirstLevel());
|
||||
}
|
||||
|
||||
long yearsInBetween = calculateYearsBetween(initialDate, endDate);
|
||||
Calendar cal = new GregorianCalendar();
|
||||
cal.setTime(initialDate);
|
||||
int initialYear = cal.get(Calendar.YEAR);
|
||||
int endYear;
|
||||
private final Collection<DetailItem> createDetailsForSecondLevel(
|
||||
Interval interval) {
|
||||
return createDetails(getRealIntervalFor(interval),
|
||||
getPeriodSecondLevel(), getDetailItemCreatorSecondLevel());
|
||||
}
|
||||
|
||||
if (yearsInBetween >= NUMBER_OF_ITEMS_MINIMUM) {
|
||||
cal.setTime(endDate);
|
||||
endYear = cal.get(Calendar.YEAR);
|
||||
} else {
|
||||
endYear = initialYear + NUMBER_OF_ITEMS_MINIMUM;
|
||||
protected abstract IDetailItemCreator getDetailItemCreatorFirstLevel();
|
||||
|
||||
protected abstract ReadablePeriod getPeriodFirstLevel();
|
||||
|
||||
protected abstract IDetailItemCreator getDetailItemCreatorSecondLevel();
|
||||
|
||||
protected abstract ReadablePeriod getPeriodSecondLevel();
|
||||
|
||||
protected abstract LocalDate round(LocalDate date, boolean down);
|
||||
|
||||
public enum PeriodType {
|
||||
YEARS {
|
||||
@Override
|
||||
public ReadablePeriod toPeriod(int amount) {
|
||||
return Years.years(amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Years differenceBetween(LocalDate start, LocalDate end) {
|
||||
return Years.yearsBetween(start, end);
|
||||
}
|
||||
},
|
||||
MONTHS {
|
||||
@Override
|
||||
public ReadablePeriod toPeriod(int amount) {
|
||||
return Months.months(amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Months differenceBetween(LocalDate start, LocalDate end) {
|
||||
return Months.monthsBetween(start, end);
|
||||
}
|
||||
},
|
||||
WEEKS {
|
||||
@Override
|
||||
public ReadablePeriod toPeriod(int amount) {
|
||||
return Weeks.weeks(amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Weeks differenceBetween(LocalDate start, LocalDate end) {
|
||||
return Weeks.weeksBetween(start, end);
|
||||
}
|
||||
},
|
||||
DAYS {
|
||||
@Override
|
||||
public ReadablePeriod toPeriod(int amount) {
|
||||
return Days.days(amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Days differenceBetween(LocalDate start, LocalDate end) {
|
||||
return Days.daysBetween(start, end);
|
||||
}
|
||||
};
|
||||
|
||||
public abstract ReadablePeriod toPeriod(int amount);
|
||||
|
||||
public abstract BaseSingleFieldPeriod differenceBetween(
|
||||
LocalDate start, LocalDate end);
|
||||
|
||||
public Period amount(int amount) {
|
||||
return new Period(this, amount);
|
||||
}
|
||||
|
||||
pairYears[0] = initialYear;
|
||||
pairYears[1] = endYear;
|
||||
|
||||
return pairYears;
|
||||
}
|
||||
|
||||
protected static long calculateYearsBetween(Date initialDate, Date endDate) {
|
||||
static class Period {
|
||||
|
||||
long milsecondsDiff = endDate.getTime() - initialDate.getTime();
|
||||
private final PeriodType type;
|
||||
|
||||
// To chech later: If you put MILLSECONDS_IN_YEAR the
|
||||
// division is made wrongly.
|
||||
private final int amount;
|
||||
|
||||
long days = milsecondsDiff / MILLSECONDS_IN_DAY;
|
||||
return (days / 365);
|
||||
private Period(PeriodType type, int amount) {
|
||||
this.type = type;
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
ReadablePeriod toPeriod() {
|
||||
return this.type.toPeriod(amount);
|
||||
}
|
||||
|
||||
BaseSingleFieldPeriod asPeriod(Interval interval) {
|
||||
LocalDate start = LocalDate.fromDateFields(interval.getStart());
|
||||
LocalDate end = LocalDate.fromDateFields(interval.getFinish());
|
||||
return type.differenceBetween(start, end);
|
||||
}
|
||||
}
|
||||
|
||||
public static Date year(int year) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.clear();
|
||||
calendar.set(Calendar.YEAR, year);
|
||||
return calendar.getTime();
|
||||
protected abstract Period getMinimumPeriod();
|
||||
|
||||
private Interval calculateIntervalWithMinimum(Interval interval) {
|
||||
Period minimumPeriod = getMinimumPeriod();
|
||||
BaseSingleFieldPeriod intervalAsPeriod = minimumPeriod
|
||||
.asPeriod(interval);
|
||||
if (intervalAsPeriod.compareTo(minimumPeriod.toPeriod()) >= 0) {
|
||||
return interval;
|
||||
}
|
||||
LocalDate newEnd = new LocalDate(interval.getStart())
|
||||
.plus(minimumPeriod.toPeriod());
|
||||
return new Interval(interval.getStart(), newEnd
|
||||
.toDateTimeAtStartOfDay().toDate());
|
||||
}
|
||||
|
||||
public abstract Interval getRealIntervalFor(Interval testInterval);
|
||||
public Interval getRealIntervalFor(Interval testInterval) {
|
||||
return calculateForAtLeastMinimum(calculateIntervalWithMinimum(testInterval));
|
||||
}
|
||||
|
||||
private Interval calculateForAtLeastMinimum(Interval atLeastMinimum) {
|
||||
LocalDate start = round(asLocalDate(atLeastMinimum.getStart()), true);
|
||||
LocalDate finish = round(asLocalDate(atLeastMinimum.getFinish()), false);
|
||||
Interval result = new Interval(start.toDateTimeAtStartOfDay().toDate(),
|
||||
finish.toDateTimeAtStartOfDay().toDate());
|
||||
return result;
|
||||
}
|
||||
|
||||
public abstract double daysPerPixel();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,213 +0,0 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
|
||||
* Desenvolvemento Tecnolóxico de Galicia
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.zkoss.ganttz.timetracker.zoom;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.Days;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.joda.time.Months;
|
||||
import org.joda.time.ReadablePeriod;
|
||||
import org.joda.time.Weeks;
|
||||
import org.joda.time.Years;
|
||||
import org.joda.time.base.BaseSingleFieldPeriod;
|
||||
import org.zkoss.ganttz.util.Interval;
|
||||
|
||||
/**
|
||||
* @author Óscar González Fernández <ogonzalez@igalia.com>
|
||||
*/
|
||||
public abstract class TimeTrackerStateUsingJodaTime extends TimeTrackerState {
|
||||
|
||||
TimeTrackerStateUsingJodaTime(
|
||||
IDetailItemModificator firstLevelModificator,
|
||||
IDetailItemModificator secondLevelModificator) {
|
||||
super(firstLevelModificator, secondLevelModificator);
|
||||
}
|
||||
|
||||
protected static LocalDate asLocalDate(Date date) {
|
||||
return new LocalDate(date);
|
||||
}
|
||||
|
||||
public interface IDetailItemCreator {
|
||||
DetailItem create(DateTime dateTime);
|
||||
}
|
||||
|
||||
public Collection<DetailItem> createDetails(Interval interval,
|
||||
ReadablePeriod period, IDetailItemCreator detailItemCreator) {
|
||||
DateTime current = asLocalDate(interval.getStart())
|
||||
.toDateTimeAtStartOfDay();
|
||||
DateTime end = asLocalDate(interval.getFinish())
|
||||
.toDateTimeAtStartOfDay();
|
||||
List<DetailItem> result = new ArrayList<DetailItem>();
|
||||
while (current.isBefore(end)) {
|
||||
result.add(detailItemCreator.create(current));
|
||||
current = current.plus(period);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Collection<DetailItem> createDetailsForFirstLevel(
|
||||
Interval interval) {
|
||||
return createDetails(getRealIntervalFor(interval),
|
||||
getPeriodFirstLevel(), getDetailItemCreatorFirstLevel());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Collection<DetailItem> createDetailsForSecondLevel(
|
||||
Interval interval) {
|
||||
return createDetails(getRealIntervalFor(interval),
|
||||
getPeriodSecondLevel(), getDetailItemCreatorSecondLevel());
|
||||
}
|
||||
|
||||
protected abstract IDetailItemCreator getDetailItemCreatorFirstLevel();
|
||||
|
||||
protected abstract ReadablePeriod getPeriodFirstLevel();
|
||||
|
||||
protected abstract IDetailItemCreator getDetailItemCreatorSecondLevel();
|
||||
|
||||
protected abstract ReadablePeriod getPeriodSecondLevel();
|
||||
|
||||
protected abstract LocalDate round(LocalDate date, boolean down);
|
||||
|
||||
public enum PeriodType {
|
||||
YEARS {
|
||||
@Override
|
||||
public ReadablePeriod toPeriod(int amount) {
|
||||
return Years.years(amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Years differenceBetween(LocalDate start,
|
||||
LocalDate end) {
|
||||
return Years.yearsBetween(start, end);
|
||||
}
|
||||
},
|
||||
MONTHS {
|
||||
@Override
|
||||
public ReadablePeriod toPeriod(int amount) {
|
||||
return Months.months(amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Months differenceBetween(LocalDate start,
|
||||
LocalDate end) {
|
||||
return Months.monthsBetween(start, end);
|
||||
}
|
||||
},
|
||||
WEEKS {
|
||||
@Override
|
||||
public ReadablePeriod toPeriod(int amount) {
|
||||
return Weeks.weeks(amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Weeks differenceBetween(LocalDate start,
|
||||
LocalDate end) {
|
||||
return Weeks.weeksBetween(start, end);
|
||||
}
|
||||
},
|
||||
DAYS {
|
||||
@Override
|
||||
public ReadablePeriod toPeriod(int amount) {
|
||||
return Days.days(amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Days differenceBetween(LocalDate start,
|
||||
LocalDate end) {
|
||||
return Days.daysBetween(start, end);
|
||||
}
|
||||
};
|
||||
|
||||
public abstract ReadablePeriod toPeriod(int amount);
|
||||
|
||||
public abstract BaseSingleFieldPeriod differenceBetween(LocalDate start,
|
||||
LocalDate end);
|
||||
|
||||
public Period amount(int amount) {
|
||||
return new Period(this, amount);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class Period {
|
||||
|
||||
private final PeriodType type;
|
||||
|
||||
private final int amount;
|
||||
|
||||
private Period(PeriodType type, int amount) {
|
||||
this.type = type;
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
ReadablePeriod toPeriod() {
|
||||
return this.type.toPeriod(amount);
|
||||
}
|
||||
|
||||
BaseSingleFieldPeriod asPeriod(Interval interval) {
|
||||
LocalDate start = LocalDate.fromDateFields(interval.getStart());
|
||||
LocalDate end = LocalDate.fromDateFields(interval.getFinish());
|
||||
return type.differenceBetween(start, end);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract Period getMinimumPeriod();
|
||||
|
||||
private Interval calculateIntervalWithMinimum(Interval interval) {
|
||||
Period minimumPeriod = getMinimumPeriod();
|
||||
BaseSingleFieldPeriod intervalAsPeriod = minimumPeriod
|
||||
.asPeriod(interval);
|
||||
if (intervalAsPeriod
|
||||
.compareTo(minimumPeriod.toPeriod()) >= 0) {
|
||||
return interval;
|
||||
}
|
||||
LocalDate newEnd = new LocalDate(interval.getStart())
|
||||
.plus(minimumPeriod.toPeriod());
|
||||
return new Interval(interval.getStart(), newEnd
|
||||
.toDateTimeAtStartOfDay().toDate());
|
||||
}
|
||||
|
||||
private Days asPeriod(Interval interval) {
|
||||
DateTime start = new DateTime(interval.getStart());
|
||||
DateTime finish = new DateTime(interval.getFinish());
|
||||
return Days.daysBetween(start, finish);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Interval getRealIntervalFor(Interval testInterval) {
|
||||
return calculateForAtLeastMinimum(calculateIntervalWithMinimum(testInterval));
|
||||
}
|
||||
|
||||
private Interval calculateForAtLeastMinimum(Interval atLeastMinimum) {
|
||||
LocalDate start = round(asLocalDate(atLeastMinimum.getStart()), true);
|
||||
LocalDate finish = round(asLocalDate(atLeastMinimum.getFinish()), false);
|
||||
Interval result = new Interval(start.toDateTimeAtStartOfDay().toDate(),
|
||||
finish
|
||||
.toDateTimeAtStartOfDay().toDate());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue