Reputation: 344
I am trying to find out how to inject a code into a xsd simpleType that is an ennumeration.
My XSD is just like below inside commons.xsd
<xsd:simpleType name="tPessoa">
<xsd:annotation>
<xsd:documentation>Enumeracao que descreve se e uma pessoa fisica ou
juridica
Valores possiveis:
- pf: para PESSOA FiSICA;
- pj: para PESSOA
JURiDICA.
</xsd:documentation>
</xsd:annotation>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="pf" />
<xsd:enumeration value="pj" />
</xsd:restriction>
</xsd:simpleType>
My binding is just like below
<jxb:bindings schemaLocation="../src/main/resources/commons.xsd"
node="//xsd:schema">
<jxb:schemaBindings>
<jxb:package name="my.canonical.commons" />
</jxb:schemaBindings>
<jxb:bindings node="/xsd:schema/xsd:simpleType[@name='tPessoa']">
<ci:code>
public static TPessoa fromValue(String v) {
if(("F".equalsIgnoreCase(v)) || ("PF".equalsIgnoreCase(v))) return PF;
if(("J".equalsIgnoreCase(v)) || ("PJ".equalsIgnoreCase(v))) return PJ;
throw new IllegalArgumentException(v);
}
</ci:code>
</jxb:bindings>
</jxb:bindings>
And I am passing inside the maven plugin the argument -Xinject-code-extension
But the result observed does not changes. I read some articles here in StackOverflow but it is unclear to me if this is a limitation of JAXB or if I am missing something.
My idea is to generate a class just like below
@XmlType(name = "tPessoa")
@XmlEnum
public enum TPessoa {
@XmlEnumValue("pf")
PF("pf"),
@XmlEnumValue("pj")
PJ("pj");
private final String value;
TPessoa(String v) {
value = v;
}
public String value() {
return value;
}
public static TPessoa fromValue(String v) {
if(("F".equalsIgnoreCase(v)) || ("PF".equalsIgnoreCase(v))) return PF;
if(("J".equalsIgnoreCase(v)) || ("PJ".equalsIgnoreCase(v))) return PJ;
throw new IllegalArgumentException(v);
}
}
Because F and PF are synonyms and some underlying systems returns different values for the same entity, some of them returns F others PF and the same behavior for J and PJ.
How to do it? Is it Possible?
Upvotes: 1
Views: 1878
Reputation: 14621
I have never managed to inject code into enumerations in JAXB. I could only inject code into complexTypes.
Below you can find an alternative example which injects the fromValue
method from your question into a complex type and might be useful as well.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.fernandes</groupId>
<artifactId>jaxb-test</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<extension>true</extension>
<schemaDirectory>${basedir}/src/main/xsd</schemaDirectory>
<bindingDirectory>${basedir}/src/main/xjb</bindingDirectory>
<generatePackage>com.fernandes.jaxb</generatePackage>
<args>
<arg>-Xinject-code</arg>
</args>
<plugins>
<plugin>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
<version>1.11.1</version>
</plugin>
</plugins>
</configuration>
</plugin>
</plugins>
</build>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://xmlns.tui.com/int/customer360/cdm/customer/v1"
targetNamespace="http://xmlns.tui.com/int/customer360/cdm/customer/v1"
elementFormDefault="qualified" attributeFormDefault="unqualified">
<xsd:complexType name="pessoaType">
<xsd:sequence>
<xsd:element name="type" type="tPessoa"/>
</xsd:sequence>
</xsd:complexType>
<xsd:simpleType name="tPessoa">
<xsd:annotation>
<xsd:documentation>Enumeracao que descreve se e uma pessoa fisica ou
juridica
Valores possiveis:
- pf: para PESSOA FiSICA;
- pj: para PESSOA
JURiDICA.
</xsd:documentation>
</xsd:annotation>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="pf"/>
<xsd:enumeration value="pj"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
<jxb:bindings version="1.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xmlns:ci="http://jaxb.dev.java.net/plugin/code-injector">
<jxb:bindings schemaLocation="../xsd/schema.xsd">
<jxb:globalBindings>
<xjc:simple/>
</jxb:globalBindings>
<jxb:bindings node="/xsd:schema/xsd:complexType[@name='pessoaType']">
<ci:code>
<![CDATA[
public static TPessoa fromValue(String v) {
if(("F".equalsIgnoreCase(v)) || ("PF".equalsIgnoreCase(v))) return TPessoa.PF;
if(("J".equalsIgnoreCase(v)) || ("PJ".equalsIgnoreCase(v))) return TPessoa.PJ;
throw new IllegalArgumentException(v);
}
]]>
</ci:code>
</jxb:bindings>
</jxb:bindings>
</jxb:bindings>
If you run maven with:
mvn clean package
You will generate the TPessoa
class and a PessoaType
. The latter will contain the static method you specified.
package com.fernandes.jaxb;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlSchemaType;
import javax.xml.bind.annotation.XmlType;
/**
* <p>Java class for pessoaType complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType name="pessoaType">
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="type" type="{http://xmlns.tui.com/int/customer360/cdm/customer/v1}tPessoa"/>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "pessoaType", propOrder = {
"type"
})
public class PessoaType {
@XmlElement(required = true)
@XmlSchemaType(name = "string")
protected TPessoa type;
/**
* Gets the value of the type property.
*
* @return
* possible object is
* {@link TPessoa }
*
*/
public TPessoa getType() {
return type;
}
/**
* Sets the value of the type property.
*
* @param value
* allowed object is
* {@link TPessoa }
*
*/
public void setType(TPessoa value) {
this.type = value;
}
public static TPessoa fromValue(String v) {
if(("F".equalsIgnoreCase(v)) || ("PF".equalsIgnoreCase(v))) return TPessoa.PF;
if(("J".equalsIgnoreCase(v)) || ("PJ".equalsIgnoreCase(v))) return TPessoa.PJ;
throw new IllegalArgumentException(v);
}
}
This is not 100% what you want, but it is pretty close.
Upvotes: 0