org.apache.myfaces.custom.schedule.renderer.AbstractScheduleRenderer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of tomahawk Show documentation
Show all versions of tomahawk Show documentation
JSF components and utilities that can be used with any JSF implementation.
This library is compatible with both JSF1.1 and JSF1.2; however for JSF1.2 users there
is an alternative build of Tomahawk available that takes advantage of JSF1.2 features to
offer some additional benefits.
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. 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.
*/
package org.apache.myfaces.custom.schedule.renderer;
import org.apache.myfaces.custom.schedule.HtmlSchedule;
import org.apache.myfaces.custom.schedule.ScheduleMouseEvent;
import org.apache.myfaces.custom.schedule.model.ScheduleEntry;
import org.apache.myfaces.custom.schedule.util.ScheduleEntryComparator;
import org.apache.myfaces.custom.schedule.util.ScheduleUtil;
import org.apache.myfaces.renderkit.html.util.AddResource;
import org.apache.myfaces.renderkit.html.util.AddResourceFactory;
import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.el.ValueBinding;
import javax.faces.event.ActionEvent;
import javax.faces.render.Renderer;
import java.io.IOException;
import java.io.Serializable;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
/**
*
* Abstract superclass for all renderer of the UISchedule component
*
*
* @author Jurgen Lust (latest modification by $Author: mkienenb $)
* @author Bruno Aranda (adaptation of Jurgen's code to myfaces)
* @version $Revision: 389938 $
*/
public abstract class AbstractScheduleRenderer extends Renderer implements
Serializable
{
//~ Static fields/initializers ---------------------------------------------
protected static final ScheduleEntryComparator comparator = new ScheduleEntryComparator();
protected static final String LAST_CLICKED_DATE = "_last_clicked_date";
protected static final String LAST_CLICKED_Y = "_last_clicked_y";
private static final String CSS_RESOURCE = "css/schedule.css";
public static final String DEFAULT_THEME = "default";
public static final String OUTLOOK_THEME = "outlookxp";
public static final String EVOLUTION_THEME = "evolution";
//~ Methods ----------------------------------------------------------------
/**
* @see javax.faces.render.Renderer#decode(javax.faces.context.FacesContext,
* javax.faces.component.UIComponent)
*/
public void decode(FacesContext context, UIComponent component)
{
HtmlSchedule schedule = (HtmlSchedule) component;
boolean queueAction = false;
if (ScheduleUtil.canModifyValue(component))
{
Map parameters = context.getExternalContext()
.getRequestParameterMap();
String selectedEntryId = (String) parameters.get((String) schedule
.getClientId(context));
String lastClickedDateId = (String) parameters
.get((String) schedule.getClientId(context)
+ LAST_CLICKED_DATE);
String lastClickedY = (String) parameters.get((String) schedule
.getClientId(context)
+ LAST_CLICKED_Y);
ScheduleMouseEvent mouseEvent = null;
if ((selectedEntryId != null) && (selectedEntryId.length() > 0))
{
ScheduleEntry entry = schedule.findEntry(selectedEntryId);
schedule.setSubmittedEntry(entry);
mouseEvent = new ScheduleMouseEvent(schedule,
ScheduleMouseEvent.SCHEDULE_ENTRY_CLICKED);
queueAction = true;
}
if (schedule.isSubmitOnClick())
{
schedule.resetMouseEvents();
if ((lastClickedY != null) && (lastClickedY.length() > 0))
{
//the body of the schedule was clicked
schedule
.setLastClickedDateAndTime(determineLastClickedDate(
schedule, lastClickedDateId, lastClickedY));
mouseEvent = new ScheduleMouseEvent(schedule,
ScheduleMouseEvent.SCHEDULE_BODY_CLICKED);
queueAction = true;
}
else if ((lastClickedDateId != null)
&& (lastClickedDateId.length() > 0))
{
//the header of the schedule was clicked
schedule
.setLastClickedDateAndTime(determineLastClickedDate(
schedule, lastClickedDateId, "0"));
mouseEvent = new ScheduleMouseEvent(schedule,
ScheduleMouseEvent.SCHEDULE_HEADER_CLICKED);
queueAction = true;
}
else if (mouseEvent == null)
{
//the form was posted without mouse events on the schedule
mouseEvent = new ScheduleMouseEvent(schedule,
ScheduleMouseEvent.SCHEDULE_NOTHING_CLICKED);
}
}
if (mouseEvent != null)
schedule.queueEvent(mouseEvent);
}
if (queueAction)
{
schedule.queueEvent(new ActionEvent(schedule));
}
}
/**
* @see javax.faces.render.Renderer#encodeBegin(javax.faces.context.FacesContext,
* javax.faces.component.UIComponent)
*/
public void encodeBegin(FacesContext context, UIComponent component)
throws IOException
{
if (!component.isRendered())
{
return;
}
HtmlSchedule schedule = (HtmlSchedule) component;
ResponseWriter writer = context.getResponseWriter();
//add needed CSS and Javascript files to the header
AddResource addResource = AddResourceFactory.getInstance(context);
String theme = getTheme(schedule);
//The default css file is only loaded if the theme is one of the provided
//themes.
if (DEFAULT_THEME.equals(theme) || OUTLOOK_THEME.equals(theme)
|| EVOLUTION_THEME.equals(theme))
{
addResource.addStyleSheet(context, AddResource.HEADER_BEGIN,
HtmlSchedule.class, CSS_RESOURCE);
}
addResource.addJavaScriptAtPosition(context, AddResource.HEADER_BEGIN,
HtmlSchedule.class, "javascript/schedule.js");
addResource.addJavaScriptAtPosition(context, AddResource.HEADER_BEGIN,
HtmlSchedule.class, "javascript/alphaAPI.js");
addResource.addJavaScriptAtPosition(context, AddResource.HEADER_BEGIN,
HtmlSchedule.class, "javascript/domLib.js");
addResource.addJavaScriptAtPosition(context, AddResource.HEADER_BEGIN,
HtmlSchedule.class, "javascript/domTT.js");
addResource.addJavaScriptAtPosition(context, AddResource.HEADER_BEGIN,
HtmlSchedule.class, "javascript/fadomatic.js");
//hidden input field containing the id of the selected entry
writer.startElement(HTML.INPUT_ELEM, schedule);
writer.writeAttribute(HTML.TYPE_ATTR, "hidden", null);
writer.writeAttribute(HTML.NAME_ATTR, schedule.getClientId(context),
"clientId");
writer.endElement(HTML.INPUT_ELEM);
//hidden input field containing the id of the last clicked date
writer.startElement(HTML.INPUT_ELEM, schedule);
writer.writeAttribute(HTML.TYPE_ATTR, "hidden", null);
writer.writeAttribute(HTML.NAME_ATTR, schedule.getClientId(context)
+ "_last_clicked_date", "clicked_date");
writer.endElement(HTML.INPUT_ELEM);
//hidden input field containing the y coordinate of the mouse when
//the schedule was clicked. This will be used to determine the hour
//of day.
writer.startElement(HTML.INPUT_ELEM, schedule);
writer.writeAttribute(HTML.TYPE_ATTR, "hidden", null);
writer.writeAttribute(HTML.NAME_ATTR, schedule.getClientId(context)
+ "_last_clicked_y", "clicked_y");
writer.endElement(HTML.INPUT_ELEM);
}
/**
*
* Get the String representation of a date, taking into account the
* specified date format or the current Locale.
*
*
* @param context the FacesContext
* @param component the component
* @param date the date
*
* @return the date string
*/
protected String getDateString(FacesContext context, UIComponent component,
Date date)
{
DateFormat format;
String pattern = getHeaderDateFormat(component);
if ((pattern != null) && (pattern.length() > 0))
{
format = new SimpleDateFormat(pattern);
}
else
{
if (context.getApplication().getDefaultLocale() != null)
{
format = DateFormat.getDateInstance(DateFormat.MEDIUM, context
.getApplication().getDefaultLocale());
}
else
{
format = DateFormat.getDateInstance(DateFormat.MEDIUM);
}
}
return format.format(date);
}
/**
*
* The theme used when rendering the schedule
*
*
* @param component the component
*
* @return the theme
*/
protected String getTheme(UIComponent component)
{
//first check if the theme property is a value binding expression
ValueBinding binding = component.getValueBinding("theme");
if (binding != null)
{
String value = (String) binding.getValue(FacesContext
.getCurrentInstance());
if (value != null)
{
return value;
}
}
//it's not a value binding expression, so check for the string value
//in the attributes
Map attributes = component.getAttributes();
String theme = (String) attributes.get("theme");
if (theme == null || theme.length() < 1)
theme = "default";
return theme;
}
/**
*
* Allow the developer to specify custom CSS classnames for the schedule
* component.
*
* @param component the component
* @param className the default CSS classname
* @return the custom classname
*/
protected String getStyleClass(UIComponent component, String className)
{
//first check if the styleClass property is a value binding expression
ValueBinding binding = component.getValueBinding(className);
if (binding != null)
{
String value = (String) binding.getValue(FacesContext
.getCurrentInstance());
if (value != null)
{
return value;
}
}
//it's not a value binding expression, so check for the string value
//in the attributes
Map attributes = component.getAttributes();
String returnValue = (String) attributes.get(className);
return returnValue == null ? className : returnValue;
}
/**
*
* The date format that is used in the schedule header
*
*
* @param component the component
*
* @return Returns the headerDateFormat.
*/
protected String getHeaderDateFormat(UIComponent component)
{
//first check if the headerDateFormat property is a value binding expression
ValueBinding binding = component.getValueBinding("headerDateFormat");
if (binding != null)
{
String value = (String) binding.getValue(FacesContext
.getCurrentInstance());
if (value != null)
{
return value;
}
}
//it's not a value binding expression, so check for the string value
//in the attributes
Map attributes = component.getAttributes();
return (String) attributes.get("headerDateFormat");
}
/**
*
* Should the tooltip be made visible?
*
*
* @param component the component
*
* @return whether or not tooltips should be rendered
*/
protected boolean showTooltip(UIComponent component)
{
//first check if the tooltip property is a value binding expression
ValueBinding binding = component.getValueBinding("tooltip");
if (binding != null)
{
Boolean value = (Boolean) binding.getValue(FacesContext
.getCurrentInstance());
if (value != null)
{
return value.booleanValue();
}
}
//it's not a value binding expression, so check for the string value
//in the attributes
Map attributes = component.getAttributes();
return Boolean.valueOf((String) attributes.get("tooltip"))
.booleanValue();
}
/**
* The user of the Schedule component can customize the look and feel
* by specifying a custom implementation of the ScheduleEntryRenderer.
* This method gets an instance of the specified class, or if none
* was specified, takes the default.
*
* @param component the Schedule component
* @return a ScheduleEntryRenderer instance
*/
protected ScheduleEntryRenderer getEntryRenderer(UIComponent component)
{
Object entryRendererObject = ScheduleUtil.getObjectProperty(component,
null, "entryRenderer", null);
if (entryRendererObject instanceof ScheduleEntryRenderer)
{
return (ScheduleEntryRenderer) entryRendererObject;
}
else
{
return new DefaultScheduleEntryRenderer();
}
}
/**
* @return The default height, in pixels, of one row in the schedule grid
*/
protected abstract int getDefaultRowHeight();
/**
* @return The name of the property that determines the row height
*/
protected abstract String getRowHeightProperty();
/**
* @param attributes
* The attributes
*
* @return The row height, in pixels
*/
protected int getRowHeight(Map attributes)
{
int rowHeight = 0;
try
{
Integer rowHeightObject = (Integer) attributes
.get(getRowHeightProperty());
rowHeight = rowHeightObject.intValue();
}
catch (Exception e)
{
rowHeight = 0;
}
if (rowHeight <= 0)
{
rowHeight = getDefaultRowHeight();
}
return rowHeight;
}
/**
* Determine the last clicked date
* @param schedule the schedule component
* @param dateId the string identifying the date
* @param yPos the y coordinate of the mouse
* @return the clicked date
*/
protected abstract Date determineLastClickedDate(HtmlSchedule schedule,
String dateId, String yPos);
}
//The End