blob: c9e7e8067845886ed0cea6893ed59c4217bd66cd [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. The ASF licenses this file to You
* under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License. For additional information regarding
* copyright in this work, please see the NOTICE file in the top level
* directory of this distribution.
*/
package org.apache.roller.weblogger.ui.core.tags.calendar;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.roller.weblogger.WebloggerException;
import org.apache.roller.weblogger.business.WebloggerFactory;
import org.apache.roller.weblogger.business.WeblogEntryManager;
import org.apache.roller.weblogger.pojos.WeblogEntry;
import org.apache.roller.weblogger.pojos.WeblogEntry.PubStatus;
import org.apache.roller.weblogger.pojos.Weblog;
import org.apache.roller.weblogger.pojos.WeblogEntrySearchCriteria;
import org.apache.roller.weblogger.ui.rendering.util.WeblogPageRequest;
import org.apache.roller.util.DateUtil;
/**
* Calendar model for calendar intended for use on view-weblog page.
*/
public class WeblogCalendarModel implements CalendarModel {
private static Log log = LogFactory.getLog(WeblogCalendarModel.class);
protected Map monthMap;
protected Date day;
protected String cat = null;
protected String pageLink = null;
protected String locale = null;
protected Calendar calendar = null;
protected Weblog weblog = null;
protected Date prevMonth = null;
protected Date nextMonth = null;
protected WeblogPageRequest pageRequest = null;
public WeblogCalendarModel(WeblogPageRequest pRequest, String catArgument) {
this.pageRequest = pRequest;
try {
this.weblog = pageRequest.getWeblog();
if(weblog == null) {
throw new WebloggerException("unable to lookup weblog: "+
pageRequest.getWeblogHandle());
}
pageLink = pageRequest.getWeblogPageName();
day = parseWeblogURLDateString(pageRequest.getWeblogDate(),
weblog.getTimeZoneInstance(), weblog.getLocaleInstance());
locale = pageRequest.getLocale();
// Category method argument overrides category from URL
if (catArgument != null) {
cat = catArgument;
} else if (pageRequest.getWeblogCategoryName() != null) {
cat = pageRequest.getWeblogCategoryName();
}
initDay(day);
} catch (Exception e) {
// some kind of error parsing the request or looking up weblog
log.debug("ERROR: initializing calendar", e);
}
}
protected void initDay(Date month) {
calendar = Calendar.getInstance(
weblog.getTimeZoneInstance(),
weblog.getLocaleInstance());
Calendar cal = (Calendar)calendar.clone();
Date startDate = DateUtil.getStartOfMonth(month,cal);
Date endDate = DateUtil.getEndOfMonth(month,cal);
// Determine previous non-empty month
// Get entries before startDate, using category restriction limit 1
// Use entry's date as previous month
try {
WeblogEntryManager mgr = WebloggerFactory.getWeblogger().getWeblogEntryManager();
WeblogEntrySearchCriteria wesc = new WeblogEntrySearchCriteria();
wesc.setWeblog(weblog);
// since we need an entry.pubTime < startDate, but the method uses endDate
wesc.setEndDate(new Date(startDate.getTime()-1));
wesc.setCatName(cat);
wesc.setStatus(PubStatus.PUBLISHED);
wesc.setSortOrder(WeblogEntrySearchCriteria.SortOrder.DESCENDING);
wesc.setLocale(locale);
wesc.setMaxResults(1);
List prevEntries = mgr.getWeblogEntries(wesc);
if (prevEntries.size() > 0) {
WeblogEntry prevEntry = (WeblogEntry)prevEntries.get(0);
prevMonth = DateUtil.getStartOfMonth(new Date(prevEntry.getPubTime().getTime()),getCalendar());
}
} catch (WebloggerException e) {
log.error("ERROR determining previous non-empty month");
}
// Determine next non-empty month
// Get entries after endDate, using category restriction limit 1
// Use entry's date as next month
try {
WeblogEntryManager mgr = WebloggerFactory.getWeblogger().getWeblogEntryManager();
WeblogEntrySearchCriteria wesc = new WeblogEntrySearchCriteria();
wesc.setWeblog(weblog);
// since we need an entry.pubTime > endDate, but the method uses startDate
wesc.setStartDate(new Date(endDate.getTime()+1));
wesc.setCatName(cat);
wesc.setStatus(PubStatus.PUBLISHED);
wesc.setSortOrder(WeblogEntrySearchCriteria.SortOrder.ASCENDING);
wesc.setLocale(locale);
wesc.setMaxResults(1);
List nextEntries = mgr.getWeblogEntries(wesc);
if (nextEntries.size() > 0) {
WeblogEntry nextEntry = (WeblogEntry)nextEntries.get(0);
nextMonth = DateUtil.getStartOfMonth(new Date(nextEntry.getPubTime().getTime()),getCalendar());
}
} catch (WebloggerException e) {
log.error("ERROR determining next non-empty month");
}
// Fix for ROL-840 Don't include future entries
Date now = new Date();
if (endDate.after(now)) {
endDate = now;
nextMonth = null;
}
loadWeblogEntries(startDate, endDate, cat);
}
protected void loadWeblogEntries(Date startDate, Date endDate, String catName) {
try {
WeblogEntryManager mgr = WebloggerFactory.getWeblogger().getWeblogEntryManager();
WeblogEntrySearchCriteria wesc = new WeblogEntrySearchCriteria();
wesc.setWeblog(weblog);
wesc.setStartDate(startDate);
wesc.setEndDate(endDate);
wesc.setCatName(catName);
wesc.setStatus(PubStatus.PUBLISHED);
wesc.setLocale(locale);
monthMap = mgr.getWeblogEntryStringMap(wesc);
} catch (WebloggerException e) {
log.error(e);
monthMap = new HashMap<Date, String>();
}
}
public void setDay(String month) throws Exception {
SimpleDateFormat fmt = DateUtil.get8charDateFormat();
fmt.setCalendar(getCalendar());
ParsePosition pos = new ParsePosition(0);
initDay( fmt.parse( month, pos ) );
}
public Date getDay() {
return (Date)day.clone();
}
public String getParameterValue(Date day) {
return (String) monthMap.get(day);
}
// convenience method returns 8 char day stamp YYYYMMDD
public static String format8chars(Date date, Calendar cal) {
SimpleDateFormat format = DateUtil.get8charDateFormat();
format.setCalendar(cal);
return DateUtil.format(date,format);
}
// convenience method returns 6 char month stamp YYYYMM
public static String format6chars(Date date, Calendar cal) {
SimpleDateFormat format = DateUtil.get6charDateFormat();
format.setCalendar(cal);
return DateUtil.format(date,format);
}
/**
* Parse data as either 6-char or 8-char format.
*/
public static Date parseWeblogURLDateString(String dateString, TimeZone tz, Locale locale) {
Date ret = new Date();
Calendar cal = Calendar.getInstance(tz,locale);
if (dateString != null
&& dateString.length()==8
&& StringUtils.isNumeric(dateString) ) {
SimpleDateFormat char8DateFormat = DateUtil.get8charDateFormat();
char8DateFormat.setCalendar(cal);
ParsePosition pos = new ParsePosition(0);
ret = char8DateFormat.parse(dateString, pos);
// make sure the requested date is not in the future
// Date is always ms offset from epoch in UTC, by no means of timezone.
Date today = new Date();
if(ret.after(today)) {
ret = today;
}
} else if(dateString != null
&& dateString.length()==6
&& StringUtils.isNumeric(dateString)) {
SimpleDateFormat char6DateFormat = DateUtil.get6charDateFormat();
char6DateFormat.setCalendar(cal);
ParsePosition pos = new ParsePosition(0);
ret = char6DateFormat.parse(dateString, pos);
// make sure the requested date is not in the future
Date today = new Date();
if(ret.after(today)) {
ret = today;
}
}
return ret;
}
/**
* Create URL for use on view-weblog page
* @param day Day for URL or null if no entries on that day
* @param alwaysURL Always return a URL, never return null
* @return URL for day, or null if no weblog entry on that day
*/
public String computeUrl(Date day, boolean monthURL, boolean alwaysURL) {
String url = null;
// get the 8 char YYYYMMDD datestring for day
String dateString = (String) monthMap.get(day);
if (dateString == null && !alwaysURL) {
return null;
}
else if (dateString == null && !monthURL) {
dateString = format8chars(day,getCalendar());
} else if (dateString == null) {
dateString = format6chars(day,getCalendar());
}
try {
if (pageLink == null) {
// create date URL
url = WebloggerFactory.getWeblogger().getUrlStrategy().getWeblogCollectionURL(weblog, locale, cat, dateString, null, -1, false);
} else {
// create page URL
url = WebloggerFactory.getWeblogger().getUrlStrategy().getWeblogPageURL(weblog, locale, pageLink, null, cat, dateString, null, -1, false);
}
} catch (Exception e) {
log.error("ERROR: creating URL",e);
}
return url;
}
public String getContent(Date day) {
return null;
}
public Calendar getCalendar() {
return (Calendar)calendar.clone();
}
public Date getNextMonth() {
return nextMonth;
}
public Date getPrevMonth() {
return prevMonth;
}
public String computeNextMonthUrl() {
return computeUrl(nextMonth, true, true);
}
public String computePrevMonthUrl() {
return computeUrl(prevMonth, true, true);
}
public String computeTodayMonthUrl() {
String url;
if (pageLink == null) {
// create default URL
url = WebloggerFactory.getWeblogger().getUrlStrategy().getWeblogCollectionURL(weblog, locale, cat, null, null, -1, false);
} else {
// create page URL
url = WebloggerFactory.getWeblogger().getUrlStrategy().getWeblogPageURL(weblog, locale, pageLink, null, cat, null, null, -1, false);
}
return url;
}
}