Author: dan.j.allen
Date: 2009-03-31 00:56:03 -0400 (Tue, 31 Mar 2009)
New Revision: 10247
Added:
trunk/src/main/org/jboss/seam/faces/DateConverter.java
Modified:
trunk/doc/Seam_Reference_Guide/en-US/Components.xml
trunk/doc/Seam_Reference_Guide/en-US/Events.xml
trunk/doc/Seam_Reference_Guide/en-US/I18n.xml
trunk/doc/Seam_Reference_Guide/en-US/Tutorial.xml
Log:
JBSEAM-3551
Modified: trunk/doc/Seam_Reference_Guide/en-US/Components.xml
===================================================================
--- trunk/doc/Seam_Reference_Guide/en-US/Components.xml 2009-03-31 03:58:24 UTC (rev
10246)
+++ trunk/doc/Seam_Reference_Guide/en-US/Components.xml 2009-03-31 04:56:03 UTC (rev
10247)
@@ -55,15 +55,41 @@
</para>
</section>
-
+
<section>
- <title>Utility components</title>
+ <title>JSF-related components</title>
<para>
- These components are merely useful.
+ The following set of components are provided to supplement JSF.
</para>
-
- <variablelist>
+
+ <variablelist>
<varlistentry>
+
<term><literal>org.jboss.seam.faces.dateConverter</literal></term>
+ <listitem>
+ <para>
+ Provides a default JSF converter for properties of type
+ <literal>java.util.Date</literal>.
+ </para>
+
+ <para>
+ This converter is automatically registered with JSF. It
+ is provided to save a developer from having to specify
+ a DateTimeConverter on an input field or page
+ parameter. By default, it assumes the type to be a date
+ (as opposed to a time or date plus time) and uses the
+ short input style adjusted to the Locale of the user.
+ For Locale.US, the input pattern is mm/DD/yy. However,
+ to comply with Y2K, the year is changed from two digits
+ to four (e.g., mm/DD/yyyy).
+ </para>
+ <para>
+ It's possible to override the input pattern globally
+ using component configuration. Consult the JavaDoc for
+ this class to see examples.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
<term><literal>org.jboss.seam.faces.facesMessages</literal></term>
<listitem>
<para>
@@ -166,6 +192,21 @@
</para>
</listitem>
</varlistentry>
+ </variablelist>
+
+ <para>
+ These components are installed when the class
<literal>javax.faces.context.FacesContext</literal>
+ is available on the classpath.
+ </para>
+ </section>
+
+ <section>
+ <title>Utility components</title>
+ <para>
+ These components are merely useful.
+ </para>
+
+ <variablelist>
<varlistentry>
<term><literal>org.jboss.seam.core.events</literal></term>
<listitem>
Modified: trunk/doc/Seam_Reference_Guide/en-US/Events.xml
===================================================================
--- trunk/doc/Seam_Reference_Guide/en-US/Events.xml 2009-03-31 03:58:24 UTC (rev 10246)
+++ trunk/doc/Seam_Reference_Guide/en-US/Events.xml 2009-03-31 04:56:03 UTC (rev 10247)
@@ -431,7 +431,8 @@
<para>
Even better, model-based Hibernate validator annotations are automatically
- recognized and validated.
+ recognized and validated. Seam also provides a default date converter to
+ convert a string parameter value to a date and back.
</para>
<para>
Modified: trunk/doc/Seam_Reference_Guide/en-US/I18n.xml
===================================================================
--- trunk/doc/Seam_Reference_Guide/en-US/I18n.xml 2009-03-31 03:58:24 UTC (rev 10246)
+++ trunk/doc/Seam_Reference_Guide/en-US/I18n.xml 2009-03-31 04:56:03 UTC (rev 10247)
@@ -336,6 +336,11 @@
the Seam timezone. In addition, Seam provides the <literal>
<s:convertDateTime></literal> tag which always performs
conversions
in the Seam timezone.</para>
+
+ <para>Seam also provides a default date converter to convert a string value
+ to a date. This saves you from having to specify a converter on input fields
+ that are simply capturing a date. The pattern is selected according the
+ the user's locale and the time zone is selected as described above.</para>
</section>
<section>
Modified: trunk/doc/Seam_Reference_Guide/en-US/Tutorial.xml
===================================================================
--- trunk/doc/Seam_Reference_Guide/en-US/Tutorial.xml 2009-03-31 03:58:24 UTC (rev 10246)
+++ trunk/doc/Seam_Reference_Guide/en-US/Tutorial.xml 2009-03-31 04:56:03 UTC (rev 10247)
@@ -1437,6 +1437,8 @@
</h:inputText>
</h:column>]]></programlisting>
+ <note>Seam provides a default JSF date converter for converting a
string to a date (no time).
+ Thus, the converter is not necessary for the field bound to
<literal>#{task.dueDate}</literal>.</note>
<para> This button ends the task by calling the action method annotated
<literal>@StartTask
@EndTask</literal>. It passes the task id to Seam as a request
parameter: </para>
Added: trunk/src/main/org/jboss/seam/faces/DateConverter.java
===================================================================
--- trunk/src/main/org/jboss/seam/faces/DateConverter.java (rev
0)
+++ trunk/src/main/org/jboss/seam/faces/DateConverter.java 2009-03-31 04:56:03 UTC (rev
10247)
@@ -0,0 +1,120 @@
+package org.jboss.seam.faces;
+
+import static org.jboss.seam.annotations.Install.BUILT_IN;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.convert.ConverterException;
+
+import org.jboss.seam.annotations.Create;
+import org.jboss.seam.annotations.Install;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.faces.Converter;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.contexts.Contexts;
+import org.jboss.seam.log.Log;
+import org.jboss.seam.log.Logging;
+
+/**
+ * Provides a default JSF converter for properties of type java.util.Date.
+ *
+ * <p>This converter is provided to save a developer from having to specify
+ * a DateTimeConverter on an input field or page parameter. By default, it
+ * assumes the type to be a date (as opposed to a time or date plus time) and
+ * uses the short input style adjusted to the Locale of the user. For Locale.US,
+ * the input pattern is mm/DD/yy. However, to comply with Y2K, the year is changed
+ * from two digits to four (e.g., mm/DD/yyyy).</p>
+ * <p>It's possible to override the input pattern globally using component
configuration.
+ * Here is an example of changing the style to both and setting the date and
+ * time style to medium.</p>
+ * <pre>
+ * org.jboss.seam.faces.dateConverter.type=both
+ * org.jboss.seam.faces.dateConverter.dateStyle=medium
+ * org.jboss.seam.faces.dateConverter.timeStyle=medium
+ * </pre>
+ * <p>Alternatively, a fixed pattern can be specified.</p>
+ * <pre>
+ * org.jboss.seam.faces.dateConverter.pattern=yyyy-mm-DD
+ * </pre>
+ *
+ * @author Dan Allen
+ */
+@Converter(forClass = Date.class)
+(a)Name("org.jboss.seam.faces.dateConverter")
+@Install(precedence = BUILT_IN, classDependencies =
"javax.faces.context.FacesContext")
+@BypassInterceptors
+public class DateConverter extends javax.faces.convert.DateTimeConverter {
+
+ private Log log = Logging.getLog(DateConverter.class);
+
+ private static final String TYPE_DATE = "date";
+ private static final String STYLE_SHORT = "short";
+ private static final String TWO_DIGIT_YEAR_PATTERN = "yy";
+ private static final String FOUR_DIGIT_YEAR_PATTERN = "yyyy";
+
+ // constructor is used to initialize converter to allow these values to be overridden
using component properties
+ public DateConverter() {
+ super();
+ setType(TYPE_DATE);
+ setDateStyle(STYLE_SHORT);
+ setTimeStyle(STYLE_SHORT); // default in case developer overrides type to be time or
both
+ }
+
+ @Create
+ public void create() {
+ // TODO make this work if using "both" for type; requires more analysis of
time style
+ if (TYPE_DATE.equals(getType()) && STYLE_SHORT.equals(getDateStyle())
&& getPattern() == null) {
+ // attempt to make the pattern Y2K compliant, which it isn't by default
+ DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT, getLocale());
+ if (dateFormat instanceof SimpleDateFormat) {
+ setPattern(((SimpleDateFormat)
dateFormat).toPattern().replace(TWO_DIGIT_YEAR_PATTERN, FOUR_DIGIT_YEAR_PATTERN));
+ }
+ }
+ // required since the superclass may access the fields directly
+ setTimeZone(getTimeZone());
+ setLocale(getLocale());
+ }
+
+ @Override
+ public TimeZone getTimeZone() {
+ if (Contexts.isApplicationContextActive()) {
+ return org.jboss.seam.international.TimeZone.instance();
+ } else {
+ // we don't want to use JSF's braindead default (maybe in JSF 2)
+ return TimeZone.getDefault();
+ }
+ }
+
+ @Override
+ public Locale getLocale() {
+ if (Contexts.isApplicationContextActive()) {
+ return org.jboss.seam.international.Locale.instance();
+ } else {
+ return super.getLocale();
+ }
+ }
+
+ @Override
+ public Object getAsObject(FacesContext context, UIComponent component,
+ String value) throws ConverterException {
+ if (log.isDebugEnabled()) {
+ log.debug("Converting string '#0' to date for clientId '#1' using
Seam's built-in JSF date converter", value, component.getClientId(context));
+ }
+ return super.getAsObject(context, component, value);
+ }
+
+ @Override
+ public String getAsString(FacesContext context, UIComponent component,
+ Object value) throws ConverterException {
+ if (log.isDebugEnabled()) {
+ log.debug("Converting date '#0' to string for clientId '#1' using
Seam's built-in JSF date converter", value, component.getClientId(context));
+ }
+ return super.getAsString(context, component, value);
+ }
+}