-
Notifications
You must be signed in to change notification settings - Fork 825
fix conversion by annotation and WW-4906 #199
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
Conversation
Note: Also will delete CLASS from annotation type because it is already the default value
For easier review, please see all commits together at once , and at one column (not side by side) |
So this PR fixes two issues, right? If so, I would register another ticket in JIRA to cover the second issue. |
@@ -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 comment
The 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 comment
The 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 :)
@@ -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) { |
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
or COLLECTION
here but now we handle none of them which means we will handle KEY_PROPERTY
or CREATE_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 when tc.rule() != ConversionRule.ELEMENT
! Also, this else if
was handling all tc.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 :)
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 comment
The reason will be displayed to describe this comment to others. Learn more.
Instead this if
statement, using converterClass
only should be sufficient
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.
I afraid if user e.g. has a spring bean with name "java.lang.String" but with another type than string. In such cases, converterCreator.createTypeConverter("java.lang.String")
and converterCreator.createTypeConverter(java.lang.String.class)
will have different results :)
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 your example with String.class
- in this place there be only TypeConverter.class
, not a string. The .converter()
value was used above to load a class (line 84), on line 94 we check if the class is TypeConverter.class
and in such case we create the converter. So in both case it must be an instance of TypeConverter
class.
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.
Thanks! You're right. Please replace java.lang.String
with com.opensymphony.xwork2.conversion.TypeConverter
in my above comment. This is an odd thing :) but please consider a spring bean with name "com.opensymphony.xwork2.conversion.TypeConverter"
and that bean type is me.yasser.MyTypeConverter
. In such case, converterCreator.createTypeConverter("com.opensymphony.xwork2.conversion.TypeConverter")
and converterCreator.createTypeConverter(com.opensymphony.xwork2.conversion.TypeConverter.class)
will have different results.
At bottom, I think this was not working already before these and previous changes. Because DefaultObjectTypeDeterminer.getKeyClass always casts it to Class
and will fail at this case when it's TypeConverter
.
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.
At bottom, I think this was not working already before these and previous changes. Because DefaultObjectTypeDeterminer.getKeyClass always casts it to Class and will fail at this case when it's TypeConverter.
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 comment
The 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.
case KEY_PROPERTY: | ||
key = DefaultObjectTypeDeterminer.KEY_PROPERTY_PREFIX + key; | ||
break; | ||
} |
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.
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 mapping,containsKey(propertyName)
that breaks the chain.
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.
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 comment
The reason will be displayed to describe this comment to others. Learn more.
I meant I didn't add all possible cases in switch-case
. My added tests show it works.
assertEquals(MyBean.class.getName(), proxy.getInvocation().getStack().findValue("annotatedBeanList.get(1)").getClass().getName()); | ||
|
||
assertEquals("This is the bla bean by annotation", proxy.getInvocation().getStack().findValue("annotatedBeanList.get(0).name")); | ||
assertEquals(new Long(1234567890), Long.valueOf(proxy.getInvocation().getStack().findValue("annotatedBeanList.get(0).id").toString())); |
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.
new Long
?
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.
I just copied it's above already test lines 😉
assertEquals(2, Integer.parseInt(proxy.getInvocation().getStack().findValue("annotatedBeanMap.size").toString())); | ||
|
||
assertEquals(true, action.getAnnotatedBeanMap().containsKey(1234567890L)); | ||
assertEquals(true, action.getAnnotatedBeanMap().containsKey(1234567891L)); |
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.
I think it would be good to check values of these keys.
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.
I see they are already checked in it's following lines using findValue
:)
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.
hm... findValue()
performs a scan over the stack so it can find other values than expected but I think in this case it's ok.
Thanks! To document second fix, I created WW-4908. I hope this PR did not confuse you. The fix itself is small as I only made a few changes into only two main files, |
LGTM 👍 |
No description provided.