/*
* Copyright 2000-2013 Enonic AS
* http://www.enonic.com/license
*/
package com.enonic.cms.core.portal.datasource.handler.util;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import org.jdom.Document;
import org.jdom.Element;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.enonic.cms.core.portal.datasource.handler.DataSourceRequest;
import com.enonic.cms.core.portal.datasource.handler.base.ParamsDataSourceHandler;
import com.enonic.cms.core.time.TimeService;
@Component("ds.GetCalendarHandler")
public final class GetCalendarHandler
extends ParamsDataSourceHandler<GetCalendarParams>
{
private TimeService timeService;
public GetCalendarHandler()
{
super( "getCalendar", GetCalendarParams.class );
}
@Override
protected Document handle( final DataSourceRequest req, final GetCalendarParams params )
throws Exception
{
final DateTime now = this.timeService.getNowAsDateTime();
if ( params.year == null )
{
params.year = now.getYear();
}
if ( params.month == null )
{
params.month = now.getMonthOfYear();
}
final Locale locale = new Locale( params.language, params.country );
return getCalendar( now.getMillis(), params.relative, params.year, params.month, params.count, params.includeWeeks,
params.includeDays, locale );
}
@Autowired
public void setTimeService( final TimeService timeService )
{
this.timeService = timeService;
}
public Document getCalendar( final long now, boolean relative, int year, int month, int count, boolean includeWeeks,
boolean includeDays, final Locale locale )
{
Element root = new org.jdom.Element( "calendar" );
Document doc = new org.jdom.Document( root );
// set current date
SimpleDateFormat dateFormat = new SimpleDateFormat( "yyyy-MM-dd", locale );
root.setAttribute( "currentdate", dateFormat.format( new Date( now ) ) );
SimpleDateFormat dayName = new SimpleDateFormat( "EEEE", locale );
SimpleDateFormat shortDayName = new SimpleDateFormat( "EE", locale );
SimpleDateFormat monthName = new SimpleDateFormat( "MMMM", locale );
SimpleDateFormat shortMonthName = new SimpleDateFormat( "MMM", locale );
// return calendar data relative to the current date
Calendar calendar = Calendar.getInstance( locale );
calendar.setTimeInMillis( now );
// Setting the DAY_OF_MONTH to 1 is necessary to avoid month problems on the 31st of a month. For instance:
// The month is changed to November, on October 31st. There is no November 31st, so the internal date will be December 1st.
calendar.set( Calendar.DAY_OF_MONTH, 1 );
if ( relative )
{
if ( year != 0 )
{
calendar.add( Calendar.YEAR, year );
}
if ( month != 0 )
{
calendar.add( Calendar.MONTH, month );
}
}
else
{
calendar.set( Calendar.YEAR, year );
if ( month > 1 )
{
calendar.set( Calendar.MONTH, month - 1 );
}
else
{
calendar.set( Calendar.MONTH, 0 );
}
}
int currentMonth = calendar.get( Calendar.MONTH );
int currentDay = calendar.get( Calendar.DAY_OF_YEAR );
int currentYear = calendar.get( Calendar.YEAR );
Element yearElement = new Element( "year" );
root.addContent( yearElement );
yearElement.setAttribute( "number", String.valueOf( currentYear ) );
// set enddate
calendar.set( Calendar.MONTH, calendar.getActualMaximum( Calendar.MONTH ) );
calendar.set( Calendar.DAY_OF_MONTH, calendar.getActualMaximum( Calendar.DAY_OF_MONTH ) );
yearElement.setAttribute( "enddate", dateFormat.format( calendar.getTime() ) );
// set startdate
calendar.set( Calendar.MONTH, calendar.getActualMinimum( Calendar.MONTH ) );
calendar.set( Calendar.DAY_OF_MONTH, calendar.getActualMinimum( Calendar.DAY_OF_MONTH ) );
yearElement.setAttribute( "startdate", dateFormat.format( calendar.getTime() ) );
// reset date
calendar.set( Calendar.MONTH, currentMonth );
calendar.set( Calendar.DAY_OF_YEAR, currentDay );
for ( int i = 0; i < count; ++i )
{
if ( calendar.get( Calendar.YEAR ) != currentYear )
{
currentYear = calendar.get( Calendar.YEAR );
yearElement = new Element( "year" );
root.addContent( yearElement );
yearElement.setAttribute( "number", String.valueOf( currentYear ) );
// set enddate
calendar.set( Calendar.MONTH, calendar.getActualMaximum( Calendar.MONTH ) );
calendar.set( Calendar.DAY_OF_MONTH, calendar.getActualMaximum( Calendar.DAY_OF_MONTH ) );
yearElement.setAttribute( "enddate", dateFormat.format( calendar.getTime() ) );
// set startdate
calendar.set( Calendar.MONTH, calendar.getActualMinimum( Calendar.MONTH ) );
calendar.set( Calendar.DAY_OF_MONTH, calendar.getActualMinimum( Calendar.DAY_OF_MONTH ) );
yearElement.setAttribute( "startdate", dateFormat.format( calendar.getTime() ) );
}
Element monthElement = new Element( "month" );
yearElement.addContent( monthElement );
monthElement.setAttribute( "name", monthName.format( calendar.getTime() ) );
monthElement.setAttribute( "shortname", shortMonthName.format( calendar.getTime() ) );
monthElement.setAttribute( "number", String.valueOf( calendar.get( Calendar.MONTH ) + 1 ) );
// set enddate
calendar.set( Calendar.DAY_OF_MONTH, calendar.getActualMaximum( Calendar.DAY_OF_MONTH ) );
monthElement.setAttribute( "enddate", dateFormat.format( calendar.getTime() ) );
// set startdate
calendar.set( Calendar.DAY_OF_MONTH, calendar.getActualMinimum( Calendar.DAY_OF_MONTH ) );
monthElement.setAttribute( "startdate", dateFormat.format( calendar.getTime() ) );
// weeks
Calendar weekCal = (Calendar) calendar.clone();
if ( includeWeeks || includeDays )
{
weekCal.set( Calendar.DAY_OF_MONTH, weekCal.getActualMinimum( Calendar.DAY_OF_MONTH ) );
int thisMonth = weekCal.get( Calendar.MONTH );
Element dayParentElement = monthElement;
int j = 0;
while ( weekCal.get( Calendar.MONTH ) == thisMonth && weekCal.get( Calendar.YEAR ) == currentYear )
{
Element weekElement = null;
// set startdate
if ( j > 0 )
{
weekCal.set( Calendar.DAY_OF_WEEK, weekCal.getFirstDayOfWeek() );
}
if ( includeWeeks )
{
weekElement = new Element( "week" );
monthElement.addContent( weekElement );
weekElement.setAttribute( "number", String.valueOf( weekCal.get( Calendar.WEEK_OF_YEAR ) ) );
weekElement.setAttribute( "startdate", dateFormat.format( weekCal.getTime() ) );
dayParentElement = weekElement;
}
int thisWeek = weekCal.get( Calendar.WEEK_OF_MONTH );
// days
if ( includeDays )
{
while ( weekCal.get( Calendar.WEEK_OF_MONTH ) == thisWeek && weekCal.get( Calendar.MONTH ) == thisMonth &&
weekCal.get( Calendar.YEAR ) == currentYear )
{
Element dayElement = new Element( "day" );
dayParentElement.addContent( dayElement );
dayElement.setAttribute( "number", String.valueOf( weekCal.get( Calendar.DAY_OF_MONTH ) ) );
dayElement.setAttribute( "date", dateFormat.format( weekCal.getTime() ) );
dayElement.setAttribute( "name", dayName.format( weekCal.getTime() ) );
dayElement.setAttribute( "shortname", shortDayName.format( weekCal.getTime() ) );
int day = weekCal.get( Calendar.DAY_OF_WEEK );
day = day - 1;
if ( day == 0 )
{
day = 7;
}
String id = String.valueOf( day );
dayElement.setAttribute( "id", id );
weekCal.add( Calendar.DAY_OF_MONTH, 1 );
}
weekCal.add( Calendar.DAY_OF_MONTH, -1 );
}
// set enddate
if ( !includeDays )
{
while ( weekCal.get( Calendar.WEEK_OF_MONTH ) < ( thisWeek + 1 ) &&
weekCal.get( Calendar.MONTH ) < ( thisMonth + 1 ) && weekCal.get( Calendar.YEAR ) < ( currentYear + 1 ) )
{
weekCal.add( Calendar.DAY_OF_MONTH, 1 );
}
weekCal.add( Calendar.DAY_OF_MONTH, -1 );
}
if ( includeWeeks )
{
weekElement.setAttribute( "enddate", dateFormat.format( weekCal.getTime() ) );
}
// increment week
weekCal.add( Calendar.DAY_OF_MONTH, 1 );
++j;
}
} // if (includeWeeks || includeDays)
// increment month
calendar.add( Calendar.MONTH, 1 );
}
return doc;
}
}