-
Notifications
You must be signed in to change notification settings - Fork 815
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix conversion by annotation and WW-4906 #199
Changes from all commits
faf5018
77cbafb
ff903e7
4394238
9739291
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,6 +26,7 @@ | |
import com.opensymphony.xwork2.conversion.annotations.ConversionType; | ||
import com.opensymphony.xwork2.conversion.annotations.TypeConversion; | ||
import com.opensymphony.xwork2.inject.Inject; | ||
import com.opensymphony.xwork2.util.ClassLoaderUtil; | ||
import org.apache.commons.lang3.StringUtils; | ||
import org.apache.logging.log4j.LogManager; | ||
import org.apache.logging.log4j.Logger; | ||
|
@@ -69,7 +70,7 @@ public void process(Map<String, Object> mapping, TypeConversion tc, String key) | |
mapping.put(key, tc.value()); | ||
} | ||
//for properties of classes | ||
else if (tc.rule() != ConversionRule.ELEMENT || tc.rule() == ConversionRule.KEY || tc.rule() == ConversionRule.COLLECTION) { | ||
else if (tc.rule() != ConversionRule.ELEMENT && tc.rule() != ConversionRule.KEY && tc.rule() != ConversionRule.COLLECTION) { | ||
if (StringUtils.isNoneEmpty(tc.converter())) { | ||
mapping.put(key, converterCreator.createTypeConverter(tc.converter())); | ||
} else { | ||
|
@@ -80,18 +81,22 @@ else if (tc.rule() != ConversionRule.ELEMENT || tc.rule() == ConversionRule.KEY | |
else if (tc.rule() == ConversionRule.KEY) { | ||
Class<?> converterClass; | ||
if (StringUtils.isNoneEmpty(tc.converter())) { | ||
converterClass = Thread.currentThread().getContextClassLoader().loadClass(tc.converter()); | ||
//check if the converter is a type converter if it is one | ||
//then just put it in the map as is. Otherwise | ||
//put a value in for the type converter of the class | ||
converterClass = ClassLoaderUtil.loadClass(tc.converter(), this.getClass()); | ||
} else { | ||
converterClass = tc.converterClass(); | ||
} | ||
|
||
LOG.debug("Converter class: [{}]", converterClass); | ||
|
||
//check if the converter is a type converter if it is one | ||
//then just put it in the map as is. Otherwise | ||
//put a value in for the type converter of the class | ||
if (converterClass.isAssignableFrom(TypeConverter.class)) { | ||
mapping.put(key, converterCreator.createTypeConverter(tc.converter())); | ||
if (StringUtils.isNoneEmpty(tc.converter())) { | ||
mapping.put(key, converterCreator.createTypeConverter(tc.converter())); | ||
} else { | ||
mapping.put(key, converterCreator.createTypeConverter(tc.converterClass())); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I afraid if user e.g. has a spring bean with name "java.lang.String" but with another type than string. In such cases, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure if I understand your example with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks! You're right. Please replace At bottom, I think this was not working already before these and previous changes. Because DefaultObjectTypeDeterminer.getKeyClass always casts it to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
FYI: I knew this piece of code was not working already before these and previous changes. But I just kept it unchanged as maybe I don't know something. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hm... still not sure if I follow (not a Spring fan) but it's safer to keep it as is if you still have some objections and corner cases. |
||
} else { | ||
mapping.put(key, converterClass); | ||
LOG.debug("Object placed in mapping for key [{}] is [{}]", key, mapping.get(key)); | ||
|
@@ -100,7 +105,7 @@ else if (tc.rule() == ConversionRule.KEY) { | |
//elements(values) of maps / lists | ||
else { | ||
if (StringUtils.isNoneEmpty(tc.converter())) { | ||
mapping.put(key, Thread.currentThread().getContextClassLoader().loadClass(tc.converter())); | ||
mapping.put(key, ClassLoaderUtil.loadClass(tc.converter(), this.getClass())); | ||
} else { | ||
mapping.put(key, tc.converterClass()); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -500,15 +500,32 @@ protected void addConverterMapping(Map<String, Object> mapping, Class clazz) { | |
for (Annotation annotation : annotations) { | ||
if (annotation instanceof TypeConversion) { | ||
TypeConversion tc = (TypeConversion) annotation; | ||
if (mapping.containsKey(tc.key())) { | ||
break; | ||
} | ||
String key = tc.key(); | ||
// Default to the property name | ||
// Default to the property name with prefix | ||
if (StringUtils.isEmpty(key)) { | ||
key = AnnotationUtils.resolvePropertyName(method); | ||
switch (tc.rule()) { | ||
case COLLECTION: | ||
key = DefaultObjectTypeDeterminer.DEPRECATED_ELEMENT_PREFIX + key; | ||
break; | ||
case CREATE_IF_NULL: | ||
key = DefaultObjectTypeDeterminer.CREATE_IF_NULL_PREFIX + key; | ||
break; | ||
case ELEMENT: | ||
key = DefaultObjectTypeDeterminer.ELEMENT_PREFIX + key; | ||
break; | ||
case KEY: | ||
key = DefaultObjectTypeDeterminer.KEY_PREFIX + key; | ||
break; | ||
case KEY_PROPERTY: | ||
key = DefaultObjectTypeDeterminer.KEY_PROPERTY_PREFIX + key; | ||
break; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. but in this case it won't be possible to use per property conversion, it will always be prefixed. I think there should be a check There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, it will be prefixed if was empty (i.e. is not specified by user explicitly) and not PROPERTY (i.e. allows per property conversion). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I meant I didn't add all possible cases in |
||
LOG.debug("Retrieved key [{}] from method name [{}]", key, method.getName()); | ||
} | ||
if (mapping.containsKey(key)) { | ||
break; | ||
} | ||
annotationProcessor.process(mapping, tc, key); | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -582,7 +582,7 @@ public void testGetBeanMap() throws Exception { | |
// just do some of the 15 tests | ||
Map beans = ognlUtil.getBeanMap(foo); | ||
assertNotNull(beans); | ||
assertEquals(19, beans.size()); | ||
assertEquals(21, beans.size()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why there is 2 more beans? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added two more beans to Foo to test conversion by annotation and cover all possible usages :) |
||
assertEquals("Hello Santa", beans.get("title")); | ||
assertEquals(new Long("123"), beans.get("ALong")); | ||
assertEquals(new Integer("44"), beans.get("number")); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if I understand this change, we expected
KEY
orCOLLECTION
here but now we handle none of them which means we will handleKEY_PROPERTY
orCREATE_IF_NULL
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a fix for that issue which I discussed at dev list. I suspected it should be wrong because this
else if
then does not require|| tc.rule() == ConversionRule.KEY || tc.rule() == ConversionRule.COLLECTION
because it's always true whentc.rule() != ConversionRule.ELEMENT
! Also, thiselse if
was handling alltc.rule() != ConversionRule.ELEMENT
and execution never reached it's next else if,tc.rule() == ConversionRule.KEY
.So i asked at dev list and your reply directed me that this code is copied from DefaultConversionFileProcessor.java#78. Please see there that a NOT is applied to all statement but the copier of code removed the NOT but did not applied on all but only on first. This is that second issue which is fixed here side by side WW-4906 :)