/*
* File : $Source: /alkacon/cvs/alkacon/com.alkacon.opencms.v8.calendar/src/com/alkacon/opencms/v8/calendar/CmsSerialDateSelectWidget.java,v $
* Date : $Date: 2008/04/25 14:50:41 $
* Version: $Revision: 1.1 $
*
* 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.v8.calendar;
import org.opencms.file.CmsObject;
import org.opencms.file.CmsProperty;
import org.opencms.file.CmsResource;
import org.opencms.i18n.CmsMessages;
import org.opencms.main.CmsException;
import org.opencms.main.OpenCms;
import org.opencms.util.CmsStringUtil;
import org.opencms.widgets.CmsSelectWidget;
import org.opencms.widgets.CmsSelectWidgetOption;
import org.opencms.widgets.I_CmsWidget;
import org.opencms.widgets.I_CmsWidgetDialog;
import org.opencms.widgets.I_CmsWidgetParameter;
import org.opencms.xml.content.I_CmsXmlContentHandler;
import org.opencms.xml.types.A_CmsXmlContentValue;
import org.opencms.xml.types.I_CmsXmlContentValue;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
/**
* Provides a widget for a serial date select box.<p>
*
* This can be used to define changes in the serial date for specific dates.
* The widget can be configured to read the serial date information from a property,
* the maximum number of available select box options can be configured as well:
* <code><layout element="Change" widget="V8SerialDateSelectWidget" configuration="property:calendar.startdate|count:25" /></code>.<p>
*
* @author Andreas Zahner
*/
public class CmsSerialDateSelectWidget extends CmsSelectWidget {
/** The prefix for the configuration of the count of entries that should be shown in the select box. */
public static final String PREFIX_COUNT = "count:";
/** The prefix for the configuration of the property name to look up for the serial date configuration. */
public static final String PREFIX_PROPERTY = I_CmsXmlContentHandler.MAPTO_PROPERTY;
/** The count of the entry dates that should be shown in the select box. */
private int m_entryCount;
/** The name of the property to read the serial date configuration from. */
private String m_propertyName;
/**
* Creates a new select widget.<p>
*/
public CmsSerialDateSelectWidget() {
// empty constructor is required for class registration
super();
}
/**
* Creates a select widget with the specified select option configuration parameters.<p>
*
* @param configuration the configuration parameters needed for the select box creation
*/
public CmsSerialDateSelectWidget(String configuration) {
super(configuration);
}
/**
* Returns the calculated calendar entries from the given serial date values.<p>
*
* @param serialDateValues the serial date values to use
* @param locale the locale for the calendar calculation
* @param maxCount the maximum count of entries
* @return the calculated calendar entries
*/
public static List<?> getCalendarEntries(Map<?, ?> serialDateValues, Locale locale, int maxCount) {
CmsCalendarEntryDateSerial serialDate = CmsCalendarSerialDateFactory.getSerialDate(serialDateValues, locale);
List<?> entries = new ArrayList<Object>(maxCount);
if (serialDate != null) {
// calculate the entries
List<CmsCalendarEntryDate> viewDates = new ArrayList<CmsCalendarEntryDate>(1);
// set start date for view creation
Calendar startDate = (Calendar)serialDate.getStartDate().clone();
startDate = CmsCalendarDisplay.setDayTime(startDate, 0, 0, 0);
// set end date for view creation
Calendar endDate = (Calendar)startDate.clone();
if (serialDate.getSerialOptions().getSerialType() == I_CmsCalendarSerialDateOptions.TYPE_YEARLY) {
// for yearly series, increase the end date
endDate.add(Calendar.YEAR, maxCount);
}
endDate.add(Calendar.YEAR, maxCount);
endDate = CmsCalendarDisplay.setDayTime(endDate, 23, 59, 59);
CmsCalendarEntryDate viewDate = new CmsCalendarEntryDate(startDate, endDate);
viewDates.add(viewDate);
// create the simple view
CmsCalendarViewSimple view = new CmsCalendarViewSimple(viewDates);
CmsCalendarEntry entry = new CmsCalendarEntry();
entry.setEntryDate(serialDate);
// get the entries
entries = serialDate.matchCalendarView(entry, view, maxCount);
}
return entries;
}
/**
* Parse the given select parameter to select option.<p>
*
* @param selectValues the selection parameter
* @param locale the locale
* @param maxCount the max values to show
* @return List of select options
*/
protected static LinkedList<CmsSelectWidgetOption> parseOptions(String selectValues, Locale locale, int maxCount) {
LinkedList<CmsSelectWidgetOption> result = new LinkedList<CmsSelectWidgetOption>();
// initialize configuration before calculating the serial date entries
result.add(new CmsSelectWidgetOption("", false, "Please select"));
// read the configured property value
Map<String, String> serialDateValues = new HashMap<String, String>();
String[] values = selectValues.split("\\|");
for (String value : values) {
String[] val = value.split("=");
if (val.length >= 2) {
serialDateValues.put(val[0], val[1]);
} else {
serialDateValues.put(val[0], "");
}
}
// get the entries
List<?> entries = getCalendarEntries(serialDateValues, locale, maxCount);
// create formatting objects to format select box options
SimpleDateFormat df = new SimpleDateFormat("EE, MMM d, yyyy", locale);
NumberFormat nf = NumberFormat.getIntegerInstance(locale);
nf.setMinimumIntegerDigits(2);
for (int i = 0; i < entries.size(); i++) {
CmsCalendarEntry currEntry = (CmsCalendarEntry)entries.get(i);
Calendar entryStart = currEntry.getEntryDate().getStartDate();
// create displayed option text
StringBuffer displayDate = new StringBuffer(32);
displayDate.append(nf.format(i + 1));
displayDate.append(": ");
displayDate.append(df.format(entryStart.getTime()));
CmsSelectWidgetOption option = new CmsSelectWidgetOption(
String.valueOf(i + 1),
false,
displayDate.toString());
// add option to result list
result.add(option);
}
return result;
}
/**
* @see org.opencms.widgets.A_CmsSelectWidget#getConfiguration(org.opencms.file.CmsObject, org.opencms.xml.types.A_CmsXmlContentValue, org.opencms.i18n.CmsMessages, org.opencms.file.CmsResource, java.util.Locale)
*/
@Override
public String getConfiguration(
CmsObject cms,
A_CmsXmlContentValue schemaType,
CmsMessages messages,
CmsResource resource,
Locale contentLocale) {
initConfiguration(getConfiguration());
return getEntryCount() + ";" + contentLocale.toString();
}
/**
* Returns the count of the entry dates that should be shown in the select box.<p>
*
* @return the count of the entry dates that should be shown in the select box
*/
public int getEntryCount() {
return m_entryCount;
}
/**
* @see org.opencms.widgets.CmsCalendarWidget#getInitCall()
*/
@Override
public String getInitCall() {
return "initSerialDateSelectWidget";
}
/**
* @see org.opencms.widgets.CmsCalendarWidget#getJavaScriptResourceLinks(org.opencms.file.CmsObject)
*/
@Override
public List<String> getJavaScriptResourceLinks(CmsObject cms) {
String link = "/system/modules/com.alkacon.opencms.v8.calendar/resources/com.alkacon.opencms.v8.calendar.SerialDateWidget/com.alkacon.opencms.v8.calendar.SerialDateWidget.nocache.js";
return Collections.singletonList(OpenCms.getLinkManager().substituteLink(cms, link));
}
/**
* Returns the name of the property to read the serial date configuration from.<p>
*
* @return the name of the property to read the serial date configuration from
*/
public String getPropertyName() {
return m_propertyName;
}
/**
* @see org.opencms.widgets.I_CmsADEWidget#getWidgetName()
*/
@Override
public String getWidgetName() {
return CmsSerialDateSelectWidget.class.getName();
}
/**
* Sets the select widget configuration options from the given configuration string.<p>
*
* @param configuration the configuration string
*/
public void initConfiguration(String configuration) {
// set default values before parsing the configuration String
setEntryCount(20);
setPropertyName(CmsCalendarDisplay.PROPERTY_CALENDAR_STARTDATE);
if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(configuration)) {
List<?> parts = CmsStringUtil.splitAsList(configuration, CmsProperty.VALUE_LIST_DELIMITER, true);
Iterator<?> i = parts.iterator();
while (i.hasNext()) {
String part = (String)i.next();
if (part.startsWith(PREFIX_COUNT)) {
String countStr = part.substring(PREFIX_COUNT.length());
try {
setEntryCount(Integer.parseInt(countStr));
} catch (Exception e) {
// ignore, use default entry count
}
} else if (part.startsWith(PREFIX_PROPERTY)) {
setPropertyName(part.substring(PREFIX_PROPERTY.length()));
}
}
}
}
/**
* @see org.opencms.widgets.I_CmsADEWidget#isInternal()
*/
@Override
public boolean isInternal() {
return false;
}
/**
* @see org.opencms.widgets.I_CmsWidget#newInstance()
*/
@Override
public I_CmsWidget newInstance() {
return new CmsSerialDateSelectWidget(getConfiguration());
}
/**
* Sets the count of the entry dates that should be shown in the select box.<p>
*
* @param entryCount the count of the entry dates that should be shown in the select box
*/
public void setEntryCount(int entryCount) {
m_entryCount = entryCount;
}
/**
* Sets the name of the property to read the serial date configuration from.<p>
*
* @param propertyName the name of the property to read the serial date configuration from
*/
public void setPropertyName(String propertyName) {
m_propertyName = propertyName;
}
/**
* @see org.opencms.widgets.A_CmsSelectWidget#parseSelectOptions(org.opencms.file.CmsObject, org.opencms.widgets.I_CmsWidgetDialog, org.opencms.widgets.I_CmsWidgetParameter)
*/
@Override
protected List<CmsSelectWidgetOption> parseSelectOptions(
CmsObject cms,
I_CmsWidgetDialog widgetDialog,
I_CmsWidgetParameter param) {
List<CmsSelectWidgetOption> result = new ArrayList<CmsSelectWidgetOption>(getEntryCount() + 1);
// cast param to I_CmsXmlContentValue
I_CmsXmlContentValue value = (I_CmsXmlContentValue)param;
// initialize configuration before calculating the serial date entries
initConfiguration(getConfiguration());
result.add(new CmsSelectWidgetOption(
"",
false,
widgetDialog.getMessages().key("GUI_SERIALDATE_WIDGET_SELECT_0")));
try {
// read the configured property value
Map<?, ?> serialDateValues = cms.readPropertyObject(value.getDocument().getFile(), getPropertyName(), false).getValueMap(
Collections.<String, String> emptyMap());
// get the entries
List<?> entries = getCalendarEntries(serialDateValues, value.getLocale(), getEntryCount());
// create formatting objects to format select box options
SimpleDateFormat df = new SimpleDateFormat("EE, ", widgetDialog.getLocale());
NumberFormat nf = NumberFormat.getIntegerInstance(widgetDialog.getLocale());
nf.setMinimumIntegerDigits(2);
for (int i = 0; i < entries.size(); i++) {
CmsCalendarEntry currEntry = (CmsCalendarEntry)entries.get(i);
Calendar entryStart = currEntry.getEntryDate().getStartDate();
// create displayed option text
StringBuffer displayDate = new StringBuffer(32);
displayDate.append(nf.format(i + 1));
displayDate.append(": ");
displayDate.append(df.format(entryStart.getTime()));
displayDate.append(widgetDialog.getMessages().getDate(entryStart.getTime(), DateFormat.MEDIUM));
CmsSelectWidgetOption option = new CmsSelectWidgetOption(
String.valueOf(i + 1),
false,
displayDate.toString());
// add option to result list
result.add(option);
}
} catch (CmsException e) {
// ignore
}
return result;
}
}