net.sf.jasperreports.types.date.DateRangeBuilder Maven / Gradle / Ivy
/*
* JasperReports - Free Java Reporting Library.
* Copyright (C) 2001 - 2014 TIBCO Software Inc. All rights reserved.
* http://www.jaspersoft.com
*
* Unless you have purchased a commercial license agreement from Jaspersoft,
* the following license terms apply:
*
* This program is part of JasperReports.
*
* JasperReports 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.
*
* JasperReports 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 JasperReports. If not, see .
*/
package net.sf.jasperreports.types.date;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
/**
* Builder which allows to build proper instance of {@link net.sf.jasperreports.types.date.DateRange}
* Usage example:
*
* DateRange range = new DateRangeBuilder("DAY").set(TimeZone.getTimeZone("GMT")).setValueClass(Timestamp.class).toDateRange()
*
*
* @author Sergey Prilukin
*/
public class DateRangeBuilder
{
private Date dateValue;
private String expression;
private String datePattern;
private Class valueClass;
private TimeZone timeZone;
private Integer weekStartDay;
/**
* Constructor which allows to create DateRange instance from passed date instance.
*
* No additional configuration via set
methods is necessary
* @param dateValue date instance to create DateRange instance
*/
public DateRangeBuilder(Date dateValue) {
this.dateValue = dateValue;
}
/**
* Constructor which allows to create DateRange instance from passed string expression.
*
* It is usually necessary to pass additional configuration through set
methods
* @param expression string expression which will be parsed in order to construct instance of DateRange
*/
public DateRangeBuilder(String expression) {
this.expression = expression;
}
/**
* Configuration method which sets date pattern which will be used to parse expression
*
* NOTE: this method only will take effect if expression is in fact formatted date like "1970-01-01".
*
* @param datePattern date pattern which will be used to parse date
* @return this instance of DateRangeBuilder
*
* @see java.text.SimpleDateFormat
*/
public DateRangeBuilder set(String datePattern) {
this.datePattern = datePattern;
return this;
}
/**
*
* Configuration method which sets value class,
* to indicate desired class of DateRange.getStart and DateRange.getEnd methods.
*
*
* NOTE: this method will not take effect if {@link #DateRangeBuilder(java.util.Date)} constructor was used.
*
*
* @param valueClass class instance of which will be returned by DateRange.getStart and DateRange.getEnd methods
* @return this instance of DateRangeBuilder
*/
public DateRangeBuilder set(Class valueClass) {
this.valueClass = valueClass;
return this;
}
/**
*
* Configuration method which sets desired time zone which will be used to calculate DateRange.getStart and DateRange.getEnd.
*
*
* NOTE: this method will not take effect if {@link #DateRangeBuilder(java.util.Date)} constructor was used.
*
*
* @param timeZone time zone which will be used to calculate DateRange.getStart and DateRange.getStart.
* @return this instance of DateRangeBuilder
*/
public DateRangeBuilder set(TimeZone timeZone) {
this.timeZone = timeZone;
return this;
}
/**
*
* Configuration method which set start of a week
* which will be used during DateRange.getStart and DateRange.getEnd calculations.
*
*
* Should be one of:
* {@link java.util.Calendar#SUNDAY}, {@link java.util.Calendar#MONDAY}
*
*
* NOTE: this method only will take effect if expression is in fact date range expression like "WEEK".
*
* @param weekStartDay week start day to calculate DateRange.getStart and DateRange.getEnd for expressions like "WEEK"
* @return this instance of DateRangeBuilder
*/
public DateRangeBuilder set(Integer weekStartDay) {
this.weekStartDay = weekStartDay;
return this;
}
/**
*
* Configuration method which set start of a week
* which will be used during DateRange.getStart and DateRange.getEnd calculations
* from passed locale instance
*
*
* NOTE: This method and {@link #set(Integer)} will overwrite each other
* so configuration which was set later will be used.
*
*
* NOTE: this method only will take effect if expression is in fact date range expression like "WEEK".
*
* @param locale locale to calculate DateRange.getStart and DateRange.getEnd for expressions like "WEEK"
* @return this instance of DateRangeBuilder
*/
public DateRangeBuilder set(Locale locale) {
Calendar cal = Calendar.getInstance(locale);
this.weekStartDay = cal.getFirstDayOfWeek();
return this;
}
/**
* Returns instance of {@link DateRange} based on which configuration methods was called
* @return instance of {@link DateRange}
* @throws InvalidDateRangeExpressionException if could not instantiate {@code DateRange} using passed expression
*/
public DateRange toDateRange() throws InvalidDateRangeExpressionException {
//If dateValue was sat we have only two possibilities - FixedDate or FixedTimestamp
if (dateValue != null) {
if (valueClass == null) {
if (Timestamp.class.equals(dateValue.getClass())) {
return new FixedTimestamp((Timestamp)dateValue);
} else {
return new FixedDate(dateValue);
}
} else if (Timestamp.class.equals(valueClass)) {
return new FixedTimestamp(new Timestamp(dateValue.getTime()));
} else {
return new FixedDate(dateValue);
}
}
//Try to get instance using FixedDate firstly and RelativeDateRange if first attempt failed
if (valueClass != null) {
if (Timestamp.class.equals(valueClass)) {
try {
return new FixedTimestamp(expression, timeZone, datePattern);
} catch (Exception e) {
return new RelativeTimestampRange(expression, timeZone, weekStartDay);
}
} else {
try {
return new FixedDate(expression, timeZone, datePattern);
} catch (Exception e) {
return new RelativeDateRange(expression, timeZone, weekStartDay);
}
}
}
//Ok need to use heuristic methods below
if (datePattern != null) {
try {
if (isLikeTimestampPattern(datePattern)) {
return new FixedTimestamp(expression, timeZone, datePattern);
} else {
return new FixedDate(expression, timeZone, datePattern);
}
} catch (Exception e) {/*do nothing*/}
}
//Worst case scenario: need to try one by one
try {
return new FixedTimestamp(expression, timeZone, datePattern);
} catch (Exception e) {/*do nothing*/}
try {
return new FixedDate(expression, timeZone, datePattern);
} catch (Exception e) {/*do nothing*/}
//Last resort
return new RelativeDateRange(expression, timeZone, weekStartDay);
}
private boolean isLikeTimestampPattern(String pattern) {
return pattern.matches(".*[hHmsS]+.*");
}
}