org.apache.myfaces.custom.date.AbstractHtmlInputDate 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.date;
import java.io.Serializable;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import javax.faces.component.html.HtmlInputText;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import org.apache.commons.lang.StringUtils;
import org.apache.myfaces.component.AlignProperty;
import org.apache.myfaces.component.ForceIdAware;
import org.apache.myfaces.component.UserRoleAware;
import org.apache.myfaces.component.UserRoleUtils;
import org.apache.myfaces.component.html.util.HtmlComponentUtils;
import org.apache.myfaces.custom.calendar.DateBusinessConverter;
import org.apache.myfaces.custom.calendar.DefaultDateBusinessConverter;
/**
* Custom input control for dates and times.
*
* Unless otherwise specified, all attributes accept static values or EL expressions.
*
* @JSFComponent
* name = "t:inputDate"
* class = "org.apache.myfaces.custom.date.HtmlInputDate"
* tagClass = "org.apache.myfaces.custom.date.HtmlInputDateTag"
* tagSuperclass = "org.apache.myfaces.custom.date.AbstractHtmlInputDateTag"
* tagHandler = "org.apache.myfaces.custom.date.HtmlInputDateTagHandler"
*
* @since 1.1.7
* @author Sylvain Vieujot (latest modification by $Author: lu4242 $)
* @version $Revision: 990311 $ $Date: 2010-08-27 21:04:55 -0500 (Fri, 27 Aug 2010) $
*/
public abstract class AbstractHtmlInputDate extends HtmlInputText
implements UserRoleAware, ForceIdAware, AlignProperty {
public static final String COMPONENT_TYPE = "org.apache.myfaces.HtmlInputDate";
public static final String COMPONENT_FAMILY = "javax.faces.Input";
private static final String DEFAULT_RENDERER_TYPE = "org.apache.myfaces.Date";
/**
* Overriden to support the force id, since the parent is not an extended component
*/
public String getClientId(FacesContext context)
{
String clientId = HtmlComponentUtils.getClientId(this, getRenderer(context), context);
if (clientId == null)
{
clientId = super.getClientId(context);
}
return clientId;
}
public boolean isRendered(){
if (!UserRoleUtils.isVisibleOnUserRole(this)) return false;
return super.isRendered();
}
public UserData getUserData(Locale currentLocale){
return new UserData((Date) getDateBusinessConverter(this).getDateValue(getFacesContext(), this, getValue()), currentLocale, getTimeZone(), isAmpm(), getType());
}
private DateBusinessConverter getDateBusinessConverter(AbstractHtmlInputDate component)
{
DateBusinessConverter dateBusinessConverter = component.getDateBusinessConverter();
if (dateBusinessConverter == null)
{
dateBusinessConverter = new DefaultDateBusinessConverter();
}
return dateBusinessConverter;
}
public static class UserData implements Serializable {
private static final long serialVersionUID = -6507279524833267707L;
private String day;
private String month;
private String year;
private String hours;
private String minutes;
private String seconds;
private TimeZone timeZone = null;
private String ampm;
private boolean uses_ampm;
private String type;
public UserData(Date date, Locale currentLocale, String _timeZone, boolean uses_ampm, String type){
this.uses_ampm = uses_ampm;
this.type = type;
Calendar calendar = Calendar.getInstance(currentLocale);
if (_timeZone != null) {
timeZone = TimeZone.getTimeZone(_timeZone);
calendar.setTimeZone(timeZone);
}
if(date == null)
return;
calendar.setTime( date );
day = Integer.toString(calendar.get(Calendar.DAY_OF_MONTH));
month = Integer.toString(calendar.get(Calendar.MONTH)+1);
year = Integer.toString(calendar.get(Calendar.YEAR));
if (uses_ampm) {
int int_hours = calendar.get(Calendar.HOUR);
// ampm hours must be in range 0-11 to be handled right; we have to handle "12" specially
if (int_hours == 0) {
int_hours = 12;
}
hours = Integer.toString(int_hours);
ampm = Integer.toString(calendar.get(Calendar.AM_PM));
} else {
hours = Integer.toString(calendar.get(Calendar.HOUR_OF_DAY));
}
minutes = Integer.toString(calendar.get(Calendar.MINUTE));
seconds = Integer.toString(calendar.get(Calendar.SECOND));
}
public Date parse() throws ParseException{
Date retDate = null;
Calendar tempCalendar=Calendar.getInstance();
tempCalendar.setLenient(Boolean.FALSE.booleanValue());
if (timeZone != null)
tempCalendar.setTimeZone(timeZone);
try{
if(!isSubmitValid(uses_ampm, type)) {
return null;
}
//There are this types: date | time | short_time | both | full
if(! (type.equals( "time" ) || type.equals( "short_time" )) ) {
//Set day, month and year for type date, both, full
tempCalendar.set(Calendar.DAY_OF_MONTH,Integer.parseInt(day));
tempCalendar.set(Calendar.MONTH,Integer.parseInt(month)-1);
tempCalendar.set(Calendar.YEAR,Integer.parseInt(year));
if( type.equals("date") ) {
//Reset hour, minute, second and milisecond to type date
tempCalendar.set(Calendar.HOUR_OF_DAY, 0);
tempCalendar.set(Calendar.MINUTE, 0);
tempCalendar.set(Calendar.SECOND, 0);
tempCalendar.set(Calendar.MILLISECOND, 0);
return new java.sql.Date(tempCalendar.getTimeInMillis());
}
}
if(! type.equals( "date" )) {
//Set hour, ampm, minute, second to
//type time, short_time, both, full
if (uses_ampm) {
int int_hours = Integer.parseInt(hours);
// ampm hours must be in range 0-11 to be handled right; we have to handle "12" specially
if (int_hours == 12) {
int_hours = 0;
}
tempCalendar.set(Calendar.HOUR,int_hours);
tempCalendar.set(Calendar.AM_PM,Integer.parseInt(ampm));
} else {
tempCalendar.set(Calendar.HOUR_OF_DAY,Integer.parseInt(hours));
}
tempCalendar.set(Calendar.MINUTE,Integer.parseInt(minutes));
if (seconds != null & (type.equals("full") || type.equals("time") || type.equals("short_time"))) {
tempCalendar.set(Calendar.SECOND,Integer.parseInt(seconds));
}
else
{
//Reset seconds for both type
tempCalendar.set(Calendar.SECOND,0);
}
}
tempCalendar.set(Calendar.MILLISECOND, 0);
retDate = tempCalendar.getTime();
} catch (NumberFormatException e) {
throw new ParseException(e.getMessage(),0);
} catch (IllegalArgumentException e) {
throw new ParseException(e.getMessage(),0);
}
return retDate;
}
private String formatedInt(String toFormat){
if( toFormat == null )
return null;
int i = -1;
try{
i = Integer.parseInt( toFormat );
}catch(NumberFormatException nfe){
return toFormat;
}
if( i >= 0 && i < 10 )
return "0"+i;
return Integer.toString(i);
}
private boolean isDateSubmitted(boolean usesAmpm, String type) {
boolean isDateSubmitted = ! (StringUtils.isEmpty(getDay()) && ((getMonth() == null) || getMonth().equals("-1")) && StringUtils.isEmpty(getYear()));
if(usesAmpm)
isDateSubmitted = isDateSubmitted || isAmpmSubmitted();
return isDateSubmitted;
}
private boolean isTimeSubmitted(boolean usesAmpm, String type) {
boolean isTimeSubmitted = ! (StringUtils.isEmpty(getHours()) && StringUtils.isEmpty(getMinutes()));
if(type.equals("time") || type.equals("full"))
isTimeSubmitted = isTimeSubmitted || ! StringUtils.isEmpty(getSeconds());
if(usesAmpm)
isTimeSubmitted = isTimeSubmitted || isAmpmSubmitted();
return isTimeSubmitted;
}
private boolean isSubmitValid(boolean usesAmpm, String type) {
if(type.equals("date"))
return isDateSubmitted(usesAmpm, type);
else if(type.equals("time") || (type.equals("short_time")))
return isTimeSubmitted(usesAmpm, type);
else if(type.equals("full") || type.equals("both"))
return isDateSubmitted(usesAmpm, type) || isTimeSubmitted(usesAmpm, type);
else
return false;
}
private boolean isAmpmSubmitted() {
if(getAmpm() == null)
return false;
else
return ! getAmpm().equals("-1");
}
public String getDay() {
return formatedInt( day );
}
public void setDay(String day) {
this.day = day;
}
public String getMonth() {
return month;
}
public void setMonth(String month) {
this.month = month;
}
public String getYear() {
return year;
}
public void setYear(String year) {
this.year = year;
}
public String getHours() {
return formatedInt( hours );
}
public void setHours(String hours) {
this.hours = hours;
}
public String getMinutes() {
return formatedInt( minutes );
}
public void setMinutes(String minutes) {
this.minutes = minutes;
}
public String getSeconds() {
return formatedInt( seconds );
}
public void setSeconds(String seconds) {
this.seconds = seconds;
}
public String getAmpm() {
return ampm;
}
public void setAmpm(String ampm) {
this.ampm = ampm;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
/**
* Indicate an object used as a bridge between the java.util.Date instance
* used by this component internally and the value object used on the bean,
* referred as a "business" value.
*
*
* - If the value is literal, look for the mentioned class instance,
* create a new instance and assign to the component property.
* - If it the value a EL Expression, set the expression to the
* component property.
*
*
* @JSFProperty stateHolder="true" inheritedTag="true"
*/
public abstract DateBusinessConverter getDateBusinessConverter();
public abstract void setDateBusinessConverter(DateBusinessConverter dateBusinessConverter);
/**
* @JSFProperty
*/
public abstract String getTimeZone();
/**
* Specifies the type of value to be accepted.
* Valid values are: date | time | short_time | both | full
*
* @JSFProperty
* defaultValue = "date"
*/
public abstract String getType();
/**
* If true, use 12hr times with AM/PM selector; if false, use 24hr time. Default false.
*
* @JSFProperty
* defaultValue = "false"
*/
public abstract boolean isAmpm();
/**
* @JSFProperty
* defaultValue = "false"
*/
public abstract boolean isPopupCalendar();
/**
* Label to be used when displaying an empty month selection
*
* @JSFProperty
* defaultValue = "\"\""
*/
public abstract String getEmptyMonthSelection();
/**
* Label to be used when displaying an empty ampm selection
*
* @JSFProperty
* defaultValue = "\"\""
*/
public abstract String getEmptyAmpmSelection();
/**
* HTML: When true, indicates that this component cannot be modified by the user.
* The element may receive focus unless it has also been disabled.
*
* @JSFProperty
*/
public abstract boolean isReadonly();
/**
* HTML: When true, this element cannot receive focus.
*
* @JSFProperty
* defaultValue = "false"
*/
public abstract boolean isDisabled();
/**
* Retrieve the converter used by this component.
*
* If no converter is selected, submitted values are converted to
* its inner class UserData on decode method.
*
*
* If some converter is used, submitted values are decoded as
* a String with the following format:
*
*
* year=yyyy
* month=mm
* day=dd
* hours=hh
* minutes=mm
* seconds=ss
* ampm=ampm
*
*
* Note that submitted values could be wrong and it is necessary to
* restore values on render response phase. The converter receive
* a string with this format on getAsObject method and it is expected
* the converter encode it on getAsString method, so the renderer can
* restore the submitted values correctly.
*
*
* @JSFProperty
*/
public Converter getConverter()
{
return super.getConverter();
}
}