You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by lu...@apache.org on 2014/03/27 19:42:50 UTC
[2/2] git commit: WW-3493 Adds new datetextfield tag
WW-3493 Adds new datetextfield tag
Project: http://git-wip-us.apache.org/repos/asf/struts/repo
Commit: http://git-wip-us.apache.org/repos/asf/struts/commit/9c9d2b5a
Tree: http://git-wip-us.apache.org/repos/asf/struts/tree/9c9d2b5a
Diff: http://git-wip-us.apache.org/repos/asf/struts/diff/9c9d2b5a
Branch: refs/heads/develop
Commit: 9c9d2b5a58f13b0b8704a30e3f53078154a9a6b8
Parents: 86813c1
Author: Lukasz Lenart <lu...@apache.org>
Authored: Thu Mar 27 19:42:35 2014 +0100
Committer: Lukasz Lenart <lu...@apache.org>
Committed: Thu Mar 27 19:42:35 2014 +0100
----------------------------------------------------------------------
.../struts2/components/DateTextField.java | 51 +++
.../interceptor/DateTextFieldInterceptor.java | 128 +++++++
.../struts2/views/jsp/ui/DateTextFieldTag.java | 35 ++
core/src/main/resources/struts-default.xml | 4 +
core/src/site/resources/tags/datetextfield.html | 376 +++++++++++++++++++
.../DateTextFieldInterceptorTest.java | 58 +++
.../views/java/simple/DateTextFieldHandler.java | 91 +++++
.../struts2/views/java/simple/SimpleTheme.java | 1 +
.../views/java/simple/DateTextFieldTest.java | 51 +++
9 files changed, 795 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/struts/blob/9c9d2b5a/core/src/main/java/org/apache/struts2/components/DateTextField.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/struts2/components/DateTextField.java b/core/src/main/java/org/apache/struts2/components/DateTextField.java
new file mode 100644
index 0000000..0fd3614
--- /dev/null
+++ b/core/src/main/java/org/apache/struts2/components/DateTextField.java
@@ -0,0 +1,51 @@
+package org.apache.struts2.components;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.struts2.views.annotations.StrutsTag;
+import org.apache.struts2.views.annotations.StrutsTagAttribute;
+
+import com.opensymphony.xwork2.util.ValueStack;
+
+@StrutsTag(
+ name="datetextfield",
+ tldTagClass="org.apache.struts2.views.jsp.ui.DateTextFieldTag",
+ description="Render an HTML input fields with the date time",
+ allowDynamicAttributes=true)
+public class DateTextField extends UIBean {
+ /**
+ * The name of the default template for the DateTextFieldTag
+ */
+ final public static String TEMPLATE = "datetextfield";
+
+ protected String format;
+
+ public DateTextField(ValueStack stack, HttpServletRequest request, HttpServletResponse response) {
+ super(stack, request, response);
+ }
+
+ protected String getDefaultTemplate() {
+ return TEMPLATE;
+ }
+
+ protected void evaluateExtraParams() {
+ super.evaluateExtraParams();
+
+ if (format != null) {
+ addParameter("format", findValue(format, String.class));
+ }
+ }
+
+ @StrutsTagAttribute(description="Date format attribute", required=true, type="String")
+ public void setFormat(String format) {
+ this.format = format;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected Class getValueClassType() {
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/struts/blob/9c9d2b5a/core/src/main/java/org/apache/struts2/interceptor/DateTextFieldInterceptor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/struts2/interceptor/DateTextFieldInterceptor.java b/core/src/main/java/org/apache/struts2/interceptor/DateTextFieldInterceptor.java
new file mode 100644
index 0000000..f5bda69
--- /dev/null
+++ b/core/src/main/java/org/apache/struts2/interceptor/DateTextFieldInterceptor.java
@@ -0,0 +1,128 @@
+package org.apache.struts2.interceptor;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
+
+import com.opensymphony.xwork2.ActionInvocation;
+import com.opensymphony.xwork2.interceptor.Interceptor;
+import com.opensymphony.xwork2.util.logging.Logger;
+import com.opensymphony.xwork2.util.logging.LoggerFactory;
+
+public class DateTextFieldInterceptor implements Interceptor {
+
+ private static final Logger LOG = LoggerFactory.getLogger(DateTextFieldInterceptor.class);
+
+ public static enum DateWord {
+
+ S("millisecond", 3, "SSS"),
+ s("second", 2, "ss"),
+ m("minute", 2, "mm"),
+ H("hour", 2, "HH"),
+ d("day", 2, "dd"),
+ M("month", 2, "MM"),
+ y("year", 4, "yyyy");
+
+ private String description;
+ private Integer length;
+ private String dateType;
+
+ private DateWord(String n, Integer l, String t) {
+ description = n;
+ length = l;
+ dateType = t;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public Integer getLength() {
+ return length;
+ }
+
+ public String getDateType() {
+ return dateType;
+ }
+
+ public static DateWord get(Character c) {
+ return valueOf(DateWord.class, c.toString());
+ }
+
+ public static DateWord[] getAll() {
+ return values();
+ }
+ }
+
+ public void destroy() {
+ }
+
+ public void init() {
+ }
+
+ public String intercept(ActionInvocation ai) throws Exception {
+ Map<String, Object> parameters = ai.getInvocationContext().getParameters();
+ Set<Entry<String, Object>> entries = parameters.entrySet();
+ Map<String, Map<String, String>> dates = new HashMap<String, Map<String,String>>();
+
+ DateWord[] dateWords = DateWord.getAll();
+
+ // Get all the values of date type
+ for (Iterator<Entry<String, Object>> iterator = entries.iterator(); iterator.hasNext();) {
+ Entry<String, ?> entry = iterator.next();
+ String key = entry.getKey();
+
+ for (DateWord dateWord : dateWords) {
+ String dateKey = "__" + dateWord.getDescription() + "_";
+ if (key.startsWith(dateKey)) {
+ String name = key.substring(dateKey.length());
+
+ if (entry.getValue() instanceof String[]) {
+ String[] values = (String[])entry.getValue();
+ if (values.length > 0 && !"".equals(values[0])) {
+ iterator.remove();
+ Map<String, String> map = dates.get(name);
+ if (map == null) {
+ map = new HashMap<String, String>();
+ dates.put(name, map);
+ }
+ map.put(dateWord.getDateType(), values[0]);
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ // Create all the date objects
+ Map<String, Date> newParams = new HashMap<String, Date>();
+ Set<Entry<String, Map<String, String>>> dateEntries = dates.entrySet();
+ for (Entry<String, Map<String, String>> dateEntry : dateEntries) {
+ Set<Entry<String, String>> dateFormatEntries = dateEntry.getValue().entrySet();
+ String dateFormat = "";
+ String dateValue = "";
+ for (Entry<String, String> dateFormatEntry : dateFormatEntries) {
+ dateFormat += dateFormatEntry.getKey() + "__";
+ dateValue += dateFormatEntry.getValue() + "__";
+ }
+ try {
+ SimpleDateFormat formatter = new SimpleDateFormat(dateFormat);
+ formatter.setLenient(false);
+ Date value = formatter.parse(dateValue);
+ newParams.put(dateEntry.getKey(), value);
+ } catch (ParseException e) {
+ LOG.warn("Cannot parse the parameter '" + dateEntry.getKey()
+ + "' with format '" + dateFormat + "' and with value '" + dateValue + "'");
+ }
+ }
+ parameters.putAll(newParams);
+
+ return ai.invoke();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/struts/blob/9c9d2b5a/core/src/main/java/org/apache/struts2/views/jsp/ui/DateTextFieldTag.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/DateTextFieldTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/DateTextFieldTag.java
new file mode 100644
index 0000000..3b3a673
--- /dev/null
+++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/DateTextFieldTag.java
@@ -0,0 +1,35 @@
+package org.apache.struts2.views.jsp.ui;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.struts2.components.Component;
+import org.apache.struts2.components.DateTextField;
+
+import com.opensymphony.xwork2.util.ValueStack;
+
+/**
+ * @see DateTextField
+ */
+public class DateTextFieldTag extends AbstractUITag {
+
+ private static final long serialVersionUID = 5811285953670562288L;
+
+ protected String format;
+
+ public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
+ return new DateTextField(stack, req, res);
+ }
+
+ protected void populateParams() {
+ super.populateParams();
+
+ DateTextField textField = ((DateTextField) component);
+ textField.setFormat(format);
+ }
+
+ public void setFormat(String format) {
+ this.format = format;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/struts/blob/9c9d2b5a/core/src/main/resources/struts-default.xml
----------------------------------------------------------------------
diff --git a/core/src/main/resources/struts-default.xml b/core/src/main/resources/struts-default.xml
index a99a945..5c446b1 100644
--- a/core/src/main/resources/struts-default.xml
+++ b/core/src/main/resources/struts-default.xml
@@ -186,6 +186,7 @@
<interceptor name="workflow" class="com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor"/>
<interceptor name="store" class="org.apache.struts2.interceptor.MessageStoreInterceptor" />
<interceptor name="checkbox" class="org.apache.struts2.interceptor.CheckboxInterceptor" />
+ <interceptor name="datetime" class="org.apache.struts2.interceptor.DateTextFieldInterceptor" />
<interceptor name="profiling" class="org.apache.struts2.interceptor.ProfilingActivationInterceptor" />
<interceptor name="roles" class="org.apache.struts2.interceptor.RolesInterceptor" />
<interceptor name="annotationWorkflow" class="com.opensymphony.xwork2.interceptor.annotations.AnnotationWorkflowInterceptor" />
@@ -198,6 +199,7 @@
<interceptor-ref name="servletConfig"/>
<interceptor-ref name="prepare"/>
<interceptor-ref name="checkbox"/>
+ <interceptor-ref name="datetime"/>
<interceptor-ref name="multiselect"/>
<interceptor-ref name="actionMappingParams"/>
<interceptor-ref name="params">
@@ -255,6 +257,7 @@
<interceptor-ref name="alias"/>
<interceptor-ref name="i18n"/>
<interceptor-ref name="checkbox"/>
+ <interceptor-ref name="datetime"/>
<interceptor-ref name="multiselect"/>
<interceptor-ref name="params">
<param name="excludeParams">^class\..*,^dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,^parameters\..*,^action:.*,^method:.*</param>
@@ -300,6 +303,7 @@
<interceptor-ref name="modelDriven"/>
<interceptor-ref name="fileUpload"/>
<interceptor-ref name="checkbox"/>
+ <interceptor-ref name="datetime"/>
<interceptor-ref name="multiselect"/>
<interceptor-ref name="staticParams"/>
<interceptor-ref name="actionMappingParams"/>
http://git-wip-us.apache.org/repos/asf/struts/blob/9c9d2b5a/core/src/site/resources/tags/datetextfield.html
----------------------------------------------------------------------
diff --git a/core/src/site/resources/tags/datetextfield.html b/core/src/site/resources/tags/datetextfield.html
new file mode 100644
index 0000000..2bfa1fe
--- /dev/null
+++ b/core/src/site/resources/tags/datetextfield.html
@@ -0,0 +1,376 @@
+<!--
+This file is generated during the build by processing Component class annotations.
+Please do not edit it directly.
+-->
+<html>
+ <head>
+ <title>datetextfield</title>
+ </head>
+
+ <body>
+ <h1>Tag Name: datetextfield</h1>
+ <h2>Description</h2>
+ <p>
+ <!-- START SNIPPET: tagdescription -->
+ Render an HTML input fields with the date time
+ <!-- END SNIPPET: tagdescription -->
+ </p>
+
+ <h2>Attributes</h2>
+ <!-- START SNIPPET: tagattributes -->
+ <table width="100%">
+ <tr>
+ <td colspan="6"><h4>Dynamic Attributes Allowed:</h4> true</td>
+ </tr>
+ <tr>
+ <td colspan="6"> </td>
+ </tr>
+ <tr>
+ <th align="left" valign="top"><h4>Name</h4></th>
+ <th align="left" valign="top"><h4>Required</h4></th>
+ <th align="left" valign="top"><h4>Default</h4></th>
+ <th align="left" valign="top"><h4>Evaluated</h4></th>
+ <th align="left" valign="top"><h4>Type</h4></th>
+ <th align="left" valign="top"><h4>Description</h4></th>
+ </tr>
+ <tr>
+ <td align="left" valign="top">accesskey</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top"></td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">String</td>
+ <td align="left" valign="top">Set the html accesskey attribute on rendered html element</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">cssClass</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top"></td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">String</td>
+ <td align="left" valign="top">The css class to use for element</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">cssErrorClass</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top"></td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">String</td>
+ <td align="left" valign="top">The css error class to use for element</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">cssErrorStyle</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top"></td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">String</td>
+ <td align="left" valign="top">The css error style definitions for element to use</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">cssStyle</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top"></td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">String</td>
+ <td align="left" valign="top">The css style definitions for element to use</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">disabled</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top"></td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">String</td>
+ <td align="left" valign="top">Set the html disabled attribute on rendered html element</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">errorPosition</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top"></td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">String</td>
+ <td align="left" valign="top">Define error position of form element (top|bottom)</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">format</td>
+ <td align="left" valign="top"><strong>true</strong></td>
+ <td align="left" valign="top"></td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">String</td>
+ <td align="left" valign="top">Date format attribute</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">id</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top"></td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">String</td>
+ <td align="left" valign="top">HTML id attribute</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">javascriptTooltip</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">Boolean</td>
+ <td align="left" valign="top">Use JavaScript to generate tooltips</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">key</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top"></td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">String</td>
+ <td align="left" valign="top">Set the key (name, value, label) for this particular component</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">label</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top"></td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">String</td>
+ <td align="left" valign="top">Label expression used for rendering an element specific label</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">labelSeparator</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">:</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">String</td>
+ <td align="left" valign="top">String that will be appended to the label</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">labelposition</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top"></td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">String</td>
+ <td align="left" valign="top">Define label position of form element (top/left)</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">name</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top"></td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">String</td>
+ <td align="left" valign="top">The name to set for element</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">onblur</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top"></td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">String</td>
+ <td align="left" valign="top"> Set the html onblur attribute on rendered html element</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">onchange</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top"></td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">String</td>
+ <td align="left" valign="top">Set the html onchange attribute on rendered html element</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">onclick</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top"></td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">String</td>
+ <td align="left" valign="top">Set the html onclick attribute on rendered html element</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">ondblclick</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top"></td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">String</td>
+ <td align="left" valign="top">Set the html ondblclick attribute on rendered html element</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">onfocus</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top"></td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">String</td>
+ <td align="left" valign="top">Set the html onfocus attribute on rendered html element</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">onkeydown</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top"></td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">String</td>
+ <td align="left" valign="top">Set the html onkeydown attribute on rendered html element</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">onkeypress</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top"></td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">String</td>
+ <td align="left" valign="top">Set the html onkeypress attribute on rendered html element</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">onkeyup</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top"></td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">String</td>
+ <td align="left" valign="top">Set the html onkeyup attribute on rendered html element</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">onmousedown</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top"></td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">String</td>
+ <td align="left" valign="top">Set the html onmousedown attribute on rendered html element</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">onmousemove</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top"></td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">String</td>
+ <td align="left" valign="top">Set the html onmousemove attribute on rendered html element</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">onmouseout</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top"></td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">String</td>
+ <td align="left" valign="top">Set the html onmouseout attribute on rendered html element</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">onmouseover</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top"></td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">String</td>
+ <td align="left" valign="top">Set the html onmouseover attribute on rendered html element</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">onmouseup</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top"></td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">String</td>
+ <td align="left" valign="top">Set the html onmouseup attribute on rendered html element</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">onselect</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top"></td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">String</td>
+ <td align="left" valign="top">Set the html onselect attribute on rendered html element</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">requiredLabel</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">Boolean</td>
+ <td align="left" valign="top">If set to true, the rendered element will indicate that input is required</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">requiredPosition</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top"></td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">String</td>
+ <td align="left" valign="top">Define required position of required form element (left|right)</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">tabindex</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top"></td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">String</td>
+ <td align="left" valign="top">Set the html tabindex attribute on rendered html element</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">template</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top"></td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">String</td>
+ <td align="left" valign="top">The template (other than default) to use for rendering the element</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">templateDir</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top"></td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">String</td>
+ <td align="left" valign="top">The template directory.</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">theme</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top"></td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">String</td>
+ <td align="left" valign="top">The theme (other than default) to use for rendering the element</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">title</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top"></td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">String</td>
+ <td align="left" valign="top">Set the html title attribute on rendered html element</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">tooltip</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top"></td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">String</td>
+ <td align="left" valign="top">Set the tooltip of this particular component</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">tooltipConfig</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top"></td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">String</td>
+ <td align="left" valign="top">Deprecated. Use individual tooltip configuration attributes instead.</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">tooltipCssClass</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">StrutsTTClassic</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">String</td>
+ <td align="left" valign="top">CSS class applied to JavaScrip tooltips</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">tooltipDelay</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">Classic</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">String</td>
+ <td align="left" valign="top">Delay in milliseconds, before showing JavaScript tooltips </td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">tooltipIconPath</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top"></td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">String</td>
+ <td align="left" valign="top">Icon path used for image that will have the tooltip</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">value</td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top"></td>
+ <td align="left" valign="top">false</td>
+ <td align="left" valign="top">String</td>
+ <td align="left" valign="top">Preset the value of input element.</td>
+ </tr>
+ </table>
+ <!-- END SNIPPET: tagattributes -->
+ </body>
+</html>
+
http://git-wip-us.apache.org/repos/asf/struts/blob/9c9d2b5a/core/src/test/java/org/apache/struts2/interceptor/DateTextFieldInterceptorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/struts2/interceptor/DateTextFieldInterceptorTest.java b/core/src/test/java/org/apache/struts2/interceptor/DateTextFieldInterceptorTest.java
new file mode 100644
index 0000000..e146239
--- /dev/null
+++ b/core/src/test/java/org/apache/struts2/interceptor/DateTextFieldInterceptorTest.java
@@ -0,0 +1,58 @@
+package org.apache.struts2.interceptor;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.struts2.StrutsInternalTestCase;
+
+import com.opensymphony.xwork2.ActionContext;
+import com.opensymphony.xwork2.mock.MockActionInvocation;
+
+/**
+ * Unit test for DateTextFieldInterceptor.
+ */
+public class DateTextFieldInterceptorTest extends StrutsInternalTestCase {
+
+ private DateTextFieldInterceptor interceptor;
+ private MockActionInvocation ai;
+ private Map<String, Object> param;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ param = new HashMap<String, Object>();
+
+ interceptor = new DateTextFieldInterceptor();
+ ai = new MockActionInvocation();
+ ai.setInvocationContext(ActionContext.getContext());
+ ActionContext.getContext().setParameters(param);
+ }
+
+ public void testNoParam() throws Exception {
+ interceptor.init();
+ interceptor.intercept(ai);
+ interceptor.destroy();
+
+ assertEquals(0, param.size());
+ }
+
+ public void testOneDateTextField() throws Exception {
+ param.put("__year_name", new String[]{"2000"});
+ param.put("__month_name", new String[]{"06"});
+ param.put("__day_name", new String[]{"15"});
+
+ interceptor.init();
+ interceptor.intercept(ai);
+ interceptor.destroy();
+
+ assertFalse(param.containsKey("__year_name"));
+ assertFalse(param.containsKey("__month_name"));
+ assertFalse(param.containsKey("__day_name"));
+ assertTrue(param.containsKey("name"));
+ assertEquals(1, param.size());
+ Date date = new SimpleDateFormat("yyyy-MM-dd").parse("2000-06-15");
+ assertEquals(date, param.get("name"));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/struts/blob/9c9d2b5a/plugins/javatemplates/src/main/java/org/apache/struts2/views/java/simple/DateTextFieldHandler.java
----------------------------------------------------------------------
diff --git a/plugins/javatemplates/src/main/java/org/apache/struts2/views/java/simple/DateTextFieldHandler.java b/plugins/javatemplates/src/main/java/org/apache/struts2/views/java/simple/DateTextFieldHandler.java
new file mode 100644
index 0000000..80aed25
--- /dev/null
+++ b/plugins/javatemplates/src/main/java/org/apache/struts2/views/java/simple/DateTextFieldHandler.java
@@ -0,0 +1,91 @@
+package org.apache.struts2.views.java.simple;
+
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Map;
+
+import org.apache.struts2.interceptor.DateTextFieldInterceptor.DateWord;
+import org.apache.struts2.views.java.Attributes;
+import org.apache.struts2.views.java.TagGenerator;
+
+
+public class DateTextFieldHandler extends AbstractTagHandler implements TagGenerator {
+
+ @SuppressWarnings("unchecked")
+ public void generate() throws IOException {
+ Map<String, Object> params = context.getParameters();
+ Attributes attr = null;
+
+ // Get format
+ String format = (String)params.get("format");
+ String id = (String)params.get("id");
+ String name = (String)params.get("name");
+ if (id == null) {
+ id = name;
+ }
+ Date date = (Date)params.get("nameValue");
+
+ if (format != null) {
+ // Verify if it's correct
+ new SimpleDateFormat(format);
+
+ attr = new Attributes();
+ attr.addIfExists("id", id);
+ super.start("div", attr);
+
+ Character antC = null;
+ for (Character c : format.toCharArray()) {
+
+ try {
+ DateWord dateWord = DateWord.get(c);
+ if (!c.equals(antC)) {
+
+ String cssClass = "date_" + dateWord.getDescription();
+ if (params.get("cssClass") != null) {
+ cssClass += " " + params.get("cssClass");
+ }
+
+ attr = new Attributes();
+ attr.add("type", "text")
+ .addIfExists("class", cssClass)
+ .addIfExists("size", dateWord.getLength())
+ .addIfExists("maxlength", dateWord.getLength())
+ .addIfTrue("disabled", params.get("disabled"))
+ .addIfTrue("readonly", params.get("readonly"))
+ .addIfExists("tabindex", params.get("tabindex"))
+ .addIfExists("style", params.get("cssStyle"))
+ .addIfExists("title", params.get("title"));
+
+ if (id != null && !"".equals(id)) {
+ attr.addDefaultToEmpty("id", "__" + dateWord.getDescription() + "_" + id);
+ }
+ if (name != null && !"".equals(id)) {
+ attr.addDefaultToEmpty("name", "__" + dateWord.getDescription() + "_" + name);
+ } else {
+ attr.addDefaultToEmpty("name", dateWord.getDescription());
+ }
+ if (date != null) {
+ SimpleDateFormat formatter = new SimpleDateFormat(dateWord.getDateType());
+ attr.addIfExists("value", formatter.format(date), false);
+ }
+
+ super.start("input", attr);
+ super.end("input");
+
+ }
+ } catch (IllegalArgumentException e) {
+ super.characters(c.toString());
+ }
+ antC = c;
+
+ }
+ super.end("div");
+ }
+
+ }
+
+
+
+}
+
http://git-wip-us.apache.org/repos/asf/struts/blob/9c9d2b5a/plugins/javatemplates/src/main/java/org/apache/struts2/views/java/simple/SimpleTheme.java
----------------------------------------------------------------------
diff --git a/plugins/javatemplates/src/main/java/org/apache/struts2/views/java/simple/SimpleTheme.java b/plugins/javatemplates/src/main/java/org/apache/struts2/views/java/simple/SimpleTheme.java
index 363717b..4c9ba29 100644
--- a/plugins/javatemplates/src/main/java/org/apache/struts2/views/java/simple/SimpleTheme.java
+++ b/plugins/javatemplates/src/main/java/org/apache/struts2/views/java/simple/SimpleTheme.java
@@ -36,6 +36,7 @@ public class SimpleTheme extends DefaultTheme {
{
put("text", new FactoryList(TextFieldHandler.class, ScriptingEventsHandler.class, CommonAttributesHandler.class, DynamicAttributesHandler.class));
put("textfield", new FactoryList(TextFieldHandler.class, ScriptingEventsHandler.class, CommonAttributesHandler.class, DynamicAttributesHandler.class));
+ put("datetextfield", new FactoryList(DateTextFieldHandler.class, ScriptingEventsHandler.class, CommonAttributesHandler.class));
put("select", new FactoryList(SelectHandler.class, ScriptingEventsHandler.class, CommonAttributesHandler.class, DynamicAttributesHandler.class));
put("form", new FactoryList(FormHandler.class, ScriptingEventsHandler.class, CommonAttributesHandler.class, DynamicAttributesHandler.class));
put("form-close", new FactoryList(FormHandler.CloseHandler.class));
http://git-wip-us.apache.org/repos/asf/struts/blob/9c9d2b5a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/DateTextFieldTest.java
----------------------------------------------------------------------
diff --git a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/DateTextFieldTest.java b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/DateTextFieldTest.java
new file mode 100644
index 0000000..7c03a65
--- /dev/null
+++ b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/DateTextFieldTest.java
@@ -0,0 +1,51 @@
+package org.apache.struts2.views.java.simple;
+
+import org.apache.struts2.components.DateTextField;
+import org.apache.struts2.components.UIBean;
+
+public class DateTextFieldTest extends AbstractCommonAttributesTest {
+
+ private DateTextField tag;
+
+ public void testRenderDateTextField() {
+ tag.setId("id");
+ tag.setName("name");
+ tag.setFormat("yyyy-MM-dd");
+
+ tag.evaluateParams();
+ map.putAll(tag.getParameters());
+ theme.renderTag(getTagName(), context);
+ String output = writer.getBuffer().toString();
+ String expected = s("<div id='id'>" +
+ "<input type='text' class='date_year' size='4' maxlength='4' id='__year_id' name='__year_name'></input>" +
+ "-<input type='text' class='date_month' size='2' maxlength='2' id='__month_id' name='__month_name'></input>" +
+ "-<input type='text' class='date_day' size='2' maxlength='2' id='__day_id' name='__day_name'></input></div>");
+ assertEquals(expected, output);
+ }
+
+ @Override
+ public void testRenderTextFieldScriptingAttrs() throws Exception { }
+
+ @Override
+ public void testRenderTextFieldCommonAttrs() throws Exception { }
+
+ @Override
+ public void testRenderTextFieldDynamicAttrs() throws Exception { }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ this.tag = new DateTextField(stack, request, response);
+ }
+
+ @Override
+ protected UIBean getUIBean() {
+ return tag;
+ }
+
+ @Override
+ protected String getTagName() {
+ return "datetextfield";
+ }
+
+}