You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2010/11/13 19:48:01 UTC
svn commit: r1034840 -
/myfaces/commons/branches/jsf_11/myfaces-commons-converters/src/main/java/org/apache/myfaces/commons/converter/DateTimeConverter.java
Author: lu4242
Date: Sat Nov 13 18:48:01 2010
New Revision: 1034840
URL: http://svn.apache.org/viewvc?rev=1034840&view=rev
Log:
TOMAHAWK-1010 Default JSF Converters evaluate value-bindings only at converter creation time and MFCOMMONS-12 Add ConverterBase class to allow create converters that evaluate EL expressions at render time
Modified:
myfaces/commons/branches/jsf_11/myfaces-commons-converters/src/main/java/org/apache/myfaces/commons/converter/DateTimeConverter.java
Modified: myfaces/commons/branches/jsf_11/myfaces-commons-converters/src/main/java/org/apache/myfaces/commons/converter/DateTimeConverter.java
URL: http://svn.apache.org/viewvc/myfaces/commons/branches/jsf_11/myfaces-commons-converters/src/main/java/org/apache/myfaces/commons/converter/DateTimeConverter.java?rev=1034840&r1=1034839&r2=1034840&view=diff
==============================================================================
--- myfaces/commons/branches/jsf_11/myfaces-commons-converters/src/main/java/org/apache/myfaces/commons/converter/DateTimeConverter.java (original)
+++ myfaces/commons/branches/jsf_11/myfaces-commons-converters/src/main/java/org/apache/myfaces/commons/converter/DateTimeConverter.java Sat Nov 13 18:48:01 2010
@@ -19,11 +19,26 @@
package org.apache.myfaces.commons.converter;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
import java.util.Locale;
+import java.util.Map;
import java.util.TimeZone;
+import javax.faces.application.FacesMessage;
+import javax.faces.application.FacesMessage.Severity;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.convert.ConverterException;
+import javax.faces.el.ValueBinding;
+
import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFConverter;
import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFProperty;
+import org.apache.myfaces.commons.util.MessageUtils;
/**
* Simple convert that overrides the spec DateTimeConverter and uses TimeZone.getDefault() as the
@@ -38,73 +53,448 @@ import org.apache.myfaces.buildtools.mav
@JSFConverter(
name = "mcc:convertDateTime",
tagClass = "org.apache.myfaces.commons.converter.ConvertDateTimeTag",
- tagSuperclass = "javax.faces.webapp.ConverterTag")
+ tagSuperclass = "javax.faces.webapp.ConverterTag",
+ evaluateELOnExecution=true)
public class DateTimeConverter extends javax.faces.convert.DateTimeConverter
{
public static final String CONVERTER_ID = "org.apache.myfaces.custom.convertDateTime.DateTimeConverter";
+
+ // internal constants
+ private static final String CONVERSION_MESSAGE_ID = "javax.faces.convert.DateTimeConverter.CONVERSION";
+ private static final String TYPE_DATE = "date";
+ private static final String TYPE_TIME = "time";
+ private static final String TYPE_BOTH = "both";
+ private static final String STYLE_DEFAULT = "default";
+ private static final String STYLE_MEDIUM = "medium";
+ private static final String STYLE_SHORT = "short";
+ private static final String STYLE_LONG = "long";
+ private static final String STYLE_FULL = "full";
+ private static final TimeZone TIMEZONE_DEFAULT = TimeZone.getTimeZone("GMT");
+ // CONSTRUCTORS
public DateTimeConverter()
{
- setTimeZone(TimeZone.getDefault());
+ //setTimeZone(TimeZone.getDefault());
+ }
+
+ private String _dateStyle;
+ private Locale _locale;
+ private String _pattern;
+ private String _timeStyle;
+ private TimeZone _timeZone;
+ private String _type;
+ private boolean _transient;
+
+ private transient FacesContext _facesContext;
+
+ // METHODS
+ public Object getAsObject(FacesContext facesContext, UIComponent uiComponent, String value)
+ {
+ if (facesContext == null) throw new NullPointerException("facesContext");
+ if (uiComponent == null) throw new NullPointerException("uiComponent");
+
+ if (value != null)
+ {
+ value = value.trim();
+ if (value.length() > 0)
+ {
+ DateFormat format = getDateFormat();
+ TimeZone tz = getTimeZone();
+ if( tz != null )
+ format.setTimeZone( tz );
+ try
+ {
+ return format.parse(value);
+ }
+ catch (ParseException e)
+ {
+ throw new ConverterException(
+ MessageUtils.getMessage(FacesMessage.FACES_MESSAGES, FacesMessage.SEVERITY_ERROR, CONVERSION_MESSAGE_ID,
+ new Object[] {value, uiComponent.getId()}, facesContext), e);
+ }
+ }
+ }
+ return null;
+ }
+
+ public String getAsString(FacesContext facesContext, UIComponent uiComponent, Object value)
+ {
+ if (facesContext == null) throw new NullPointerException("facesContext");
+ if (uiComponent == null) throw new NullPointerException("uiComponent");
+
+ if (value == null)
+ {
+ return "";
+ }
+ if (value instanceof String)
+ {
+ return (String)value;
+ }
+
+ DateFormat format = getDateFormat();
+ TimeZone tz = getTimeZone();
+ if (tz != null)
+ {
+ format.setTimeZone(tz);
+ }
+ try
+ {
+ return format.format(value);
+ }
+ catch (Exception e)
+ {
+ throw new ConverterException(e);
+ }
+ }
+
+ private DateFormat getDateFormat()
+ {
+ String type = getType();
+ DateFormat format;
+ if (_pattern != null)
+ {
+ try
+ {
+ format = new SimpleDateFormat(_pattern, getLocale());
+ }
+ catch (IllegalArgumentException iae)
+ {
+ throw new ConverterException("Invalid pattern", iae);
+ }
+ }
+ else if (type.equals(TYPE_DATE))
+ {
+ format = DateFormat.getDateInstance(calcStyle(getDateStyle()), getLocale());
+ }
+ else if (type.equals(TYPE_TIME))
+ {
+ format = DateFormat.getTimeInstance(calcStyle(getTimeStyle()), getLocale());
+ }
+ else if (type.equals(TYPE_BOTH))
+ {
+ format = DateFormat.getDateTimeInstance(calcStyle(getDateStyle()),
+ calcStyle(getTimeStyle()),
+ getLocale());
+ }
+ else
+ {
+ throw new ConverterException("invalid type '" + _type + "'");
+ }
+
+ // format cannot be lenient (JSR-127)
+ format.setLenient(false);
+ return format;
+ }
+
+ private int calcStyle(String name)
+ {
+ if (name.equals(STYLE_DEFAULT))
+ {
+ return DateFormat.DEFAULT;
+ }
+ if (name.equals(STYLE_MEDIUM))
+ {
+ return DateFormat.MEDIUM;
+ }
+ if (name.equals(STYLE_SHORT))
+ {
+ return DateFormat.SHORT;
+ }
+ if (name.equals(STYLE_LONG))
+ {
+ return DateFormat.LONG;
+ }
+ if (name.equals(STYLE_FULL))
+ {
+ return DateFormat.FULL;
+ }
+
+ throw new ConverterException("invalid style '" + name + "'");
}
+ // STATE SAVE/RESTORE
+ public void restoreState(FacesContext facesContext, Object state)
+ {
+ Object[] values = (Object[])state;
+ _dateStyle = (String)values[0];
+ _locale = (Locale)values[1];
+ _pattern = (String)values[2];
+ _timeStyle = (String)values[3];
+ _timeZone = (TimeZone)values[4];
+ _type = (String)values[5];
+ restoreValueBindingMap(facesContext, values[6]);
+
+ }
+
+ public Object saveState(FacesContext facesContext)
+ {
+ Object[] values = new Object[7];
+ values[0] = _dateStyle;
+ values[1] = _locale;
+ values[2] = _pattern;
+ values[3] = _timeStyle;
+ values[4] = _timeZone;
+ values[5] = _type;
+ values[6] = saveValueBindingMap(facesContext);
+ return values;
+ }
+
+ // --------------------- borrowed from UIComponentBase ------------
+
+ private Map _valueBindingMap = null;
+
+ public ValueBinding getValueBinding(String name)
+ {
+ if (name == null) throw new NullPointerException("name");
+ if (_valueBindingMap == null)
+ {
+ return null;
+ }
+ else
+ {
+ return (ValueBinding)_valueBindingMap.get(name);
+ }
+ }
+
+ public void setValueBinding(String name,
+ ValueBinding binding)
+ {
+ if (name == null) throw new NullPointerException("name");
+ if (_valueBindingMap == null)
+ {
+ _valueBindingMap = new HashMap();
+ }
+ _valueBindingMap.put(name, binding);
+ }
+
+ private Object saveValueBindingMap(FacesContext context)
+ {
+ if (_valueBindingMap != null)
+ {
+ int initCapacity = (_valueBindingMap.size() * 4 + 3) / 3;
+ HashMap stateMap = new HashMap(initCapacity);
+ for (Iterator it = _valueBindingMap.entrySet().iterator(); it.hasNext(); )
+ {
+ Map.Entry entry = (Map.Entry)it.next();
+ stateMap.put(entry.getKey(),
+ ConverterBase.saveAttachedState(context, entry.getValue()));
+ }
+ return stateMap;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ private void restoreValueBindingMap(FacesContext context, Object stateObj)
+ {
+ if (stateObj != null)
+ {
+ Map stateMap = (Map)stateObj;
+ int initCapacity = (stateMap.size() * 4 + 3) / 3;
+ _valueBindingMap = new HashMap(initCapacity);
+ for (Iterator it = stateMap.entrySet().iterator(); it.hasNext(); )
+ {
+ Map.Entry entry = (Map.Entry)it.next();
+ _valueBindingMap.put(entry.getKey(),
+ ConverterBase.restoreAttachedState(context, entry.getValue()));
+ }
+ }
+ else
+ {
+ _valueBindingMap = null;
+ }
+ }
+ protected FacesContext getFacesContext()
+ {
+ if (_facesContext == null)
+ {
+ return FacesContext.getCurrentInstance();
+ }
+ else
+ {
+ return _facesContext;
+ }
+ }
+
+ boolean isCachedFacesContext()
+ {
+ return _facesContext != null;
+ }
+
+ void setCachedFacesContext(FacesContext facesContext)
+ {
+ _facesContext = facesContext;
+ }
+
+
+ // GETTER & SETTER
+
/**
- * longDesc = "default|short|medium|long|full"
+ * The style of the date. Values include: default, short, medium,
+ * long, and full.
*
*/
@JSFProperty(inheritedTag = false)
public String getDateStyle()
{
- return super.getDateStyle();
+ if (_dateStyle != null)
+ {
+ return _dateStyle;
+ }
+ ValueBinding vb = getValueBinding("dateStyle");
+ if (vb != null)
+ {
+ return (String) vb.getValue(getFacesContext());
+ }
+ return STYLE_DEFAULT;
+ }
+
+ public void setDateStyle(String dateStyle)
+ {
+ _dateStyle = dateStyle;
}
/**
- * longDesc = "locale"
+ * The name of the locale to be used, instead of the default.
*
- */
- @JSFProperty(inheritedTag = false)
+ */
+ @JSFProperty(inheritedTag = false)
public Locale getLocale()
+ {
+ if (_locale != null)
+ {
+ return _locale;
+ }
+ ValueBinding vb = getValueBinding("locale");
+ if (vb != null)
+ {
+ Object _localeValue = vb.getValue(getFacesContext());
+ if (_localeValue instanceof String)
+ {
+ _localeValue = org.apache.myfaces.commons.util.TagUtils.getLocale((String)_localeValue);
+ }
+ return (java.util.Locale)_localeValue;
+ }
+ FacesContext context = FacesContext.getCurrentInstance();
+ return context.getViewRoot().getLocale();
+ }
+
+ public void setLocale(Locale locale)
{
- return super.getLocale();
+ _locale = locale;
}
/**
- * Custom formatting pattern
+ * A custom Date formatting pattern, in the format used by java.text.SimpleDateFormat.
*
*/
@JSFProperty(inheritedTag = false)
public String getPattern()
{
- return super.getPattern();
+ if (_pattern != null)
+ {
+ return _pattern;
+ }
+ ValueBinding vb = getValueBinding("pattern");
+ if (vb != null)
+ {
+ return (String) vb.getValue(getFacesContext()).toString();
+ }
+ return null;
+ }
+
+ public void setPattern(String pattern)
+ {
+ _pattern = pattern;
}
/**
- * default|short|medium|long|full
+ * The style of the time. Values include: default, short, medium, long,
+ * and full.
*
*/
@JSFProperty(inheritedTag = false)
public String getTimeStyle()
{
- return super.getTimeStyle();
+ if (_timeStyle != null)
+ {
+ return _timeStyle;
+ }
+ ValueBinding vb = getValueBinding("timeStyle");
+ if (vb != null)
+ {
+ return (String) vb.getValue(getFacesContext()).toString();
+ }
+ return STYLE_DEFAULT;
+ }
+
+ public void setTimeStyle(String timeStyle)
+ {
+ _timeStyle = timeStyle;
}
/**
- * timeZome
- *
+ * The time zone to use instead of GMT (the default timezone). When
+ * this value is a value-binding to a TimeZone instance, that
+ * timezone is used. Otherwise this value is treated as a String
+ * containing a timezone id, ie as the ID parameter of method
+ * java.util.TimeZone.getTimeZone(String).
+ *
*/
@JSFProperty(inheritedTag = false)
public TimeZone getTimeZone()
{
- return super.getTimeZone();
+ //return _timeZone != null ? _timeZone : TIMEZONE_DEFAULT;
+ if (_timeZone != null)
+ {
+ return _timeZone;
+ }
+ ValueBinding vb = getValueBinding("timeZone");
+ if (vb != null)
+ {
+ Object _timeZoneValue = vb.getValue(getFacesContext());
+ if(_timeZoneValue instanceof java.util.TimeZone)
+ {
+ return (java.util.TimeZone) _timeZoneValue;
+ }
+ else
+ {
+ return java.util.TimeZone.getTimeZone(_timeZoneValue.toString());
+ }
+ }
+ return TimeZone.getDefault(); //TIMEZONE_DEFAULT
+ }
+
+ public void setTimeZone(TimeZone timeZone)
+ {
+ _timeZone = timeZone;
}
/**
- * date|time|both
+ * Specifies whether the date, time, or both should be
+ * parsed/formatted. Values include: date, time, and both.
+ * Default based on setting of timeStyle and dateStyle.
*
*/
@JSFProperty(inheritedTag = false)
public String getType()
{
- return super.getType();
+ if (_type != null)
+ {
+ return _type;
+ }
+ ValueBinding vb = getValueBinding("type");
+ if (vb != null)
+ {
+ return (String) vb.getValue(getFacesContext()).toString();
+ }
+ return TYPE_DATE;
+ }
+
+ public void setType(String type)
+ {
+ _type = type;
}
}