if (sortedRows == null || sortedRows.isEmpty()) {
return results;
}
// Get the lower & upper limits.
SortedList sortedValues = new SortedList(values, sortedRows);
Date minDate = (Date) sortedValues.get(0);
Date maxDate = (Date) sortedValues.get(sortedValues.size()-1);
// If min/max are equals then create a single interval.
if (minDate.compareTo(maxDate) == 0) {
IntervalDateRange interval = new IntervalDateRange(DAY, minDate, maxDate);
for (int row = 0; row < sortedValues.size(); row++) interval.rows.add(row);
results.add(interval);
return results;
}
// Calculate the interval type used according to the constraints set.
int maxIntervals = columnGroup.getMaxIntervals();
if (maxIntervals < 1) maxIntervals = 15;
DateIntervalType intervalType = YEAR;
long millis = (maxDate.getTime() - minDate.getTime());
for (DateIntervalType type : values()) {
long nintervals = millis / getDurationInMillis(type);
if (nintervals < maxIntervals) {
intervalType = type;
break;
}
}
// Ensure the interval mode obtained is always greater or equals than the preferred interval size.
DateIntervalType intervalSize = null;
if (!StringUtils.isBlank(columnGroup.getIntervalSize())) {
intervalSize = getByName(columnGroup.getIntervalSize());
}
if (intervalSize != null && compare(intervalType, intervalSize) == -1) {
intervalType = intervalSize;
}
// Adjust the minDate according to the interval type.
Calendar gc = GregorianCalendar.getInstance();
gc.setLenient(false);
gc.setTime(minDate);
if (YEAR.equals(intervalType)) {
gc.set(Calendar.MONTH, 0);
gc.set(Calendar.DAY_OF_MONTH, 1);
gc.set(Calendar.HOUR, 0);
gc.set(Calendar.MINUTE, 0);
gc.set(Calendar.SECOND, 0);
gc.set(Calendar.MILLISECOND, 0);
}
if (QUARTER.equals(intervalType)) {
int currentMonth = gc.get(Calendar.MONTH);
int firstMonthYear = columnGroup.getFirstMonthOfYear().getIndex();
int rest = Quarter.getPositionInQuarter(firstMonthYear, currentMonth);
gc.add(Calendar.MONTH, rest * -1);
gc.set(Calendar.DAY_OF_MONTH, 1);
gc.set(Calendar.HOUR, 0);
gc.set(Calendar.MINUTE, 0);
gc.set(Calendar.SECOND, 0);
gc.set(Calendar.MILLISECOND, 0);
}
if (MONTH.equals(intervalType)) {
gc.set(Calendar.DAY_OF_MONTH, 1);
gc.set(Calendar.HOUR, 0);
gc.set(Calendar.MINUTE, 0);
gc.set(Calendar.SECOND, 0);
gc.set(Calendar.MILLISECOND, 0);
}
if (DAY.equals(intervalType) || DAY_OF_WEEK.equals(intervalType)) {
gc.set(Calendar.HOUR, 0);
gc.set(Calendar.MINUTE, 0);
gc.set(Calendar.SECOND, 0);
gc.set(Calendar.MILLISECOND, 0);
}
if (HOUR.equals(intervalType)) {
gc.set(Calendar.MINUTE, 0);
gc.set(Calendar.SECOND, 0);
gc.set(Calendar.MILLISECOND, 0);
}
if (MINUTE.equals(intervalType)) {
gc.set(Calendar.SECOND, 0);
gc.set(Calendar.MILLISECOND, 0);
}
if (SECOND.equals(intervalType)) {
gc.set(Calendar.MILLISECOND, 0);
}
// Create the intervals according to the min/max dates.
int index = 0;
while (gc.getTime().compareTo(maxDate) <= 0) {
Date intervalMinDate = gc.getTime();
// Go to the next interval
if (MILLENIUM.equals(intervalType)) {
gc.add(Calendar.YEAR, 1000);
}
if (CENTURY.equals(intervalType)) {
gc.add(Calendar.YEAR, 100);
}
if (DECADE.equals(intervalType)) {
gc.add(Calendar.YEAR, 10);
}
if (YEAR.equals(intervalType)) {
gc.add(Calendar.YEAR, 1);
}
if (QUARTER.equals(intervalType)) {
gc.add(Calendar.MONTH, 3);
}
if (MONTH.equals(intervalType)) {
gc.add(Calendar.MONTH, 1);
}
if (WEEK.equals(intervalType)) {
gc.add(Calendar.DAY_OF_MONTH, 7);
}
if (DAY.equals(intervalType) || DAY_OF_WEEK.equals(intervalType)) {
gc.add(Calendar.DAY_OF_MONTH, 1);
}
if (HOUR.equals(intervalType)) {
gc.add(Calendar.HOUR_OF_DAY, 1);
}
if (MINUTE.equals(intervalType)) {
gc.add(Calendar.MINUTE, 1);
}
if (SECOND.equals(intervalType)) {
gc.add(Calendar.SECOND, 1);
}
// Create the interval.
Date intervalMaxDate = gc.getTime();
IntervalDateRange interval = new IntervalDateRange(intervalType, intervalMinDate, intervalMaxDate);
results.add(interval);
// Add the target rows to the interval.
boolean stop = false;
while (!stop) {
if (index >= sortedValues.size()) {
stop = true;
} else {
Date dateValue = (Date) sortedValues.get(index);
Integer row = sortedRows.get(index);
if (dateValue.before(intervalMaxDate)){
interval.rows.add(row);
index++;
} else {