/* * File : $Source: /alkacon/cvs/alkacon/com.alkacon.opencms.calendar/src/com/alkacon/opencms/calendar/CmsSerialDateContentBean.java,v $ * Date : $Date: 2009/02/05 09:49:31 $ * Version: $Revision: 1.2 $ * * This file is part of the Alkacon OpenCms Add-On Module Package * * Copyright (c) 2008 Alkacon Software GmbH (http://www.alkacon.com) * * The Alkacon OpenCms Add-On Module Package is free software: * you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The Alkacon OpenCms Add-On Module Package 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with the Alkacon OpenCms Add-On Module Package. * If not, see http://www.gnu.org/licenses/. * * For further information about Alkacon Software GmbH, please see the * company website: http://www.alkacon.com. * * For further information about OpenCms, please see the * project website: http://www.opencms.org. */ package com.alkacon.opencms.calendar; import org.opencms.file.CmsFile; import org.opencms.file.CmsObject; import org.opencms.file.CmsProperty; import org.opencms.file.CmsPropertyDefinition; import org.opencms.file.CmsResource; import org.opencms.jsp.CmsJspActionElement; import org.opencms.main.CmsException; import org.opencms.main.OpenCms; import org.opencms.util.CmsStringUtil; import org.opencms.xml.content.CmsXmlContent; import org.opencms.xml.content.CmsXmlContentFactory; import java.util.Calendar; import java.util.Collections; import java.util.Date; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.jsp.PageContext; /** * Provides methods to generate the detail page of the serial date, depending on the passed request parameter value * for the start date.<p> * * @author Andreas Zahner */ public class CmsSerialDateContentBean extends CmsJspActionElement implements I_CmsCalendarSerialDateContent { /** Node name for the "Location" element. */ public static final String NODE_LOCATION = "Location"; /** Node name for the "Showtime" element. */ public static final String NODE_SHOWTIME = "Showtime"; /** Node name for the "Teaser" element. */ public static final String NODE_TEASER = "Teaser"; /** Node name for the "Text" element. */ public static final String NODE_TEXT = "Text"; /** Node name for the "Title" element. */ public static final String NODE_TITLE = "Title"; /** The calendar start date parameter value. */ private String m_calendarStartParam; /** The XML content to get the values from. */ private CmsXmlContent m_content; /** The name of the detail file to render. */ private String m_detailFile; /** The serial date entry. */ private CmsCalendarEntryDateSerial m_serialDateEntry; /** The xpath prefix depending on the serial date start date and if a change is defined for that date. */ private String m_xpathPrefix; /** * Empty constructor, needed for every Java bean.<p> */ public CmsSerialDateContentBean() { super(); } /** * Constructor, with parameters. * * @param context the JSP page context object * @param req the JSP request * @param res the JSP response */ public CmsSerialDateContentBean(PageContext context, HttpServletRequest req, HttpServletResponse res) { super(context, req, res); } /** * Returns the name of the detail file to render.<p> * * @return the name of the detail file to render */ public String getDetailFile() { return m_detailFile; } /** * Returns the end date of the serial date to show, depending on the start date.<p> * * @return the end date of the serial date to show */ public Date getEndDate() { Date result = new Date(); CmsCalendarEntryDateSerial serialDate = getSerialDate(); if (serialDate != null) { Calendar startDate = new GregorianCalendar(getRequestContext().getLocale()); String calDatParam = getCalendarStartParam(); if (CmsStringUtil.isNotEmpty(calDatParam)) { // calculate matching end date from given start date startDate.setTimeInMillis(Long.parseLong(calDatParam)); // important: get duration before setting start date, otherwise it will be reset int duration = serialDate.getDuration(); serialDate.setStartDate(startDate, true); serialDate.setStartDate(startDate); Calendar endDate = (GregorianCalendar)startDate.clone(); endDate.add(Calendar.DATE, duration); long endTime = serialDate.getEndTime(); endDate.set(Calendar.HOUR_OF_DAY, 0); endDate.set(Calendar.MINUTE, 0); endDate.set(Calendar.SECOND, 0); endDate.add(Calendar.MILLISECOND, (int)endTime); serialDate.setEndDate(endDate); } result = new Date(serialDate.getEndDate().getTimeInMillis()); } getJspContext().setAttribute("enddate", result); return result; } /** * Returns the serial entry for the calendar generation of the passed resource.<p> * * @param cms the current users context * @param resource the resource to generate the serial entry from * @return the serial entry */ public CmsCalendarEntry getSerialEntryForCalendar(CmsObject cms, CmsResource resource) { // first create the entry data CmsCalendarEntryData entryData = new CmsCalendarEntryData(); Map values = new HashMap(); try { String title = cms.readPropertyObject(resource, CmsPropertyDefinition.PROPERTY_TITLE, false).getValue(""); String showTimeStr = cms.readPropertyObject( resource, I_CmsCalendarEntryData.PROPERTY_CALENDAR_SHOWTIME, false).getValue(CmsStringUtil.TRUE); String type = OpenCms.getResourceManager().getResourceType(resource.getTypeId()).getTypeName(); entryData.setTitle(title); entryData.setShowTime(Boolean.valueOf(showTimeStr).booleanValue()); entryData.setType(type); entryData.setDetailUri(cms.getRequestContext().getSitePath(resource)); entryData.setDescription(cms.readPropertyObject(resource, CmsPropertyDefinition.PROPERTY_DESCRIPTION, false).getValue( "")); // read serial date property value values = cms.readPropertyObject(resource, CmsCalendarDisplay.PROPERTY_CALENDAR_STARTDATE, false).getValueMap( values); } catch (CmsException e) { // failed to read a property, no serial entry can be created, return null return null; } Locale locale = cms.getRequestContext().getLocale(); // second create the serial date CmsCalendarEntryDateSerial serialDate = CmsCalendarSerialDateFactory.getSerialDate(values, locale); String serialChanges = null; try { serialChanges = cms.readPropertyObject( resource, CmsSerialDateXmlContentHandler.PROPERTY_SERIALDATE_CHANGE, false).getValue(); } catch (CmsException e) { // failed to read property, ignore serialChanges = ""; } if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(serialChanges)) { // there are some changes in the series we have to check CmsXmlContent content = null; if (serialChanges.indexOf(CmsSerialDateXmlContentHandler.SERIES_FLAG_CHANGED) != -1) { // there are changes, we have to unmarshal the content try { content = CmsXmlContentFactory.unmarshal(cms, cms.readFile(resource)); } catch (CmsException e) { // ignore } } List changeList = CmsStringUtil.splitAsList(serialChanges, CmsProperty.VALUE_LIST_DELIMITER); for (int i = 0; i < changeList.size(); i++) { String change = (String)changeList.get(i); String[] changeEntry = CmsStringUtil.splitAsArray(change, CmsProperty.VALUE_MAP_DELIMITER); // get the start date from the string part Calendar startDate = new GregorianCalendar(locale); startDate.setTimeInMillis(Long.parseLong(changeEntry[0])); CmsCalendarEntryData entryDataClone = null; if (changeEntry[1].equals(CmsSerialDateXmlContentHandler.SERIES_FLAG_CHANGED)) { // this is an entry that should be changed entryDataClone = (CmsCalendarEntryData)entryData.clone(); String xPath = CmsSerialDateXmlContentHandler.NODE_CHANGE + "[" + (i + 1) + "]/"; if (content != null) { if (content.hasValue(xPath + NODE_TITLE, locale)) { entryDataClone.setTitle(content.getStringValue(cms, xPath + NODE_TITLE, locale)); } if (content.hasValue(xPath + NODE_TEASER, locale)) { entryDataClone.setDescription(content.getStringValue(cms, xPath + NODE_TEASER, locale)); } if (content.hasValue(xPath + NODE_SHOWTIME, locale)) { entryDataClone.setShowTime(Boolean.valueOf( content.getStringValue(cms, xPath + NODE_SHOWTIME, locale)).booleanValue()); } } } serialDate.getSerialOptions().addSerialDateChange( new CmsCalendarSerialDateChange(startDate, entryDataClone)); } } // check interruptions String serialInterruptions = null; try { serialInterruptions = cms.readPropertyObject( resource, CmsSerialDateXmlContentHandler.PROPERTY_SERIALDATE_INTERRUPTION, false).getValue(); } catch (CmsException e) { // failed to read property, ignore } if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(serialInterruptions)) { // get the interruptions and analyze the String List interruptionList = CmsStringUtil.splitAsList(serialInterruptions, CmsProperty.VALUE_LIST_DELIMITER); for (int i = 0; i < interruptionList.size(); i++) { String interruption = (String)interruptionList.get(i); String[] interruptionEntry = CmsStringUtil.splitAsArray(interruption, CmsProperty.VALUE_MAP_DELIMITER); // get the start date of the interruption Calendar startDate = new GregorianCalendar(locale); startDate.setTimeInMillis(Long.parseLong(interruptionEntry[0])); // get the end date of the interruption Calendar endDate = new GregorianCalendar(locale); endDate.setTimeInMillis(Long.parseLong(interruptionEntry[1])); // add the interruption to the serial date serialDate.getSerialOptions().addSerialDateInterruption( new CmsCalendarSerialDateInterruption(startDate, endDate)); } } return new CmsCalendarEntry(entryData, serialDate); } /** * Returns the start date of the serial date to show.<p> * * @return the start date of the serial date to show */ public Date getStartDate() { Calendar startDate = new GregorianCalendar(getRequestContext().getLocale()); String calDatParam = getCalendarStartParam(); if (CmsStringUtil.isNotEmpty(calDatParam)) { // calculate matching end date from given start date startDate.setTimeInMillis(Long.parseLong(calDatParam)); } else { CmsCalendarEntryDateSerial serialDate = getSerialDate(); if (serialDate != null) { startDate = serialDate.getStartDate(); } } Date result = new Date(startDate.getTimeInMillis()); getJspContext().setAttribute("startdate", result); return result; } /** * Returns the value of the element with the provided path.<p> * * @param path the path of the element * @return the value of the element */ public String getStringValue(String path) { String xPath = getXpathPrefix() + path; if (!getContent().hasValue(xPath, getRequestContext().getLocale())) { // changed value not activated, switch back to base value xPath = path; } return getContent().getStringValue(getCmsObject(), xPath, getRequestContext().getLocale()); } /** * Returns the value of the "Location" element of the serial date.<p> * * @return the value of the "Location" element */ public String getValueLocation() { return getStringValue(NODE_LOCATION); } /** * Returns the value of the "Text" element of the serial date.<p> * * @return the value of the "Text" element */ public String getValueText() { return getStringValue(NODE_TEXT); } /** * Returns the value of the "Title" element of the serial date.<p> * * @return the value of the "Title" element */ public String getValueTitle() { return getStringValue(NODE_TITLE); } /** * Returns if the value exists in the content.<p> * * @param path the path of the element to check * @return true if the value exists in the content, otherwise false */ public boolean hasValue(String path) { String xPath = getXpathPrefix() + path; if (!getContent().hasValue(xPath, getRequestContext().getLocale())) { // changed value not activated, switch back to base value xPath = path; } return getContent().hasValue(xPath, getRequestContext().getLocale()); } /** * @see org.opencms.jsp.CmsJspBean#init(javax.servlet.jsp.PageContext, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ public void init(PageContext context, HttpServletRequest req, HttpServletResponse res) { super.init(context, req, res); m_detailFile = getRequestContext().getUri(); } /** * Checks if the start and end date have the same date and differ only from their time.<p> * * @return true if the two dates differ only in time, otherwise false */ public boolean isSameDate() { return isSameDate(getStartDate(), getEndDate()); } /** * Checks if two dates have the same date and differ only from their time.<p> * * @param start the the start date * @param end the end date * @return true if the two dates differ only in time, otherwise false */ public boolean isSameDate(Date start, Date end) { Calendar calStart = new GregorianCalendar(); calStart.setTimeInMillis(start.getTime()); Calendar calEnd = new GregorianCalendar(); calEnd.setTimeInMillis(end.getTime()); return ((calStart.get(Calendar.DAY_OF_YEAR) == calEnd.get(Calendar.DAY_OF_YEAR)) && (calStart.get(Calendar.YEAR) == calEnd.get(Calendar.YEAR))); } /** * Checks if two dates in the page context attributes have the same date and differ only from their time.<p> * * @param startDateAttrib the name of the page context attribute containing the start date Date * @param endDateAttrib the name of the page context attribute containing the end date Date * @return true if the two dates differ only in time, otherwise false */ public boolean isSameDate(String startDateAttrib, String endDateAttrib) { Date start = (Date)getJspContext().getAttribute(startDateAttrib); Date end = (Date)getJspContext().getAttribute(endDateAttrib); return isSameDate(start, end); } /** * Returns if the time information should be shown.<p> * * @return true if the time information should be shown, otherwise false */ public boolean isShowTime() { String showTimeValue = getStringValue(NODE_SHOWTIME); return Boolean.valueOf(showTimeValue).booleanValue(); } /** * Returns the calendar start date parameter value.<p> * * @return the calendar start date parameter value */ protected String getCalendarStartParam() { if (m_calendarStartParam == null) { m_calendarStartParam = getRequest().getParameter(CmsCalendarDisplay.PARAM_DATE); } return m_calendarStartParam; } /** * Returns the XML content to get the values from.<p> * * @return the XML content */ protected CmsXmlContent getContent() { if (m_content == null) { try { CmsFile file = getCmsObject().readFile(getDetailFile()); m_content = CmsXmlContentFactory.unmarshal(getCmsObject(), file); } catch (CmsException e) { // ignore, should never happen } } return m_content; } /** * Returns the serial date generated from the serial date property values on the resource to show.<p> * * @return the serial date or <code>null</code>, if generating the serial date fails */ protected CmsCalendarEntryDateSerial getSerialDate() { if (m_serialDateEntry == null) { Map values = new HashMap(); try { values = getCmsObject().readPropertyObject( getDetailFile(), CmsCalendarDisplay.PROPERTY_CALENDAR_STARTDATE, false).getValueMap(values); } catch (CmsException e) { // failed to read property } m_serialDateEntry = CmsCalendarSerialDateFactory.getSerialDate(values, getRequestContext().getLocale()); } return m_serialDateEntry; } /** * Returns the xpath prefix depending on the serial date start date and if a change is defined for that date.<p> * * @return the xpath prefix for the content values */ protected String getXpathPrefix() { if (m_xpathPrefix == null) { m_xpathPrefix = ""; String calDatParam = getCalendarStartParam(); if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(calDatParam)) { // found a calendar date parameter, check if a changed date should be shown try { List changeDateValues = getCmsObject().readPropertyObject( getDetailFile(), CmsSerialDateXmlContentHandler.PROPERTY_SERIALDATE_CHANGE, false).getValueList(Collections.EMPTY_LIST); for (int i = 0; i < changeDateValues.size(); i++) { String currentDate = (String)changeDateValues.get(i); currentDate = currentDate.substring(0, currentDate.indexOf(CmsProperty.VALUE_MAP_DELIMITER)); if (calDatParam.equals(currentDate)) { m_xpathPrefix = CmsSerialDateXmlContentHandler.NODE_CHANGE + "[" + (i + 1) + "]/"; break; } } } catch (CmsException e) { // ignore } } } return m_xpathPrefix; } }