Return-Path: X-Original-To: apmail-struts-commits-archive@minotaur.apache.org Delivered-To: apmail-struts-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id C6F1510E8F for ; Thu, 27 Mar 2014 18:42:53 +0000 (UTC) Received: (qmail 41141 invoked by uid 500); 27 Mar 2014 18:42:53 -0000 Delivered-To: apmail-struts-commits-archive@struts.apache.org Received: (qmail 41060 invoked by uid 500); 27 Mar 2014 18:42:51 -0000 Mailing-List: contact commits-help@struts.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@struts.apache.org Delivered-To: mailing list commits@struts.apache.org Received: (qmail 41040 invoked by uid 99); 27 Mar 2014 18:42:50 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 27 Mar 2014 18:42:49 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id BF658894BC3; Thu, 27 Mar 2014 18:42:49 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: lukaszlenart@apache.org To: commits@struts.apache.org Date: Thu, 27 Mar 2014 18:42:50 -0000 Message-Id: <9f992ddd14ff4fcea78b3ced42c03b44@git.apache.org> In-Reply-To: <18276a75e1b844b4a51303ad3a9e20af@git.apache.org> References: <18276a75e1b844b4a51303ad3a9e20af@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [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 Authored: Thu Mar 27 19:42:35 2014 +0100 Committer: Lukasz Lenart 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 parameters = ai.getInvocationContext().getParameters(); + Set> entries = parameters.entrySet(); + Map> dates = new HashMap>(); + + DateWord[] dateWords = DateWord.getAll(); + + // Get all the values of date type + for (Iterator> iterator = entries.iterator(); iterator.hasNext();) { + Entry 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 map = dates.get(name); + if (map == null) { + map = new HashMap(); + dates.put(name, map); + } + map.put(dateWord.getDateType(), values[0]); + } + } + break; + } + } + } + + // Create all the date objects + Map newParams = new HashMap(); + Set>> dateEntries = dates.entrySet(); + for (Entry> dateEntry : dateEntries) { + Set> dateFormatEntries = dateEntry.getValue().entrySet(); + String dateFormat = ""; + String dateValue = ""; + for (Entry 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 @@ + @@ -198,6 +199,7 @@ + @@ -255,6 +257,7 @@ + ^class\..*,^dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,^parameters\..*,^action:.*,^method:.* @@ -300,6 +303,7 @@ + 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 @@ + + + + datetextfield + + + +

Tag Name: datetextfield

+

Description

+

+ + Render an HTML input fields with the date time + +

+ +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Dynamic Attributes Allowed:

true
 

Name

Required

Default

Evaluated

Type

Description

accesskeyfalsefalseStringSet the html accesskey attribute on rendered html element
cssClassfalsefalseStringThe css class to use for element
cssErrorClassfalsefalseStringThe css error class to use for element
cssErrorStylefalsefalseStringThe css error style definitions for element to use
cssStylefalsefalseStringThe css style definitions for element to use
disabledfalsefalseStringSet the html disabled attribute on rendered html element
errorPositionfalsefalseStringDefine error position of form element (top|bottom)
formattruefalseStringDate format attribute
idfalsefalseStringHTML id attribute
javascriptTooltipfalsefalsefalseBooleanUse JavaScript to generate tooltips
keyfalsefalseStringSet the key (name, value, label) for this particular component
labelfalsefalseStringLabel expression used for rendering an element specific label
labelSeparatorfalse:falseStringString that will be appended to the label
labelpositionfalsefalseStringDefine label position of form element (top/left)
namefalsefalseStringThe name to set for element
onblurfalsefalseString Set the html onblur attribute on rendered html element
onchangefalsefalseStringSet the html onchange attribute on rendered html element
onclickfalsefalseStringSet the html onclick attribute on rendered html element
ondblclickfalsefalseStringSet the html ondblclick attribute on rendered html element
onfocusfalsefalseStringSet the html onfocus attribute on rendered html element
onkeydownfalsefalseStringSet the html onkeydown attribute on rendered html element
onkeypressfalsefalseStringSet the html onkeypress attribute on rendered html element
onkeyupfalsefalseStringSet the html onkeyup attribute on rendered html element
onmousedownfalsefalseStringSet the html onmousedown attribute on rendered html element
onmousemovefalsefalseStringSet the html onmousemove attribute on rendered html element
onmouseoutfalsefalseStringSet the html onmouseout attribute on rendered html element
onmouseoverfalsefalseStringSet the html onmouseover attribute on rendered html element
onmouseupfalsefalseStringSet the html onmouseup attribute on rendered html element
onselectfalsefalseStringSet the html onselect attribute on rendered html element
requiredLabelfalsefalsefalseBooleanIf set to true, the rendered element will indicate that input is required
requiredPositionfalsefalseStringDefine required position of required form element (left|right)
tabindexfalsefalseStringSet the html tabindex attribute on rendered html element
templatefalsefalseStringThe template (other than default) to use for rendering the element
templateDirfalsefalseStringThe template directory.
themefalsefalseStringThe theme (other than default) to use for rendering the element
titlefalsefalseStringSet the html title attribute on rendered html element
tooltipfalsefalseStringSet the tooltip of this particular component
tooltipConfigfalsefalseStringDeprecated. Use individual tooltip configuration attributes instead.
tooltipCssClassfalseStrutsTTClassicfalseStringCSS class applied to JavaScrip tooltips
tooltipDelayfalseClassicfalseStringDelay in milliseconds, before showing JavaScript tooltips
tooltipIconPathfalsefalseStringIcon path used for image that will have the tooltip
valuefalsefalseStringPreset the value of input element.
+ + + + 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 param; + + protected void setUp() throws Exception { + super.setUp(); + param = new HashMap(); + + 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 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("
" + + "" + + "-" + + "-
"); + 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"; + } + +}