Cómo hacer que las clases generadas contengan Javadoc a partir de la documentación del esquema XML

StackOverflow https://stackoverflow.com/questions/1650249

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 complexTypes está escrito al principio de su Javadoc!El problema sigue siendo que solo eso complexTypes se utiliza y simpleTypes (que también puede dar como resultado una clase) y los elementos aún no tienen Javadoc.

¿Fue útil?

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 &lt;p&gt; 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>
                      &lt;p&gt;Documentation goes here.&lt;/p&gt;
                   </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>
                      &lt;p&gt;Documentation goes here.&lt;/p&gt;
                   </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>
                      &lt;p&gt;Documentation goes here.&lt;/p&gt;
                   </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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top