I basically figured out how to implement that and here's some interim result.
> > > - Add validation of facets like "maxLength", or "totalDigits"
> > Do you mean just validation or additional support for those facets?
> > Could you point me classes relevant to this mission?
>
> Validating whether the facets are matched. For example, add
>
> if (pFoo.length() > 6) {
> throw new IllegalArgumentException("Length of 6
> characters exceeded: "
> + pFoo);
> }
>
> to setters.
>
> The suggested implementation goes as follows:
>
> - The interface SimpleTypeSG currently has a method:
>
> public JavaMethod getXMLSetMethod(JavaSource,String,String);
>
> The method is mainly implemented by
>
> public JavaMethod
> getXMLSetMethod(SimpleTypeSG,JavaSource,String,String);
>
> Note the additional parameter. See
>
> http://jaxme.sourceforge.net/JaxMeJS/docs/Patterns.html#chains
>
> for the rationale.
>
> - The interface SimpleTypeSG should be extended by another method
>
> /** <p>Generates code verifying whether the parameter
> * <code>pValue</code> of method <code>pMethod</code> is
> * valid. A runtime exception is thrown otherwise. Used
> * to generate the "set" and "add" methods.</p>
> */
> public void addValidation(JavaMethod pMethod,
> DirectAccessible pValue);
>
I added addValidation method to SimpleTypeSG as you said.
> Note that you have to rerun the ant target "precompile" to
> update the
> interface SimpleTypeSGChain.
>
The following generation was successful.
> - Add code to the implementation which invokes the method.
>
> - Implement this method in the various concrete type implementations
> like StringTypeSG, and so on. For examples on how to verify whether
> a facet is set, you can take a look at
> ParserTest.testNegativeInteger()
> and similar methods.
>
>
In this result, I implemented 3 facet validations, maxLength and minLength
in xs:string(StringTypeSG) and totalDigits in xs:integer(IntegerSG)
respectively. First, SimpleTypeSGImpl's getXMLSetMethod was modified and
addValidation are added so that every type source generator may make use of
addValidation customization.
public JavaMethod getXMLSetMethod(SimpleTypeSG pController, JavaSource
pSource,
String pFieldName, String pMethodName)
throws SAXException {
if (pController.hasSetMethod()) {
String pName = "p" + Character.toUpperCase(pFieldName.charAt(0)) +
pFieldName.substring(1);
JavaMethod jm = pSource.newJavaMethod(pMethodName, JavaQNameImpl.VOID,
JavaSource.PUBLIC);
DirectAccessible param = jm.addParam(pController.getRuntimeType(),
pName);
if (!pSource.isInterface()) {
addValidation(pController, jm, param);
jm.addLine(pFieldName, " = ", param, ";");
}
return jm;
} else {
return null;
}
}
public void addValidation(SimpleTypeSG pController, JavaMethod p0,
DirectAccessible p1)
{
}
StringSG's addValidation is following:
public void addValidation(SimpleTypeSG pController, JavaMethod p0,
DirectAccessible p1) {
AtomicTypeSG atomicType = pController.getAtomicType();
Long maxLength = atomicType.getMaxLength();
if (maxLength != null) {
p0.addIf(p1, ".length()", " > ", maxLength);
p0.addThrowNew(IllegalArgumentException.class, "\"Length of " + maxLength +
" characters exceeded: \" + ", p1);
p0.addEndIf();
}
Long minLength = atomicType.getMinLength();
if (minLength != null) {
p0.addIf(p1, ".length()", " < ", minLength);
p0.addThrowNew(IllegalArgumentException.class, "\"Length of " + minLength +
" characters lacked: \" + ", p1);
p0.addEndIf();
}
}
IntegerSG's addValidation is following:
public void addValidation(SimpleTypeSG pController, JavaMethod p0,
DirectAccessible p1) {
AtomicTypeSG atomicType = pController.getAtomicType();
Long totalDigits = atomicType.getTotalDigits();
if (totalDigits != null) {
p0.addIf(p1, ".signum()", " == -1");
p0.addIf(p1, ".toString().length() - 1", " > ",
totalDigits);
p0.addThrowNew(IllegalArgumentException.class,
"\"Length of " + totalDigits + " digits exceeded: \" + ", p1);
p0.addEndIf();
p0.addElse();
p0.addIf(p1, ".toString().length()", " > ",
totalDigits);
p0.addThrowNew(IllegalArgumentException.class,
"\"Length of " + totalDigits + " digits exceeded: \" + ", p1);
p0.addEndIf();
p0.addEndIf();
}
}
I made some changes to Address.xsd to test the above validation codes:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xml:lang="EN"
targetNamespace="http://jaxme.sf.net/examples/misc/address"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
...
<xs:element name="Postal">
...
<xs:element name="ZIP">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="5"/>
</xs:restriction>
</xs:simpleType>
...
<xs:element name="PhoneDetails" minOccurs="0">
...
<xs:element name="PhoneNumber">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:totalDigits value="30"/>
</xs:restriction>
</xs:simpleType>
...
</xs:schema>
The generated AddressTypeImpl turn out that those validation codes are
properly added.
...
public void setZIP(String pZIP) {
if (pZIP.length() > 5) {
throw new IllegalArgumentException("Length of 5 characters exceeded:
" + pZIP);
}
zIP = pZIP;
}
...
public void setPhoneNumber(BigInteger pPhoneNumber) {
if (pPhoneNumber.signum() == -1) {
if (pPhoneNumber.toString().length() - 1 > 30) {
throw new IllegalArgumentException("Length of 30 digits
exceeded: " + pPhoneNumber);
}
} else {
if (pPhoneNumber.toString().length() > 30) {
throw new IllegalArgumentException("Length of 30 digits
exceeded: " + pPhoneNumber);
}
}
phoneNumber = pPhoneNumber;
}
...
In addition, net.sf.jaxme.xs.xml.impl.XsETotalDigitsImpl in JaxMeXS should
be updated because its setValue method omitted super.setValue(pValue);
therefore "missing value" SAXException was thrown in compiling Address.xsd
into Java sources.
Keeping implementing facet validations, I'll go to mission 2 - adding
support for "isSet" methods.
Thanks for your great guidance,
Ias
mission1.zip
Description: Zip compressed data
