krasa / krasa-jaxb-tools

XJC / JAXB plugin for generation of Bean Validation Annotations (JSR-303) and replacing primitive types
Apache License 2.0
60 stars 49 forks source link

Krasa - JAXB : Wrong @Digit validation attribute with totalDigits & fractionDigits (XSD) #40

Closed akumar11 closed 8 years ago

akumar11 commented 9 years ago

The converted JAXB target Bean using Krasa, is producing wrong @Digit validation attributes.

The Simple Type is :

<simpleType name="max11DecVal">
    <restriction base="decimal">
        <totalDigits value="11" />
        <fractionDigits value="10" />
    </restriction>
</simpleType>

The Genrated JAVA Bean property with validation is:

@XmlElement(required = true) @Generated(value = "com.sun.tools.xjc.Driver", date = "2015-10-26T05:40:39+05:30", comments = "JAXB RI v2.2.11") @NotNull @Digits(integer = 1, fraction = 10) protected BigDecimal someProp;

The problem is :

ACTUAL Generation : @Digits(integer = 1, fraction = 10) (the integer attribute is always coming the difference i.e 11-10 =1, which is not right) It SHOULD BE : @Digits(integer = 11, fraction = 10) (integer should be the totalDigits which is 11 as stated in XSD)

I am using below options in my pom.xml to genrate JAVA classes from XSD :

                  <extraargs>
                        <extraarg>-fe</extraarg>
                        <extraarg>jaxws21</extraarg>
                        <extraarg>-xjc-Xts</extraarg>
                        <extraarg>-xjc-Xfluent-api</extraarg>
                        <extraarg>-xjc-mark-generated</extraarg>
                        <extraarg>-verbose</extraarg>
                        <extraarg>-xjc-Xvalue-constructor</extraarg>
                        <extraarg>-xjc-Xannotate</extraarg>
                        <extraarg>-xjc-Xequals</extraarg>
                        <extraarg>-xjc-XhashCode</extraarg>
                        <extraarg>-xjc-Xcopyable</extraarg>
                        <extraarg>-xjc-Xmergeable</extraarg>
                        <extraarg>-xjc-XJsr303Annotations</extraarg>

                    </extraargs>

Please help to resolve the issue, or advice if I am missing something in the above extra arguments.

davidkarlsen commented 9 years ago

https://www.safaribooksonline.com/library/view/xml-schema/0596002521/re52.html " Description xs:totalDigits defines the maximum number of digits of decimal and derived datatypes (both after and before the decimal point, not counting the decimal point itself).

This facet constrains the value space, which means that the number of digits is checked after the value is transformed to its canonical form and the leading and trailing zeros are removed. "

Another example here: http://zvon.org/xxl/XMLSchemaTutorial/Output/ser_types_st3.html With 10 reserved for the fractional part, that should leave 1 for the whole number part? Which seems to match the generated code?

mcmoulis commented 9 years ago

<simpleType name="decimalType"> <restriction base="decimal"> <totalDigits value="3"/> <fractionDigits value="2"/> </restriction> </simpleType> Valid 123 123.0 123.000 12.3 1.23

Invalid 0.123 12.34 123.1

When decimals are not present then integral part is allowed to have number of digits as 'totalDigits' as per schema. But generated annotation is not going to do that if integer is (totalDigits - fractionDigits) instead totalDigits.

mcmoulis commented 9 years ago

Digits supporting "total" (optional) along with integer and fraction will be helpful! But it wont come in the scope of this forum probably.

So even it's not exact fix it's good if we would have Digits:integer as decimal:totalDigits from schema definition?

davidkarlsen commented 9 years ago

If you can provide a github project demoing the issue I could attempt to fix with a pull-request. Demo including: minimal schema generated bean showing xsd validation passes and hibnerate validator does not or vice versa

akumar11 commented 8 years ago

@davidkarlsen : The github sample for above issue is available at https://github.com/akumar11/KrasaSample

davidkarlsen commented 8 years ago

@akumar11 Actually there seems to be an error with the test itself - when I fixed the filepaths all tests pass: https://github.com/akumar11/KrasaSample/pulls

mcmoulis commented 8 years ago

By changing (correcting) test case com.test.krasa.XsdObjectValidateTest.testXsdObject we can see bug.

Modify line assertEquals(Boolean.FALSE, validateBean(travelInfoData3).isEmpty()); to assertEquals(Boolean.TRUE, validateBean(travelInfoData3).isEmpty()); then there is failure.

akumar11 commented 8 years ago

@davidkarlsen : I prepared the above sample as per Windows Environment. However, you can see @Digits validation failure by changing the assertion (line#85) from Boolean.FALSE to Boolean.TRUE ( @mcmoulis explained this well in above comment ) .

mcmoulis commented 8 years ago

Any comments/inputs?

krasa commented 8 years ago

Should I take a look? :-)

davidkarlsen commented 8 years ago

@krasa That would be great - I never came along for it.

davidkarlsen commented 8 years ago

@krasa Did you figure anything out?

krasa commented 8 years ago

Well, I agree that there is a bug :-)

I think the best would be to introduce a custom annotation+validator. That would require the plugin to be used also as a compile+runtime dependency (or make a new runtime library for just that, but that would be much more work). And @Digits should not be used when there are fractionDigits in xsd.

davidkarlsen commented 8 years ago

@krasa Could we not simply apply some simple arithmetics? When defining totalDigits and fractionDigits in the xsd world, leaving total-fraction=integer in the jsr303 world? http://zvon.org/xxl/XMLSchemaTutorial/Output/ser_types_st3.html http://docs.oracle.com/javaee/6/api/javax/validation/constraints/Digits.html

davidkarlsen commented 8 years ago

aha - I see it now - that's actually what is happening - but leaves no space for the integral part when in fact no fraction digits are present

davidkarlsen commented 8 years ago

Super - this issue can be closed and put in the 1.4 milestone! Thanks a lot!