From issues-return-32098-archive-asf-public=cust-asf.ponee.io@struts.apache.org Mon May 21 07:25:10 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 7CBD2180679 for ; Mon, 21 May 2018 07:25:09 +0200 (CEST) Received: (qmail 28569 invoked by uid 500); 21 May 2018 05:25:07 -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 28553 invoked by uid 99); 21 May 2018 05:25:07 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd4-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 21 May 2018 05:25:07 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd4-us-west.apache.org (ASF Mail Server at spamd4-us-west.apache.org) with ESMTP id E168EC0575 for ; Mon, 21 May 2018 05:25:06 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd4-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: -109.511 X-Spam-Level: X-Spam-Status: No, score=-109.511 tagged_above=-999 required=6.31 tests=[ENV_AND_HDR_SPF_MATCH=-0.5, KAM_ASCII_DIVIDERS=0.8, RCVD_IN_DNSWL_MED=-2.3, SPF_PASS=-0.001, T_RP_MATCHES_RCVD=-0.01, USER_IN_DEF_SPF_WL=-7.5, USER_IN_WHITELIST=-100] autolearn=disabled Received: from mx1-lw-eu.apache.org ([10.40.0.8]) by localhost (spamd4-us-west.apache.org [10.40.0.11]) (amavisd-new, port 10024) with ESMTP id 2xXsvGEcp-AL for ; Mon, 21 May 2018 05:25:03 +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 C6CF75F58C for ; Mon, 21 May 2018 05:25:02 +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 96B1CE0F2B for ; Mon, 21 May 2018 05:25: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 BC75A217AD for ; Mon, 21 May 2018 05:25:00 +0000 (UTC) Date: Mon, 21 May 2018 05:25:00 +0000 (UTC) From: "ASF GitHub Bot (JIRA)" To: issues@struts.apache.org Message-ID: In-Reply-To: References: Subject: [jira] [Commented] (WW-4932) Conversion fails when generic type is an interface 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-4932?page=3Dcom.atlassian.ji= ra.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=3D1648220= 7#comment-16482207 ]=20 ASF GitHub Bot commented on WW-4932: ------------------------------------ lukaszlenart closed pull request #221: WW-4932 honor .properties file befo= re the generic parametrics URL: https://github.com/apache/struts/pull/221 =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/conversion/impl/Def= aultObjectTypeDeterminer.java b/core/src/main/java/com/opensymphony/xwork2/= conversion/impl/DefaultObjectTypeDeterminer.java index c375ce147..2ef75e88c 100644 --- a/core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultObj= ectTypeDeterminer.java +++ b/core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultObj= ectTypeDeterminer.java @@ -75,11 +75,11 @@ public DefaultObjectTypeDeterminer(@Inject XWorkConvert= er converter, @Inject Ref =20 /** * Determines the key class by looking for the value of @Key annotatio= n for the given class. - * If no annotation is found, the key class is determined by using the= generic parametrics. - * - * As fallback, it determines the key class by looking for the value o= f Key_${property} in the properties + * If no annotation is found, it determines the key class by looking f= or the value of Key_${property} in the properties * file for the given class. * + * As fallback, the key class is determined by using the generic param= etrics. + * * @param parentClass the Class which contains as a property the Map o= r Collection we are finding the key for. * @param property the property of the Map or Collection for the gi= ven parent class * @see com.opensymphony.xwork2.conversion.ObjectTypeDeterminer#getKey= Class(Class, String) @@ -89,21 +89,21 @@ public Class getKeyClass(Class parentClass, String prop= erty) { if (annotation !=3D null) { return annotation.value(); } - Class clazz =3D getClass(parentClass, property, false); + Class clazz =3D (Class) xworkConverter.getConverter(parentClass, K= EY_PREFIX + property); if (clazz !=3D null) { return clazz; } - return (Class) xworkConverter.getConverter(parentClass, KEY_PREFIX= + property); + return getClass(parentClass, property, false); } =20 /** * Determines the element class by looking for the value of @Element a= nnotation for the given * class. - * If no annotation is found, the element class is determined by using= the generic parametrics. - * - * As fallback, it determines the key class by looking for the value o= f Element_${property} in the properties + * If no annotation is found, it determines the key class by looking f= or the value of Element_${property} in the properties * file for the given class. Also looks for the deprecated Collection_= ${property} * + * As fallback, the element class is determined by using the generic p= arametrics. + * * @param parentClass the Class which contains as a property the Map o= r Collection we are finding the key for. * @param property the property of the Map or Collection for the gi= ven parent class * @see com.opensymphony.xwork2.conversion.ObjectTypeDeterminer#getEle= mentClass(Class, String, Object) @@ -113,17 +113,17 @@ public Class getElementClass(Class parentClass, Strin= g property, Object key) { if (annotation !=3D null) { return annotation.value(); } - Class clazz =3D getClass(parentClass, property, true); - if (clazz !=3D null) { - return clazz; - } - clazz =3D (Class) xworkConverter.getConverter(parentClass, ELEMENT= _PREFIX + property); + Class clazz =3D (Class) xworkConverter.getConverter(parentClass, E= LEMENT_PREFIX + property); if (clazz =3D=3D null) { clazz =3D (Class) xworkConverter.getConverter(parentClass, DEP= RECATED_ELEMENT_PREFIX + property); if (clazz !=3D null) { LOG.info("The Collection_xxx pattern for collection type c= onversion is deprecated. Please use Element_xxx!"); } } + if (clazz !=3D null) { + return clazz; + } + clazz =3D getClass(parentClass, property, true); return clazz; } =20 diff --git a/core/src/test/java/com/opensymphony/xwork2/ognl/OgnlUtilTest.j= ava b/core/src/test/java/com/opensymphony/xwork2/ognl/OgnlUtilTest.java index dec0cc0ff..87578a7a3 100644 --- a/core/src/test/java/com/opensymphony/xwork2/ognl/OgnlUtilTest.java +++ b/core/src/test/java/com/opensymphony/xwork2/ognl/OgnlUtilTest.java @@ -582,7 +582,7 @@ public void testGetBeanMap() throws Exception { // just do some of the 15 tests Map beans =3D ognlUtil.getBeanMap(foo); assertNotNull(beans); - assertEquals(21, beans.size()); + assertEquals(22, beans.size()); assertEquals("Hello Santa", beans.get("title")); assertEquals(new Long("123"), beans.get("ALong")); assertEquals(new Integer("44"), beans.get("number")); diff --git a/core/src/test/java/com/opensymphony/xwork2/ognl/OgnlValueStack= Test.java b/core/src/test/java/com/opensymphony/xwork2/ognl/OgnlValueStackT= est.java index 012122085..514b31325 100644 --- a/core/src/test/java/com/opensymphony/xwork2/ognl/OgnlValueStackTest.ja= va +++ b/core/src/test/java/com/opensymphony/xwork2/ognl/OgnlValueStackTest.ja= va @@ -733,6 +733,14 @@ public void testSetNullList() { assertEquals("Cat One", ((Cat) foo.getCats().get(0)).getName()); assertEquals("Cat Two", ((Cat) foo.getCats().get(1)).getName()); =20 + //test when both Key and Value types of Map are interfaces but con= crete classes are defined in .properties file + vs.setValue("animalMap[3].name", "Cat Three by interface"); + vs.setValue("animalMap[6].name", "Cat Six by interface"); + assertNotNull(foo.getAnimalMap()); + assertEquals(2, foo.getAnimalMap().size()); + assertEquals("Cat Three by interface", foo.getAnimalMap().get(new = Long(3)).getName()); + assertEquals("Cat Six by interface", foo.getAnimalMap().get(new Lo= ng(6)).getName()); + vs.setValue("annotatedCats[0].name", "Cat One By Annotation"); vs.setValue("annotatedCats[1].name", "Cat Two By Annotation"); assertNotNull(foo.getAnnotatedCats()); diff --git a/core/src/test/java/com/opensymphony/xwork2/util/Animal.java b/= core/src/test/java/com/opensymphony/xwork2/util/Animal.java new file mode 100644 index 000000000..cc26a4524 --- /dev/null +++ b/core/src/test/java/com/opensymphony/xwork2/util/Animal.java @@ -0,0 +1,23 @@ +/* + * 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.util; + +public interface Animal { + String getName(); +} diff --git a/core/src/test/java/com/opensymphony/xwork2/util/Cat.java b/cor= e/src/test/java/com/opensymphony/xwork2/util/Cat.java index 626c78b8e..2ebdd136a 100644 --- a/core/src/test/java/com/opensymphony/xwork2/util/Cat.java +++ b/core/src/test/java/com/opensymphony/xwork2/util/Cat.java @@ -26,7 +26,7 @@ * @author $Author$ * @version $Revision$ */ -public class Cat { +public class Cat implements Animal { =20 public static final String SCIENTIFIC_NAME =3D "Feline"; =20 diff --git a/core/src/test/java/com/opensymphony/xwork2/util/Foo.java b/cor= e/src/test/java/com/opensymphony/xwork2/util/Foo.java index b14270a2e..f8b67c71a 100644 --- a/core/src/test/java/com/opensymphony/xwork2/util/Foo.java +++ b/core/src/test/java/com/opensymphony/xwork2/util/Foo.java @@ -53,6 +53,7 @@ long aLong; Calendar calendar; BarJunior barJunior; + Map animalMap; =20 public BarJunior getBarJunior() { return barJunior; @@ -242,5 +243,13 @@ public Calendar getCalendar() { =20 public void setCalendar(Calendar calendar) { this.calendar =3D calendar; - } =20 + } + + public Map getAnimalMap() { + return animalMap; + } + + public void setAnimalMap(Map animalMap) { + this.animalMap =3D animalMap; + } } diff --git a/core/src/test/java/com/opensymphony/xwork2/util/MyNumber.java = b/core/src/test/java/com/opensymphony/xwork2/util/MyNumber.java new file mode 100644 index 000000000..218747234 --- /dev/null +++ b/core/src/test/java/com/opensymphony/xwork2/util/MyNumber.java @@ -0,0 +1,22 @@ +/* + * 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.util; + +abstract class MyNumber extends Number { +} diff --git a/core/src/test/resources/com/opensymphony/xwork2/util/Foo-conve= rsion.properties b/core/src/test/resources/com/opensymphony/xwork2/util/Foo= -conversion.properties index 945f69e2c..b4960c4c1 100644 --- a/core/src/test/resources/com/opensymphony/xwork2/util/Foo-conversion.p= roperties +++ b/core/src/test/resources/com/opensymphony/xwork2/util/Foo-conversion.p= roperties @@ -26,4 +26,5 @@ KeyProperty_barCollection=3Did Element_barCollection=3Dcom.opensymphony.xwork2.util.Bar KeyProperty_barList=3Did Element_barList=3Dcom.opensymphony.xwork2.util.Bar - +Key_animalMap=3Djava.lang.Long +Element_animalMap=3Dcom.opensymphony.xwork2.util.Cat =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 > Conversion fails when generic type is an interface > -------------------------------------------------- > > Key: WW-4932 > URL: https://issues.apache.org/jira/browse/WW-4932 > Project: Struts 2 > Issue Type: Improvement > Components: Other > Reporter: Nuno Oliveira > Assignee: Yasser Zamani > Priority: Minor > Fix For: 2.6 > > > Hi, I was asked to create this issue after exchanging some emails in the = struts mailing list. > I had the following problem: > {noformat} > Hi, > I am having problems populating an action variable Set by request using > struts type conversion if the Set has the element type defined as an > interface. > I have a UserAction-conversion.properties file with the following > configuration using the class implementation: > KeyProperty_roles=3Did > Element_roles=3Dpath.to.class.Roles > CreateIfNull_roles=3Dtrue > And UserAction has the collection Set. Roles obviously > implements RolesInterface. > If the Set element type is deleted it works just fine. > Am I doing something wrong or is this not possible? > Thanks{noformat} > And this was the response, which fixed my problem. : > {noformat} > I reproduced it and seems it's because it tries to instantiate a new > element but the interface cannot being instantiated. Please see [1] to > know why it tries to instantiate interface instead of class. > Annotating the getRoles or setRoles method with @Element(value =3D > path.to.class.Roles.class) may fix this issue. (shouldn't it be > path.to.class.Role instead? it seems Roles is a list not element) > Regards. > [1] > github.com/apache/struts/blob/05829e3faadd15cfa67eb234cd1775f2b98918cb/co= re/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultObjectTypeD= eterminer.java#L100{noformat} > After acknowledging the issue is fixed, the fix suggestion: > {noformat} > You're welcome :) glad to hear this. However, I think it's better that > Struts honor .properties file (where element class has been defined > strictly by user) before the generic parametrics [1]. Could you please > register an issue at [2] with title "conversion fails when generic type > is an interface" then paste these emails contents in it's description. > Thanks for your report! > [1] > github.com/apache/struts/blob/05829e3faadd15cfa67eb234cd1775f2b98918cb/co= re/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultObjectTypeD= eterminer.java#L100 > [2] issues.apache.org/jira/projects/WW/ > {noformat} > =C2=A0 -- This message was sent by Atlassian JIRA (v7.6.3#76005)