Как заставить сгенерированные классы содержать Javadoc из документации XML-схемы - PullRequest
43 голосов
/ 30 октября 2009

В настоящее время я работаю со схемой XML, которая имеет <xsd:annotation> / <xsd:documentation> для большинства типов и элементов. Когда я генерирую Java Beans из этой XML-схемы, Javadoc этих Beans содержит только некоторую общую сгенерированную информацию о разрешенном содержимом типа / элемента.

Я бы хотел видеть содержимое тега <xsd:documentation> в соответствующих местах (например, содержимое этого тега для completextype должно отображаться в Javadoc класса, сгенерированного для представления этого complexType).

Есть ли способ добиться этого?

Редактировать : эта XML-схема будет использоваться в WSDL с JAX-WS, поэтому этот тег также может быть уместным.

Редактировать 2 : Я читал о <jxb:javadoc>. Из того, что я понимаю, я могу указать это либо в отдельном файле привязки JAXB, либо непосредственно в схеме XML. Это почти решило бы мою проблему. Но я бы предпочел использовать существующий тег <xsd:documentation>, поскольку Javadoc не является основной целью документации (это прежде всего информация о структуре данных, а не о сгенерированных из нее компонентах Java Beans) и позволяет инструментам, не являющимся JAXB, получать доступ информация также. Предоставление документации как в <jxb:javadoc>, так и xsd:documentation> "кажется" неправильным, потому что я дублирую данные (и работаю) без веской причины.

Редактировать 3 : Благодаря ответу Паскаля я понял, что у меня уже есть половина решения: <xsd:documentation> из complexType s записывается в начало его Javadoc! Проблема по-прежнему в том, что only , что используется complexType s и simpleType s (что также может привести к классу), а элементы по-прежнему не содержат Javadoc.

Ответы [ 4 ]

35 голосов
/ 30 октября 2009

Мне никогда не удавалось получить обычный xsd:documentation для размещения в java-источнике, кроме , если и только если это был сложный тип. Документация для элементов, простых типов, и т. д. игнорируются.

Итак, я использую jxb:javadoc. Для этого включите определение xmlns:jxb="http://java.sun.com/xml/ns/jaxb" в элемент <xsd:schema>.

Добавить ребенка к <xsd:complexType> или <xsd: element> или <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>

Где XXX - это "класс" или "свойство".

За посылку вы пишите ребенку 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>

Для написания HTML-документа требуется заключить в скобки <![CDATA[ --- ]]>

(РЕДАКТИРОВАТЬ: во время написания моего ответа ОП редактировал вопрос, поэтому я обновляю его соответствующим образом)

В моем случае единственной целью был javadoc, поэтому было приемлемо использовать jxb:javadoc. Но ваше обновление имеет смысл, и, на самом деле, я полностью согласен с вами. К сожалению, я никогда не находил идеального решения для ситуации, которую вы описываете (поэтому я буду очень внимательно следить за этим вопросом). Возможно, вы могли бы использовать что-то вроде xframe для генерации документации из xsd:documentation, но это не отвечает на вопрос.

12 голосов
/ 02 ноября 2009

Это просто невозможно с эталонной реализацией JAXB. Даже если вы попытаетесь написать плагин XJC, вы обнаружите, что API плагина не имеет ссылки на определение схемы, поэтому нет способа извлечь эту информацию.

Наша единственная надежда состоит в том, что будущая версия JAXB исправит ситуацию. открытый запрос здесь .

4 голосов
/ 05 ноября 2016

Я считаю, что следующие методы работают очень хорошо для добавления заголовков JavaDoc к классам элементов Java (генерируемых из схем XML). Я вкладываю JavaDoc в теги, определенные в пространстве имен jax-b, вложенные в аннотацию схемы xml и теги appinfo. Обратите внимание, что пространство имен jaxb определяет типы тегов документации; Я использую два из них: класс и теги свойств. определено в следующем пространстве имен: xmlns: jxb = "http://java.sun.com/xml/ns/jaxb"

1) Для документирования класса я использую тег jaxb "class" в следующей последовательности:

  <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) Для документирования элемента я использую тег «property» следующим образом:

       <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) Я использую тот же набор тегов для атрибутов документа:

      <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) Для документирования выбора я использую тег свойства jaxb и документирую выбор.

    <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>

Попытка документировать отдельные варианты здесь потерпит неудачу, так как этот тег создает нетипизированный список.

0 голосов
/ 28 января 2019

Специально для этого случая я написал плагин XJC xjc-documentation-annotation-plugin .

Что он делает: <annotation><documentation> -> Аннотации классов Java

Сказал, что этот объект описан в 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>

Мы запускаем xjc как:

xjc -npa -no-header -d src/main/generated-java/ -p xsd.generated scheme.xsd

И получил класс как (геттеры, сеттеры и любые аннотации для простоты опущены):

public class CadastralBlock {
    protected String number;
}

Но в моем случае я хочу знать, как класс и поля были названы в исходном файле! Так что же делает этот плагин!

Итак, вы получите:

@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;
}

Как использовать

Ручной вызов в командной строке

Если вы хотите запустить его вручную, обеспечьте jar-класс с плагином в run classpath и просто добавьте опцию -XPluginDescriptionAnnotation. F.e.:

xjc -npa -no-header -d src/main/generated-java/ -p xsd.generated -XPluginDescriptionAnnotation scheme.xsd

Звонок с Java / Groovy

Driver.run(
    [
        '-XPluginDescriptionAnnotation'
        ,'-d', generatedClassesDir.absolutePath
        ,'-p', 'info.hubbitus.generated.test'
        ,'CadastralBlock.xsd'
    ] as String[]
    ,new XJCListener() {...}
)

См. Тестовый тест XJCPluginDescriptionAnnotationTest, например.

Использование от Gradle

С 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' ]
}

Завершить gradle пример в каталоге example-project-gradle проекта.

...