From issues-return-31982-archive-asf-public=cust-asf.ponee.io@struts.apache.org Fri Mar 16 14:33:14 2018 Return-Path: X-Original-To: archive-asf-public@cust-asf.ponee.io Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx-eu-01.ponee.io (Postfix) with SMTP id E4D36180608 for ; Fri, 16 Mar 2018 14:33:12 +0100 (CET) Received: (qmail 14564 invoked by uid 500); 16 Mar 2018 13:33:11 -0000 Mailing-List: contact issues-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 issues@struts.apache.org Received: (qmail 14554 invoked by uid 99); 16 Mar 2018 13:33:11 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd2-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 16 Mar 2018 13:33:11 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd2-us-west.apache.org (ASF Mail Server at spamd2-us-west.apache.org) with ESMTP id 617BF1A01CC for ; Fri, 16 Mar 2018 13:33:11 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd2-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: -101.511 X-Spam-Level: X-Spam-Status: No, score=-101.511 tagged_above=-999 required=6.31 tests=[KAM_ASCII_DIVIDERS=0.8, RCVD_IN_DNSWL_MED=-2.3, SPF_PASS=-0.001, T_RP_MATCHES_RCVD=-0.01, USER_IN_WHITELIST=-100] autolearn=disabled Received: from mx1-lw-eu.apache.org ([10.40.0.8]) by localhost (spamd2-us-west.apache.org [10.40.0.9]) (amavisd-new, port 10024) with ESMTP id K-Tpi65Twhwj for ; Fri, 16 Mar 2018 13:33:05 +0000 (UTC) Received: from mailrelay1-us-west.apache.org (mailrelay1-us-west.apache.org [209.188.14.139]) by mx1-lw-eu.apache.org (ASF Mail Server at mx1-lw-eu.apache.org) with ESMTP id B50A55F2EC for ; Fri, 16 Mar 2018 13:33:03 +0000 (UTC) Received: from jira-lw-us.apache.org (unknown [207.244.88.139]) by mailrelay1-us-west.apache.org (ASF Mail Server at mailrelay1-us-west.apache.org) with ESMTP id D6779E0358 for ; Fri, 16 Mar 2018 13:33:01 +0000 (UTC) Received: from jira-lw-us.apache.org (localhost [127.0.0.1]) by jira-lw-us.apache.org (ASF Mail Server at jira-lw-us.apache.org) with ESMTP id 40F6521291 for ; Fri, 16 Mar 2018 13:33:01 +0000 (UTC) Date: Fri, 16 Mar 2018 13:33:01 +0000 (UTC) From: "ASF GitHub Bot (JIRA)" To: issues@struts.apache.org Message-ID: In-Reply-To: References: Subject: [jira] [Commented] (WW-685) Generic error message - Type Conversion Error Handling MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-JIRA-FingerPrint: 30527f35849b9dde25b450d4833f0394 [ https://issues.apache.org/jira/browse/WW-685?page=3Dcom.atlassian.jir= a.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=3D16401905= #comment-16401905 ]=20 ASF GitHub Bot commented on WW-685: ----------------------------------- lukaszlenart closed pull request #215: WW-685 Add generic type conversion e= rror message URL: https://github.com/apache/struts/pull/215 =20 =20 =20 This is a PR merged from a forked repository. As GitHub hides the original diff on merge, it is displayed below for the sake of provenance: As this is a foreign pull request (from a fork), the diff is supplied below (as it won't show otherwise due to GitHub magic): diff --git a/core/src/main/java/com/opensymphony/xwork2/ActionContext.java = b/core/src/main/java/com/opensymphony/xwork2/ActionContext.java index 4e4367fcb..34198d1fa 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ActionContext.java +++ b/core/src/main/java/com/opensymphony/xwork2/ActionContext.java @@ -18,6 +18,7 @@ */ package com.opensymphony.xwork2; =20 +import com.opensymphony.xwork2.conversion.impl.ConversionData; import com.opensymphony.xwork2.inject.Container; import com.opensymphony.xwork2.util.ValueStack; import org.apache.struts2.dispatcher.HttpParameters; @@ -192,7 +193,7 @@ public void setContextMap(Map contextMa= p) { * * @param conversionErrors a Map of errors which occurred when executi= ng the action. */ - public void setConversionErrors(Map conversionErrors) = { + public void setConversionErrors(Map conversion= Errors) { put(CONVERSION_ERRORS, conversionErrors); } =20 @@ -202,8 +203,8 @@ public void setConversionErrors(Map con= versionErrors) { * @return the map of conversion errors which occurred when executing = the action or an empty map if * there were no errors. */ - public Map getConversionErrors() { - Map errors =3D (Map) get(CONVERSION_ERRORS); + public Map getConversionErrors() { + Map errors =3D (Map) get(CONVERSION_ERRORS= ); =20 if (errors =3D=3D null) { errors =3D new HashMap<>(); diff --git a/core/src/main/java/com/opensymphony/xwork2/ActionSupport.java = b/core/src/main/java/com/opensymphony/xwork2/ActionSupport.java index 8e57f6d45..a1ef00e47 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ActionSupport.java +++ b/core/src/main/java/com/opensymphony/xwork2/ActionSupport.java @@ -18,6 +18,7 @@ */ package com.opensymphony.xwork2; =20 +import com.opensymphony.xwork2.conversion.impl.ConversionData; import com.opensymphony.xwork2.inject.Container; import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.interceptor.ValidationAware; @@ -131,9 +132,9 @@ public String getText(String key, String defaultValue, = String[] args, ValueStack * @return formatted expr with format specified by key */ public String getFormatted(String key, String expr) { - Map conversionErrors =3D ActionContext.getContext(= ).getConversionErrors(); + Map conversionErrors =3D ActionContext.get= Context().getConversionErrors(); if (conversionErrors.containsKey(expr)) { - String[] vals =3D (String[]) conversionErrors.get(expr); + String[] vals =3D (String[]) conversionErrors.get(expr).getVal= ue(); return vals[0]; } else { final ValueStack valueStack =3D ActionContext.getContext().get= ValueStack(); diff --git a/core/src/main/java/com/opensymphony/xwork2/conversion/impl/Con= versionData.java b/core/src/main/java/com/opensymphony/xwork2/conversion/im= pl/ConversionData.java new file mode 100644 index 000000000..2c3dd5d5f --- /dev/null +++ b/core/src/main/java/com/opensymphony/xwork2/conversion/impl/Conversion= Data.java @@ -0,0 +1,46 @@ +/* + * 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 com.opensymphony.xwork2.conversion.impl; + +public class ConversionData { + private Object value; + private Class toClass; + + public ConversionData() { + } + + public ConversionData(Object value, Class toClass) { + super(); + this.value =3D value; + this.toClass =3D toClass; + } + + public Object getValue() { + return value; + } + public void setValue(Object value) { + this.value =3D value; + } + public Class getToClass() { + return toClass; + } + public void setToClass(Class toClass) { + this.toClass =3D toClass; + } +} diff --git a/core/src/main/java/com/opensymphony/xwork2/conversion/impl/XWo= rkConverter.java b/core/src/main/java/com/opensymphony/xwork2/conversion/im= pl/XWorkConverter.java index 07358887b..96405ff08 100644 --- a/core/src/main/java/com/opensymphony/xwork2/conversion/impl/XWorkConve= rter.java +++ b/core/src/main/java/com/opensymphony/xwork2/conversion/impl/XWorkConve= rter.java @@ -189,7 +189,7 @@ public void setTypeConverterHolder(TypeConverterHolder = converterHolder) { this.converterHolder =3D converterHolder; } =20 - public static String getConversionErrorMessage(String propertyName, Va= lueStack stack) { + public static String getConversionErrorMessage(String propertyName, Cl= ass toClass, ValueStack stack) { LocalizedTextProvider localizedTextProvider =3D ActionContext.getC= ontext().getContainer().getInstance(LocalizedTextProvider.class); String defaultMessage =3D localizedTextProvider.findDefaultText("x= work.default.invalid.fieldvalue", ActionContext.getContext().getLocale(), @@ -201,9 +201,15 @@ public static String getConversionErrorMessage(String = propertyName, ValueStack s =20 propertyName =3D removeAllIndexesInPropertyName(propertyName); =20 - String getTextExpression =3D "getText('" + CONVERSION_ERROR_PROPER= TY_PREFIX + propertyName + "','" + defaultMessage + "')"; + String prefixedPropertyName =3D CONVERSION_ERROR_PROPERTY_PREFIX += propertyName; + String getTextExpression =3D "getText('" + prefixedPropertyName + = "')"; String message =3D (String) stack.findValue(getTextExpression); =20 + if (message =3D=3D null || prefixedPropertyName.equals(message)) { + getTextExpression =3D "getText('" + CONVERSION_ERROR_PROPERTY_= PREFIX + toClass.getName() + "','" + defaultMessage + "')"; + message =3D (String) stack.findValue(getTextExpression); + } + if (message =3D=3D null) { message =3D defaultMessage; } else { @@ -308,7 +314,7 @@ public Object convertValue(Map context,= Object target, Member me return tc.convertValue(context, target, member, property, = value, toClass); } catch (Exception e) { LOG.debug("Unable to convert value using type converter [{= }]", tc.getClass().getName(), e); - handleConversionException(context, property, value, target= ); + handleConversionException(context, property, value, target= , toClass); =20 return TypeConverter.NO_CONVERSION_POSSIBLE; } @@ -320,7 +326,7 @@ public Object convertValue(Map context,= Object target, Member me return defaultTypeConverter.convertValue(context, target, = member, property, value, toClass); } catch (Exception e) { LOG.debug("Unable to convert value using type converter [{= }]", defaultTypeConverter.getClass().getName(), e); - handleConversionException(context, property, value, target= ); + handleConversionException(context, property, value, target= , toClass); =20 return TypeConverter.NO_CONVERSION_POSSIBLE; } @@ -330,7 +336,7 @@ public Object convertValue(Map context,= Object target, Member me return super.convertValue(value, toClass); } catch (Exception e) { LOG.debug("Unable to convert value using type converter [{= }]", super.getClass().getName(), e); - handleConversionException(context, property, value, target= ); + handleConversionException(context, property, value, target= , toClass); =20 return TypeConverter.NO_CONVERSION_POSSIBLE; } @@ -426,7 +432,7 @@ protected Object getConverter(Class clazz, String prope= rty) { return null; } =20 - protected void handleConversionException(Map context, = String property, Object value, Object object) { + protected void handleConversionException(Map context, = String property, Object value, Object object, Class toClass) { if (context !=3D null && (Boolean.TRUE.equals(context.get(REPORT_C= ONVERSION_ERRORS)))) { String realProperty =3D property; String fullName =3D (String) context.get(CONVERSION_PROPERTY_F= ULLNAME); @@ -435,14 +441,14 @@ protected void handleConversionException(Map context, String pro realProperty =3D fullName; } =20 - Map conversionErrors =3D (Map)= context.get(ActionContext.CONVERSION_ERRORS); + Map conversionErrors =3D (Map) context.get(ActionContext.CONVERSION_ERRORS); =20 if (conversionErrors =3D=3D null) { conversionErrors =3D new HashMap<>(); context.put(ActionContext.CONVERSION_ERRORS, conversionErr= ors); } =20 - conversionErrors.put(realProperty, value); + conversionErrors.put(realProperty, new ConversionData(value, t= oClass)); } } =20 diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/Convers= ionErrorInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/inter= ceptor/ConversionErrorInterceptor.java index 2c2113b7e..f2713800f 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/ConversionErro= rInterceptor.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/ConversionErro= rInterceptor.java @@ -20,6 +20,7 @@ =20 import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; +import com.opensymphony.xwork2.conversion.impl.ConversionData; import com.opensymphony.xwork2.conversion.impl.XWorkConverter; import com.opensymphony.xwork2.util.ValueStack; import org.apache.commons.lang3.StringEscapeUtils; @@ -100,17 +101,17 @@ protected String escape(Object value) { public String doIntercept(ActionInvocation invocation) throws Exceptio= n { =20 ActionContext invocationContext =3D invocation.getInvocationContex= t(); - Map conversionErrors =3D invocationContext.getConv= ersionErrors(); + Map conversionErrors =3D invocationContext= .getConversionErrors(); ValueStack stack =3D invocationContext.getValueStack(); =20 HashMap fakie =3D null; =20 - for (Map.Entry entry : conversionErrors.entrySet()= ) { + for (Map.Entry entry : conversionErrors.en= trySet()) { String propertyName =3D entry.getKey(); - Object value =3D entry.getValue(); + ConversionData conversionData =3D entry.getValue(); =20 - if (shouldAddError(propertyName, value)) { - String message =3D XWorkConverter.getConversionErrorMessag= e(propertyName, stack); + if (shouldAddError(propertyName, conversionData.getValue())) { + String message =3D XWorkConverter.getConversionErrorMessag= e(propertyName, conversionData.getToClass(), stack); =20 Object action =3D invocation.getAction(); if (action instanceof ValidationAware) { @@ -122,7 +123,7 @@ public String doIntercept(ActionInvocation invocation) = throws Exception { fakie =3D new HashMap<>(); } =20 - fakie.put(propertyName, getOverrideExpr(invocation, value)= ); + fakie.put(propertyName, getOverrideExpr(invocation, conver= sionData.getValue())); } } =20 diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validator= s/ConversionErrorFieldValidator.java b/core/src/main/java/com/opensymphony/= xwork2/validator/validators/ConversionErrorFieldValidator.java index d24e0269f..3fcf02356 100644 --- a/core/src/main/java/com/opensymphony/xwork2/validator/validators/Conve= rsionErrorFieldValidator.java +++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/Conve= rsionErrorFieldValidator.java @@ -19,6 +19,7 @@ package com.opensymphony.xwork2.validator.validators; =20 import com.opensymphony.xwork2.ActionContext; +import com.opensymphony.xwork2.conversion.impl.ConversionData; import com.opensymphony.xwork2.conversion.impl.XWorkConverter; import com.opensymphony.xwork2.validator.ValidationException; import org.apache.commons.lang3.StringUtils; @@ -70,11 +71,11 @@ public void doValidate(Object object) throws Validation= Exception { String fieldName =3D getFieldName(); String fullFieldName =3D getValidatorContext().getFullFieldName(fi= eldName); ActionContext context =3D ActionContext.getContext(); - Map conversionErrors =3D context.getConversionErro= rs(); + Map conversionErrors =3D context.getConver= sionErrors(); =20 if (conversionErrors.containsKey(fullFieldName)) { if (StringUtils.isBlank(defaultMessage)) { - defaultMessage =3D XWorkConverter.getConversionErrorMessag= e(fullFieldName, context.getValueStack()); + defaultMessage =3D XWorkConverter.getConversionErrorMessag= e(fullFieldName, conversionErrors.get(fullFieldName).getToClass(), context.= getValueStack()); } =20 addFieldError(fieldName, object); diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validator= s/RepopulateConversionErrorFieldValidatorSupport.java b/core/src/main/java/= com/opensymphony/xwork2/validator/validators/RepopulateConversionErrorField= ValidatorSupport.java index 30799215f..501a966b4 100644 --- a/core/src/main/java/com/opensymphony/xwork2/validator/validators/Repop= ulateConversionErrorFieldValidatorSupport.java +++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/Repop= ulateConversionErrorFieldValidatorSupport.java @@ -20,6 +20,7 @@ =20 import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; +import com.opensymphony.xwork2.conversion.impl.ConversionData; import com.opensymphony.xwork2.interceptor.PreResultListener; import com.opensymphony.xwork2.util.ValueStack; import com.opensymphony.xwork2.validator.ValidationException; @@ -155,12 +156,12 @@ public void validate(Object object) throws Validation= Exception { public void repopulateField(Object object) throws ValidationException = { =20 ActionInvocation invocation =3D ActionContext.getContext().getActi= onInvocation(); - Map conversionErrors =3D ActionContext.getContext(= ).getConversionErrors(); + Map conversionErrors =3D ActionContext.get= Context().getConversionErrors(); =20 String fieldName =3D getFieldName(); String fullFieldName =3D getValidatorContext().getFullFieldName(fi= eldName); if (conversionErrors.containsKey(fullFieldName)) { - Object value =3D conversionErrors.get(fullFieldName); + Object value =3D conversionErrors.get(fullFieldName).getValue(= ); =20 final Map fakeParams =3D new LinkedHashMap(); boolean doExprOverride =3D false; diff --git a/core/src/test/java/com/opensymphony/xwork2/ActionContextTest.j= ava b/core/src/test/java/com/opensymphony/xwork2/ActionContextTest.java index 600c61994..ed8f39b31 100644 --- a/core/src/test/java/com/opensymphony/xwork2/ActionContextTest.java +++ b/core/src/test/java/com/opensymphony/xwork2/ActionContextTest.java @@ -18,6 +18,7 @@ */ package com.opensymphony.xwork2; =20 +import com.opensymphony.xwork2.conversion.impl.ConversionData; import com.opensymphony.xwork2.util.ValueStack; import com.opensymphony.xwork2.util.ValueStackFactory; import org.apache.struts2.dispatcher.HttpParameters; @@ -97,11 +98,11 @@ public void testParameters() { } =20 public void testConversionErrors() { - Map errors =3D context.getConversionErrors(); + Map errors =3D context.getConversionErrors= (); assertNotNull(errors); assertEquals(0, errors.size()); =20 - Map errors2 =3D new HashMap<>(); + Map errors2 =3D new HashMap<>(); context.setConversionErrors(errors); assertEquals(errors2, context.getConversionErrors()); } diff --git a/core/src/test/java/com/opensymphony/xwork2/ActionSupportTest.j= ava b/core/src/test/java/com/opensymphony/xwork2/ActionSupportTest.java index 26999f1b5..f712ee74b 100644 --- a/core/src/test/java/com/opensymphony/xwork2/ActionSupportTest.java +++ b/core/src/test/java/com/opensymphony/xwork2/ActionSupportTest.java @@ -18,6 +18,7 @@ */ package com.opensymphony.xwork2; =20 +import com.opensymphony.xwork2.conversion.impl.ConversionData; import com.opensymphony.xwork2.util.ValueStack; =20 import java.util.*; @@ -303,7 +304,7 @@ public void testFormattingSupport() throws Exception { } =20 public void testFormattingSupportWithConversionError() throws Exceptio= n { - ActionContext.getContext().getConversionErrors().put("val", new St= ring[]{"4567def"}); + ActionContext.getContext().getConversionErrors().put("val", new Co= nversionData(new String[]{"4567def"}, Double.class)); ActionContext.getContext().setLocale(new Locale("da")); MyActionSupport mas =3D new MyActionSupport(); container.inject(mas); diff --git a/core/src/test/java/com/opensymphony/xwork2/conversion/impl/Ann= otationXWorkConverterTest.java b/core/src/test/java/com/opensymphony/xwork2= /conversion/impl/AnnotationXWorkConverterTest.java index eb1b0f6d3..d75c6dd5b 100644 --- a/core/src/test/java/com/opensymphony/xwork2/conversion/impl/Annotation= XWorkConverterTest.java +++ b/core/src/test/java/com/opensymphony/xwork2/conversion/impl/Annotation= XWorkConverterTest.java @@ -112,10 +112,10 @@ public void testFieldErrorMessageAddedForComplexPrope= rty() { assertEquals("Conversion should have failed.", OgnlRuntime.NoConve= rsionPossible, converter.convertValue(ognlStackContext, action.getBean(), n= ull, "birth", value, Date.class)); stack.pop(); =20 - Map conversionErrors =3D (Map) stack.getContext().get(ActionContex= t.CONVERSION_ERRORS); + Map conversionErrors =3D (Map) stack.getContext().get(ActionContext.CONVERSION_ERRORS); assertNotNull(conversionErrors); assertTrue(conversionErrors.size() =3D=3D 1); - assertEquals(value, conversionErrors.get("bean.birth")); + assertEquals(value, conversionErrors.get("bean.birth").getValue())= ; } =20 public void testFieldErrorMessageAddedWhenConversionFails() { @@ -132,11 +132,11 @@ public void testFieldErrorMessageAddedWhenConversionF= ails() { assertEquals("Conversion should have failed.", OgnlRuntime.NoConve= rsionPossible, converter.convertValue(ognlStackContext, action, null, "date= ", value, Date.class)); stack.pop(); =20 - Map conversionErrors =3D (Map) ognlStackContext.get(ActionContext.= CONVERSION_ERRORS); + Map conversionErrors =3D (Map) ognlStackContext.get(ActionContext.CONVERSION_ERRORS); assertNotNull(conversionErrors); assertEquals(1, conversionErrors.size()); assertNotNull(conversionErrors.get("date")); - assertEquals(value, conversionErrors.get("date")); + assertEquals(value, conversionErrors.get("date").getValue()); } =20 public void testFieldErrorMessageAddedWhenConversionFailsOnModelDriven= () { @@ -153,11 +153,11 @@ public void testFieldErrorMessageAddedWhenConversionF= ailsOnModelDriven() { stack.pop(); stack.pop(); =20 - Map conversionErrors =3D (Map) ognlStackContext.get(ActionContext.= CONVERSION_ERRORS); + Map conversionErrors =3D (Map) ognlStackContext.get(ActionContext.CONVERSION_ERRORS); assertNotNull(conversionErrors); assertEquals(1, conversionErrors.size()); assertNotNull(conversionErrors.get("birth")); - assertEquals(value, conversionErrors.get("birth")); + assertEquals(value, conversionErrors.get("birth").getValue()); } =20 public void testFindConversionErrorMessage() { @@ -168,11 +168,11 @@ public void testFindConversionErrorMessage() { stack.push(action); stack.push(action.getModel()); =20 - String message =3D XWorkConverter.getConversionErrorMessage("birth= ", stack); + String message =3D XWorkConverter.getConversionErrorMessage("birth= ", Integer.class, stack); assertNotNull(message); assertEquals("Invalid date for birth.", message); =20 - message =3D XWorkConverter.getConversionErrorMessage("foo", stack)= ; + message =3D XWorkConverter.getConversionErrorMessage("foo", Intege= r.class, stack); assertNotNull(message); assertEquals("Invalid field value for field \"foo\".", message); } diff --git a/core/src/test/java/com/opensymphony/xwork2/conversion/impl/XWo= rkConverterTest.java b/core/src/test/java/com/opensymphony/xwork2/conversio= n/impl/XWorkConverterTest.java index 1c4faa3e8..5982cb4a2 100644 --- a/core/src/test/java/com/opensymphony/xwork2/conversion/impl/XWorkConve= rterTest.java +++ b/core/src/test/java/com/opensymphony/xwork2/conversion/impl/XWorkConve= rterTest.java @@ -135,10 +135,10 @@ public void testFieldErrorMessageAddedForComplexPrope= rty() { assertEquals("Conversion should have failed.", OgnlRuntime.NoConve= rsionPossible, converter.convertValue(ognlStackContext, action.getBean(), n= ull, "birth", value, Date.class)); stack.pop(); =20 - Map conversionErrors =3D (Map) stack.getContext().get(ActionContex= t.CONVERSION_ERRORS); + Map conversionErrors =3D (Map) stack.getContext().get(ActionContext.CONVERSION_ERRORS); assertNotNull(conversionErrors); assertTrue(conversionErrors.size() =3D=3D 1); - assertEquals(value, conversionErrors.get("bean.birth")); + assertEquals(value, conversionErrors.get("bean.birth").getValue())= ; } =20 public void testFieldErrorMessageAddedWhenConversionFails() { @@ -154,11 +154,11 @@ public void testFieldErrorMessageAddedWhenConversionF= ails() { assertEquals("Conversion should have failed.", OgnlRuntime.NoConve= rsionPossible, converter.convertValue(ognlStackContext, action, null, "date= ", value, Date.class)); stack.pop(); =20 - Map conversionErrors =3D (Map) ognlStackContext.get(ActionContext.= CONVERSION_ERRORS); + Map conversionErrors =3D (Map) ognlStackContext.get(ActionContext.CONVERSION_ERRORS); assertNotNull(conversionErrors); assertEquals(1, conversionErrors.size()); assertNotNull(conversionErrors.get("date")); - assertEquals(value, conversionErrors.get("date")); + assertEquals(value, conversionErrors.get("date").getValue()); } =20 public void testFieldErrorMessageAddedWhenConversionFailsOnModelDriven= () { @@ -174,11 +174,11 @@ public void testFieldErrorMessageAddedWhenConversionF= ailsOnModelDriven() { stack.pop(); stack.pop(); =20 - Map conversionErrors =3D (Map) ognlStackContext.get(ActionContext.= CONVERSION_ERRORS); + Map conversionErrors =3D (Map) ognlStackContext.get(ActionContext.CONVERSION_ERRORS); assertNotNull(conversionErrors); assertEquals(1, conversionErrors.size()); assertNotNull(conversionErrors.get("birth")); - assertEquals(value, conversionErrors.get("birth")); + assertEquals(value, conversionErrors.get("birth").getValue()); } =20 public void testDateStrictConversion() throws Exception { @@ -208,11 +208,11 @@ public void testFindConversionErrorMessage() { stack.push(action); stack.push(action.getModel()); =20 - String message =3D XWorkConverter.getConversionErrorMessage("birth= ", stack); + String message =3D XWorkConverter.getConversionErrorMessage("birth= ", Integer.class, stack); assertNotNull(message); assertEquals("Invalid date for birth.", message); =20 - message =3D XWorkConverter.getConversionErrorMessage("foo", stack)= ; + message =3D XWorkConverter.getConversionErrorMessage("foo", Intege= r.class, stack); assertNotNull(message); assertEquals("Invalid field value for field \"foo\".", message); } @@ -234,6 +234,83 @@ public void testFindConversionMappingForInterface() { assertEquals(value, b.getTitle() + ":" + b.getSomethingElse()); } =20 + public void testDefaultFieldConversionErrorMessage() { + SimpleAction action =3D new SimpleAction(); + container.inject(action); + + stack.push(action); + + String message =3D XWorkConverter.getConversionErrorMessage("baz",= int.class, stack); + assertNotNull(message); + assertEquals("Invalid field value for field \"baz\".", message); + } + + public void testCustomFieldConversionErrorMessage() { + SimpleAction action =3D new SimpleAction(); + container.inject(action); + + stack.push(action); + + String message =3D XWorkConverter.getConversionErrorMessage("foo",= int.class, stack); + assertNotNull(message); + assertEquals("Custom error message for foo.", message); + } + + public void testCustomPrimitiveConversionErrorMessage() { + SimpleAction action =3D new SimpleAction(); + container.inject(action); + + stack.push(action); + + String message =3D XWorkConverter.getConversionErrorMessage("perce= ntage", double.class, stack); + assertNotNull(message); + assertEquals("Custom error message for double.", message); + } + + public void testCustomClassConversionErrorMessage() { + SimpleAction action =3D new SimpleAction(); + container.inject(action); + + stack.push(action); + + String message =3D XWorkConverter.getConversionErrorMessage("date"= , Date.class, stack); + assertNotNull(message); + assertEquals("Custom error message for java.util.Date.", message); + } + + public void testDefaultIndexedConversionErrorMessage() { + SimpleAction action =3D new SimpleAction(); + container.inject(action); + + stack.push(action); + + String message =3D XWorkConverter.getConversionErrorMessage("beanL= ist[0].name", String.class, stack); + assertNotNull(message); + assertEquals("Invalid field value for field \"beanList[0].name\"."= , message); + } + + public void testCustomIndexedFieldConversionErrorMessage() { + SimpleAction action =3D new SimpleAction(); + container.inject(action); + + stack.push(action); + + String message =3D XWorkConverter.getConversionErrorMessage("beanL= ist[0].count", int.class, stack); + assertNotNull(message); + assertEquals("Custom error message for beanList.count.", message); + } + + public void testCustomIndexedClassConversionErrorMessage() { + SimpleAction action =3D new SimpleAction(); + container.inject(action); + + stack.push(action); + + String message =3D XWorkConverter.getConversionErrorMessage("beanL= ist[0].birth", Date.class, stack); + assertNotNull(message); + assertEquals("Custom error message for java.util.Date.", message); + } + public void testLocalizedDateConversion() throws Exception { Date date =3D new Date(System.currentTimeMillis()); Locale locale =3D Locale.GERMANY; diff --git a/core/src/test/java/com/opensymphony/xwork2/interceptor/Convers= ionErrorInterceptorTest.java b/core/src/test/java/com/opensymphony/xwork2/i= nterceptor/ConversionErrorInterceptorTest.java index 77d533258..9ed6f5db3 100644 --- a/core/src/test/java/com/opensymphony/xwork2/interceptor/ConversionErro= rInterceptorTest.java +++ b/core/src/test/java/com/opensymphony/xwork2/interceptor/ConversionErro= rInterceptorTest.java @@ -21,6 +21,7 @@ import com.mockobjects.dynamic.C; import com.mockobjects.dynamic.Mock; import com.opensymphony.xwork2.*; +import com.opensymphony.xwork2.conversion.impl.ConversionData; import com.opensymphony.xwork2.mock.MockActionInvocation; import com.opensymphony.xwork2.util.ValueStack; =20 @@ -38,13 +39,13 @@ protected ActionContext context; protected ActionInvocation invocation; protected ConversionErrorInterceptor interceptor; - protected Map conversionErrors; + protected Map conversionErrors; protected Mock mockInvocation; protected ValueStack stack; =20 =20 public void testFieldErrorAdded() throws Exception { - conversionErrors.put("foo", 123L); + conversionErrors.put("foo", new ConversionData(123L, int.class)); =20 SimpleAction action =3D new SimpleAction(); mockInvocation.expectAndReturn("getAction", action); @@ -58,7 +59,7 @@ public void testFieldErrorAdded() throws Exception { =20 public void testFieldErrorWithMapKeyAdded() throws Exception { String fieldName =3D "foo['1'].intValue"; - conversionErrors.put(fieldName, "bar"); + conversionErrors.put(fieldName, new ConversionData("bar", int.clas= s)); ActionSupport action =3D new ActionSupport(); mockInvocation.expectAndReturn("getAction", action); stack.push(action); @@ -70,7 +71,7 @@ public void testFieldErrorWithMapKeyAdded() throws Except= ion { } =20 public void testWithPreResultListener() throws Exception { - conversionErrors.put("foo", "Hello"); + conversionErrors.put("foo", new ConversionData("Hello", int.class)= ); =20 ActionContext ac =3D createActionContext(); MockActionInvocation mai =3D createActionInvocation(ac); @@ -93,7 +94,7 @@ public void testWithPreResultListener() throws Exception = { * @throws Exception */ public void testWithPreResultListenerAgainstMaliciousCode() throws Exc= eption { - conversionErrors.put("foo", "\" + #root + \""); + conversionErrors.put("foo", new ConversionData("\" + #root + \"", = int.class)); =20 ActionContext ac =3D createActionContext(); =20 diff --git a/core/src/test/java/com/opensymphony/xwork2/validator/Conversio= nErrorFieldValidatorTest.java b/core/src/test/java/com/opensymphony/xwork2/= validator/ConversionErrorFieldValidatorTest.java index 007b31d79..f36a1aa46 100644 --- a/core/src/test/java/com/opensymphony/xwork2/validator/ConversionErrorF= ieldValidatorTest.java +++ b/core/src/test/java/com/opensymphony/xwork2/validator/ConversionErrorF= ieldValidatorTest.java @@ -23,6 +23,7 @@ import com.opensymphony.xwork2.interceptor.ValidationAware; import com.opensymphony.xwork2.ValidationAwareSupport; import com.opensymphony.xwork2.XWorkTestCase; +import com.opensymphony.xwork2.conversion.impl.ConversionData; import com.opensymphony.xwork2.util.ValueStack; import com.opensymphony.xwork2.validator.validators.ConversionErrorFieldVa= lidator; =20 @@ -50,8 +51,8 @@ public void setUp() throws Exception { ValueStack stack =3D ActionContext.getContext().getValueStack(); ActionContext context =3D new ActionContext(stack.getContext()); =20 - Map conversionErrors =3D new HashMap<>(); - conversionErrors.put("foo", "bar"); + Map conversionErrors =3D new HashMap<>(); + conversionErrors.put("foo", new ConversionData("bar", Integer.clas= s)); context.setConversionErrors(conversionErrors); validator =3D new ConversionErrorFieldValidator(); validationAware =3D new ValidationAwareSupport(); diff --git a/core/src/test/java/com/opensymphony/xwork2/validator/Repopulat= eConversionErrorFieldValidatorSupportTest.java b/core/src/test/java/com/ope= nsymphony/xwork2/validator/RepopulateConversionErrorFieldValidatorSupportTe= st.java index 889dcc841..be49dcddd 100644 --- a/core/src/test/java/com/opensymphony/xwork2/validator/RepopulateConver= sionErrorFieldValidatorSupportTest.java +++ b/core/src/test/java/com/opensymphony/xwork2/validator/RepopulateConver= sionErrorFieldValidatorSupportTest.java @@ -22,6 +22,7 @@ import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.TextProviderFactory; import com.opensymphony.xwork2.XWorkTestCase; +import com.opensymphony.xwork2.conversion.impl.ConversionData; import com.opensymphony.xwork2.mock.MockActionInvocation; import com.opensymphony.xwork2.util.ValueStack; import com.opensymphony.xwork2.validator.validators.RepopulateConversionEr= rorFieldValidatorSupport; @@ -91,9 +92,9 @@ protected void setUp() throws Exception { =09=09ActionContext.getContext().setActionInvocation(invocation); =09=09 =09=09String[] conversionErrorValue =3D new String[] { "some value" }; -=09=09Map conversionErrors =3D ActionContext.getContext().= getConversionErrors(); -=09=09conversionErrors.put("someFieldName", conversionErrorValue); -=09=09conversionErrors.put("xxxsomeFieldName", conversionErrorValue); +=09=09Map conversionErrors =3D ActionContext.getCo= ntext().getConversionErrors(); +=09=09conversionErrors.put("someFieldName", new ConversionData(conversionE= rrorValue, Integer.class)); +=09=09conversionErrors.put("xxxsomeFieldName", new ConversionData(conversi= onErrorValue, Integer.class)); =20 =09=09TextProviderFactory tpf =3D container.getInstance(TextProviderFactor= y.class); =20 diff --git a/core/src/test/java/com/opensymphony/xwork2/validator/VisitorFi= eldValidatorTest.java b/core/src/test/java/com/opensymphony/xwork2/validato= r/VisitorFieldValidatorTest.java index cd66aca2f..62ed2baa2 100644 --- a/core/src/test/java/com/opensymphony/xwork2/validator/VisitorFieldVali= datorTest.java +++ b/core/src/test/java/com/opensymphony/xwork2/validator/VisitorFieldVali= datorTest.java @@ -20,6 +20,8 @@ =20 import com.opensymphony.xwork2.*; import com.opensymphony.xwork2.config.entities.ActionConfig; +import com.opensymphony.xwork2.conversion.impl.ConversionData; + import org.easymock.EasyMock; =20 import java.util.*; @@ -177,8 +179,8 @@ public void testVisitorChildValidation() throws Excepti= on { =20 public void testVisitorChildConversionValidation() throws Exception { //add conversion error - Map conversionErrors =3D new HashMap<>(); - conversionErrors.put("bean.child.count", "bar"); + Map conversionErrors =3D new HashMap<>(); + conversionErrors.put("bean.child.count", new ConversionData("bar",= Integer.class)); ActionContext.getContext().setConversionErrors(conversionErrors); =20 validate("visitorChildValidation"); diff --git a/core/src/test/java/org/apache/struts2/interceptor/StrutsConver= sionErrorInterceptorTest.java b/core/src/test/java/org/apache/struts2/inter= ceptor/StrutsConversionErrorInterceptorTest.java index 6b8c9a670..d7189b868 100644 --- a/core/src/test/java/org/apache/struts2/interceptor/StrutsConversionErr= orInterceptorTest.java +++ b/core/src/test/java/org/apache/struts2/interceptor/StrutsConversionErr= orInterceptorTest.java @@ -24,13 +24,13 @@ import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.ActionSupport; +import com.opensymphony.xwork2.conversion.impl.ConversionData; import com.opensymphony.xwork2.util.ValueStack; import org.apache.struts2.StrutsInternalTestCase; =20 import java.util.HashMap; import java.util.Map; =20 - /** * StrutsConversionErrorInterceptorTest * @@ -39,16 +39,16 @@ =20 protected ActionContext context; protected ActionInvocation invocation; - protected Map conversionErrors; + protected Map conversionErrors; protected Mock mockInvocation; protected ValueStack stack; protected StrutsConversionErrorInterceptor interceptor; =20 =20 public void testEmptyValuesDoNotSetFieldErrors() throws Exception { - conversionErrors.put("foo", 123L); - conversionErrors.put("bar", ""); - conversionErrors.put("baz", new String[]{""}); + conversionErrors.put("foo", new ConversionData("bar", Integer.clas= s)); + conversionErrors.put("bar", new ConversionData("", Integer.class))= ; + conversionErrors.put("baz", new ConversionData(new String[]{""}, I= nteger.class)); =20 ActionSupport action =3D new ActionSupport(); mockInvocation.expectAndReturn("getAction", action); @@ -65,7 +65,7 @@ public void testEmptyValuesDoNotSetFieldErrors() throws E= xception { } =20 public void testFieldErrorAdded() throws Exception { - conversionErrors.put("foo", 123L); + conversionErrors.put("foo", new ConversionData("bar", Integer.clas= s)); =20 ActionSupport action =3D new ActionSupport(); mockInvocation.expectAndReturn("getAction", action); @@ -84,7 +84,7 @@ protected void setUp() throws Exception { invocation =3D (ActionInvocation) mockInvocation.proxy(); stack =3D ActionContext.getContext().getValueStack(); context =3D new ActionContext(stack.getContext()); - conversionErrors =3D new HashMap(); + conversionErrors =3D new HashMap<>(); context.setConversionErrors(conversionErrors); mockInvocation.matchAndReturn("getInvocationContext", context); mockInvocation.expectAndReturn("invoke", Action.SUCCESS); diff --git a/core/src/test/resources/com/opensymphony/xwork2/SimpleAction.p= roperties b/core/src/test/resources/com/opensymphony/xwork2/SimpleAction.pr= operties index af92f350b..f4ca339d8 100644 --- a/core/src/test/resources/com/opensymphony/xwork2/SimpleAction.properti= es +++ b/core/src/test/resources/com/opensymphony/xwork2/SimpleAction.properti= es @@ -19,3 +19,7 @@ foo.range=3DFoo Range Message baz.range=3D${getText(fieldName)} must be greater than ${min} baz=3DBaz Field +invalid.fieldvalue.foo=3DCustom error message for foo. +invalid.fieldvalue.double=3DCustom error message for double. +invalid.fieldvalue.java.util.Date=3DCustom error message for java.util.Dat= e. +invalid.fieldvalue.beanList.count=3DCustom error message for beanList.coun= t. =20 ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on GitHub and use the URL above to go to the specific comment. =20 For queries about this service, please contact Infrastructure at: users@infra.apache.org > Generic error message - Type Conversion Error Handling > ------------------------------------------------------ > > Key: WW-685 > URL: https://issues.apache.org/jira/browse/WW-685 > Project: Struts 2 > Issue Type: Improvement > Reporter: Ricardo Lecheta > Assignee: Aleksandr Mashchenko > Priority: Major > Fix For: 2.6 > > > To change the default message "invalid field value for field "xxx"",=20 > you can put this line in the Action.properties > > invalid.fieldvalue.[propertyName] > But will be useful if there is a way to do a generic custom message to an= y type? For example a custom message for Dates, double, boolean, etc: > > invalid.fieldvalue.For_All_Dates=3DThis is not a valid date. > I don=C2=B4t know how to implement it, but could be like this: > > invalid.fieldvalue.java.lang.Integer=3DThis is not a valid Number. > > invalid.fieldvalue.java.util.Date=3DThis is not a valid Date. > ------------- > I tried the following examples, but them doesn=C2=B4t work: > invalid.fieldvalue.*=3DInvalid Date. > and > invalid.fieldvalue.[*]=3DInvalid Date. -- This message was sent by Atlassian JIRA (v7.6.3#76005)