/**
* AnalyzerBeans
* Copyright (C) 2014 Neopost - Customer Information Management
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* 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 Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.eobjects.analyzer.beans.transform;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import org.eobjects.analyzer.beans.api.Categorized;
import org.eobjects.analyzer.beans.api.Configured;
import org.eobjects.analyzer.beans.api.Description;
import org.eobjects.analyzer.beans.api.Initialize;
import org.eobjects.analyzer.beans.api.OutputColumns;
import org.eobjects.analyzer.beans.api.Transformer;
import org.eobjects.analyzer.beans.api.TransformerBean;
import org.eobjects.analyzer.beans.categories.DateAndTimeCategory;
import org.eobjects.analyzer.data.InputColumn;
import org.eobjects.analyzer.data.InputRow;
@TransformerBean("Extract date part")
@Description("Extract the parts of a date (year, month, day etc.)")
@Categorized({ DateAndTimeCategory.class })
public class DatePartTransformer implements Transformer<Number> {
public static enum WeekDay {
MONDAY(Calendar.MONDAY), TUESDAY(Calendar.TUESDAY), WEDNESDAY(Calendar.WEDNESDAY), THURSDAY(Calendar.THURSDAY), FRIDAY(
Calendar.FRIDAY), SATURDAY(Calendar.SATURDAY), SUNDAY(Calendar.SUNDAY);
private final int _calendarInt;
private WeekDay(int calendarInt) {
_calendarInt = calendarInt;
}
public int getCalendarInt() {
return _calendarInt;
}
public static WeekDay get(int firstDayOfWeek) {
for (WeekDay weekDay : values()) {
if (firstDayOfWeek == weekDay.getCalendarInt()) {
return weekDay;
}
}
return null;
}
public WeekDay next() {
if (this == SUNDAY) {
return MONDAY;
}
return values()[ordinal() + 1];
}
}
@Configured(order = 1)
InputColumn<Date> column;
@Configured(order = 2)
boolean year = true;
@Configured(order = 3)
boolean month = true;
@Configured(order = 4)
boolean dayOfMonth = true;
@Configured(order = 5)
boolean hour = false;
@Configured(order = 6)
boolean minute = false;
@Configured(order = 7)
boolean second = false;
@Configured(order = 8)
boolean dayOfWeek = false;
@Configured(order = 9)
boolean weekNumber = false;
@Configured(order = 10)
int minimalDaysInFirstWeek = Calendar.getInstance().getMinimalDaysInFirstWeek();
@Configured(order = 11)
WeekDay firstDayOfWeek = WeekDay.get(Calendar.getInstance().getFirstDayOfWeek());
private ArrayList<WeekDay> _indexedWeekDays;
@Initialize
public void init() {
// build indexed week days for reuse in transformation
_indexedWeekDays = new ArrayList<WeekDay>(7);
WeekDay nextWeekDay = firstDayOfWeek;
for (int i = 0; i < 7; i++) {
_indexedWeekDays.add(nextWeekDay);
nextWeekDay = nextWeekDay.next();
}
}
@Override
public OutputColumns getOutputColumns() {
final List<String> columnNames = new ArrayList<String>();
final String columnName = column.getName();
if (year) {
columnNames.add(columnName + " (year)");
}
if (month) {
columnNames.add(columnName + " (month)");
}
if (dayOfMonth) {
columnNames.add(columnName + " (day of month)");
}
if (hour) {
columnNames.add(columnName + " (hour)");
}
if (minute) {
columnNames.add(columnName + " (minute)");
}
if (second) {
columnNames.add(columnName + " (second)");
}
if (dayOfWeek) {
columnNames.add(columnName + " (day of week)");
}
if (weekNumber) {
columnNames.add(columnName + " (week number)");
}
if (columnNames.isEmpty()) {
columnNames.add(columnName + " (year)");
}
return new OutputColumns(columnNames.toArray(new String[columnNames.size()]));
}
@Override
public Number[] transform(InputRow inputRow) {
final Date value = inputRow.getValue(column);
return transform(value);
}
public Number[] transform(Date date) {
final Calendar cal;
if (date == null) {
cal = null;
} else {
cal = Calendar.getInstance();
cal.setFirstDayOfWeek(firstDayOfWeek.getCalendarInt());
cal.setMinimalDaysInFirstWeek(minimalDaysInFirstWeek);
cal.setTime(date);
}
final List<Number> result = new ArrayList<Number>();
if (year) {
result.add(getYear(cal));
}
if (month) {
result.add(getMonth(cal));
}
if (dayOfMonth) {
result.add(getDayOfMonth(cal));
}
if (hour) {
result.add(getHour(cal));
}
if (minute) {
result.add(getMinute(cal));
}
if (second) {
result.add(getSecond(cal));
}
if (dayOfWeek) {
result.add(getDayOfWeek(cal));
}
if (weekNumber) {
result.add(getWeekNumber(cal));
}
if (result.isEmpty()) {
result.add(getYear(cal));
}
return result.toArray(new Number[result.size()]);
}
private Number getWeekNumber(Calendar cal) {
if (cal == null) {
return null;
}
return cal.get(Calendar.WEEK_OF_YEAR);
}
private Number getDayOfWeek(Calendar cal) {
if (cal == null) {
return null;
}
WeekDay weekDay = WeekDay.get(cal.get(Calendar.DAY_OF_WEEK));
return _indexedWeekDays.indexOf(weekDay) + 1;
}
private Number getSecond(Calendar cal) {
if (cal == null) {
return null;
}
return cal.get(Calendar.SECOND);
}
private Number getMinute(Calendar cal) {
if (cal == null) {
return null;
}
return cal.get(Calendar.MINUTE);
}
private Number getHour(Calendar cal) {
if (cal == null) {
return null;
}
return cal.get(Calendar.HOUR_OF_DAY);
}
private Number getDayOfMonth(Calendar cal) {
if (cal == null) {
return null;
}
return cal.get(Calendar.DAY_OF_MONTH);
}
private Number getMonth(Calendar cal) {
if (cal == null) {
return null;
}
// add 1 to the month, to make it 1-based (January = 1)
return cal.get(Calendar.MONTH) + 1;
}
private Number getYear(Calendar cal) {
if (cal == null) {
return null;
}
return cal.get(Calendar.YEAR);
}
}