Cómo hacer que las clases generadas contengan Javadoc a partir de la documentación del esquema XML
Pregunta
Actualmente estoy trabajando con un esquema XML que tiene <xsd:annotation>
/<xsd:documentation>
en la mayoría de tipos y elementos.Cuando genero Java Beans a partir de este esquema XML, el Javadoc de esos Beans solo contiene información genérica generada sobre el contenido permitido del tipo/elemento.
Me gustaría ver el contenido del <xsd:documentation>
etiqueta en los lugares relevantes (por ejemplo, el contenido de esa etiqueta para un tipo complejo debe aparecer en el Javadoc de la clase generada para representar ese tipo complejo).
¿Hay alguna manera de lograr esto?
Editar:Este esquema XML se utilizará en un WSDL con JAX-WS, por lo que esta etiqueta también podría ser apropiada.
Editar 2:he leído sobre <jxb:javadoc>
.Por lo que tengo entendido, puedo especificar eso en un archivo de enlace JAXB separado o directamente en el esquema XML.Eso casi resolvería mi problema.Pero prefiero usar el existente. <xsd:documentation>
etiqueta, ya que Javadoc no es el objetivo principal de la documentación (es información sobre la estructura de datos principalmente y no sobre los Java Beans generados a partir de ella) y para permitir que herramientas que no sean JAXB también accedan a la información.Aportando la documentación en ambos <jxb:javadoc>
y xsd:documentation>
"Se siente" mal, porque estoy duplicando datos (y trabajo) sin una buena razón.
Editar 3:Gracias a la respuesta de Pascal me di cuenta de que ya tengo media solución:El <xsd:documentation>
de complexType
s está escrito al principio de su Javadoc!El problema sigue siendo que solo eso complexType
s se utiliza y simpleType
s (que también puede dar como resultado una clase) y los elementos aún no tienen Javadoc.
Solución
Nunca he podido colocar xsd:documentation
regularmente en la fuente de Java, excepto si y solo si era un tipo complejo. Documentación para elementos, tipos simples,
etc. son ignorados.
Entonces, termino usando jxb:javadoc
. Para hacerlo, incluya la definición de xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
en su elemento <xsd:schema>
.
Agregue un hijo a <xsd:complexType>
o <xsd: element>
o <xsd:attribute>
:
<xsd:annotation><xsd:appinfo><jxb:XXX><jxb:javadoc>
This is my comment for a class/property
</jxb:javadoc></jxb:XXX></xsd:appinfo></xsd:annotation>
Donde XXX es " clase " o " propiedad " ;.
Para un paquete, escribe un elemento secundario en xsd:schema
<xsd:annotation><xsd:appinfo><jxb:schemaBindings><jxb:package name="com.acme"><jxb:javadoc>
This is my comment for a package
</jxb:javadoc></jxb:package></jxb:schemaBindings></xsd:appinfo></xsd:annotation>
Escribir un documento HTML requiere el uso de corchetes con <![CDATA[ --- ]]>
(EDITAR: mientras escribía mi respuesta, la pregunta fue editada por el OP, así que la actualizo en consecuencia)
En mi caso, javadoc era el único objetivo, por lo que era aceptable usar <=>. Pero su actualización tiene mucho sentido y, de hecho, estoy totalmente de acuerdo con usted. Lamentablemente, nunca encontré una solución ideal para la situación que describe (así que seguiré esta pregunta con mucho cuidado). Tal vez podría usar algo como xframe para generar documentación desde <=>, pero esto no ' t responde la pregunta.
Otros consejos
Esto simplemente no es posible con la implementación de referencia JAXB. Incluso si intentara escribir un complemento XJC, descubriría que la API del complemento no tiene referencia a la definición del esquema, por lo que no hay forma de extraer esta información.
Nuestra única esperanza es que una versión futura de JAXB arregle la situación. Hay una solicitud de función abierta aquí .
Creo que las siguientes técnicas funcionan bastante bien para agregar encabezados JavaDoc a las clases de elementos Java (generadas a partir de esquemas XML). Anido JavaDoc en etiquetas definidas en el espacio de nombres jax-b, anidadas dentro de la anotación de esquema xml y las etiquetas de información de aplicación. Tenga en cuenta que el espacio de nombres jaxb define los tipos de etiquetas de documentación; Yo uso dos de allí: la clase y las etiquetas de propiedad. definido en el siguiente espacio de nombres: xmlns: jxb = " http: //java.sun.com/xml/ns/jaxb "
1) Para documentar una clase, uso un jaxb " class " etiqueta en la siguiente secuencia:
<xs:complexType name="Structure">
<xs:annotation>
<xs:appinfo>
<jxb:class>
<jxb:javadoc>
Documentation text goes here. Since parsing the schema
into Java involves evaluating the xml, I escape all
the tags I use as follows <p> for <p>.
</jxb:javadoc>
</jxb:class>
</xs:appinfo>
</xs:annotation>
.
.
.
</xs:complexType>
2) Para documentar un elemento, uso " propiedad " etiqueta de la siguiente manera:
<xs:element name="description" type="rep:NamedString">
<xs:annotation>
<xs:appinfo>
<jxb:property>
<jxb:javadoc>
<p>Documentation goes here.</p>
</jxb:javadoc>
</jxb:property>
</xs:appinfo>
</xs:annotation>
</xs:element>
3) Uso el mismo conjunto de etiquetas para documentar atributos:
<xs:attribute name="name" type="xs:NCName" use="required">
<xs:annotation>
<xs:appinfo>
<jxb:property>
<jxb:javadoc>
<p>Documentation goes here.</p>
</jxb:javadoc>
</jxb:property>
</xs:appinfo>
</xs:annotation>
</xs:attribute>
4) Para documentar una elección, utilizo la etiqueta de propiedad jaxb, y documento la elección.
<xs:choice maxOccurs="unbounded">
<xs:annotation>
<xs:appinfo>
<jxb:property>
<jxb:javadoc>
<p>Documentation goes here.</p>
</jxb:javadoc>
</jxb:property>
</xs:appinfo>
</xs:annotation>
<xs:element name="value" type="rep:NamedValue" />
<xs:element name="list" type="rep:NamedList" />
<xs:element name="structure" type="rep:NamedStructure" />
</xs:choice>
Intentar documentar las opciones individuales aquí fallaría, ya que esta etiqueta produce una lista sin tipo.
Especialmente para ese caso, escribí el complemento XJC xjc-documentation-annotation-plugin .
Qué hace: <annotation><documentation>
- > Anotaciones de clase Java
Dijo que tenemos este objeto descrito en XSD
:
<xs:complexType name="CadastralBlock">
<xs:annotation>
<xs:documentation>Cadastral quarter</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element name="number" type="xs:string">
<xs:annotation>
<xs:documentation>Cadastral number</xs:documentation>
</xs:annotation>
</xs:element>
</xs:complexType>
Ejecutamos xjc como:
xjc -npa -no-header -d src/main/generated-java/ -p xsd.generated scheme.xsd
Y obtuve una clase como (getters, setters y cualquier anotación omitida por simplicidad):
public class CadastralBlock {
protected String number;
}
¡Pero en mi caso, quiero saber cómo clasificar y los campos se nombraron en el archivo fuente! ¡Entonces, qué hace este complemento!
Entonces obtienes:
@XsdInfo(name = "Cadastral quarter", xsdElementPart = "<complexType name=\"CadastralBlock\">\n <complexContent>\n <restriction base=\"{http://www.w3.org/2001/XMLSchema}anyType\">\n <sequence>\n <element name=\"number\" type=\"{http://www.w3.org/2001/XMLSchema}string\"/></sequence>\n </restriction>\n </complexContent></complexType>")
public class CadastralBlock {
@XsdInfo(name = "Cadastral number")
protected String number;
}
Cómo usar
Llamada manual en línea de comandos
Si desea ejecutarlo manualmente, asegúrese de que la clase jar con el complemento se ejecute en classpath y simplemente agregue la opción -XPluginDescriptionAnnotation
. F.e .:
xjc -npa -no-header -d src/main/generated-java/ -p xsd.generated -XPluginDescriptionAnnotation scheme.xsd
Llamada desde Java / Groovy
Driver.run(
[
'-XPluginDescriptionAnnotation'
,'-d', generatedClassesDir.absolutePath
,'-p', 'info.hubbitus.generated.test'
,'CadastralBlock.xsd'
] as String[]
,new XJCListener() {...}
)
Ver prueba XJCPluginDescriptionAnnotationTest por ejemplo.
Uso de Gradle
Con gradle-xjc-plugin :
plugins {
id 'java'
id 'org.unbroken-dome.xjc' version '1.4.1' // https://github.com/unbroken-dome/gradle-xjc-plugin
}
...
dependencies {
xjcClasspath 'info.hubbitus:xjc-documentation-annotation-plugin:1.0'
}
// Results by default in `build/xjc/generated-sources`
xjcGenerate {
source = fileTree('src/main/resources') { include '*.xsd' }
packageLevelAnnotations = false
targetPackage = 'info.hubbitus.xjc.plugin.example'
extraArgs = [ '-XPluginDescriptionAnnotation' ]
}
Ejemplo gradle
completo en ejemplo -project-gradle directorio del proyecto.