2015-06-16 12 views
5

Tôi đang làm việc trên một ứng dụng sử dụng XJC để tạo các POJO Java từ XSD. Có hàng chục lược đồ, và con số đó sẽ tăng lên. Ứng dụng cũng cần có khả năng xử lý các phiên bản khác nhau của cùng một lược đồ, có nghĩa là tôi sẽ có nhiều lược đồ xác định các loại phổ biến. Tôi đang cố gắng tùy chỉnh các ràng buộc để các loại lõi nhất định thực hiện một giao diện chung. Plugin Inheritance của JAXB2 Basics dường như làm những gì tôi cần, nhưng dường như tôi không thể làm đúng cú pháp.JAXB đã tạo các lớp một số loại thực hiện một giao diện tùy chỉnh

Dưới đây là phần có liên quan của giản đồ của tôi:

<?xml version="1.0" encoding="UTF-8"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
      xmlns:my="http://example.com/core" 
      targetNamespace="http://example.com/core" 
      xmlns:xml="http://www.w3.org/XML/1998/namespace"> 

    ... 

    <xs:complexType name="addressType"> 
     <xs:sequence> 
      <xs:element name="Address" type="xs:string"/> 
      <xs:element name="City" type="xs:string"/> 
      <xs:element name="Province" type="xs:string"/> 
      <xs:element name="Country" type="xs:string"/> 
      <xs:element name="County" type="xs:string" minOccurs="0"/> 
      <xs:element name="PostalCode" type="xs:string"/> 
     </xs:sequence> 
    </xs:complexType> 

    ... 

</xs:schema> 

... và đây là những gì tùy chỉnh của tôi tập ràng buộc trông giống như:

<?xml version="1.0"?> 
<jaxb:bindings 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" 
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" 
    xmlns:inheritance="http://jaxb2-commons.dev.java.net/basic/inheritance" 
    xmlns:my="http://example.com/core" 
    jaxb:extensionBindingPrefixes="inheritance" 
    version="2.1"> 

    <jaxb:bindings scd="x-schema::my" xmlns:my="http://example.com/core"> 
     <jaxb:globalBindings localScoping="toplevel"> 
      <jaxb:serializable/> 
      <xjc:simple/> 
     </jaxb:globalBindings> 
     <jaxb:bindings scd="/type::my:addressType"> 
      <inheritance:implements>com.mysite.validator.ValidatableAddress</inheritance:implements> 
      <!--<xjc:superInterface name="com.mysite.validator.ValidatableAddress"/>--> 
     </jaxb:bindings> 
    </jaxb:bindings> 

</jaxb:bindings> 

Tôi đang sử dụng cách tiếp cậnSCD , bởi vì trong tất cả các ví dụ ràng buộc "truyền thống" chỉ ra cách sử dụng plugin kế thừa, lược đồ vị trí được chỉ định. Tôi muốn tránh phải chỉ định schemaLocation vì số lượng lớn (và ngày càng tăng) của các lược đồ. Tôi không muốn phải thay đổi tệp ràng buộc mỗi lần chúng tôi thêm lược đồ mới. Vì vậy, scd có vẻ như nó sẽ đáp ứng yêu cầu này.

Tuy nhiên khi tôi chạy xây dựng bằng cách sử dụng trên ràng buộc, tôi có được điều này:

[xjc] [ERROR] cvc-elt.1: Cannot find the declaration of element 'inheritance:implements'. 
    [xjc] line 18 of file:/dev/workspace/my_app/etc/schemas/bindings-common.xml 
    [xjc] failure in the XJC task. Use the Ant -verbose switch for more details 
    [xjc] classLoader = [email protected] 
    [xjc] SharedSecrets.getJavaNetAccess()[email protected] 

Nếu tôi nhận xét ra thừa kế: thực hiện dòng và bỏ XJC: superInterface dòng, sai đi và quá trình xây dựng hoàn tất thành công, nhưng các lớp AddressType của tôi không triển khai loại ValidatableAddress.

Plugin kế thừa có thể được sử dụng với scd không? Có thể xjc: superInterface được giới hạn chỉ một số yếu tố?

Chúc mừng.

Trả lời

4

Nhờ lexicore cho các câu trả lời nhanh chóng và chi tiết. Tuy nhiên cách tiếp cận đó không hiệu quả đối với tôi, vì vậy tôi đã kết thúc với giải pháp sau ...

Vì tôi đang sử dụng Ant để gọi XJC, tôi đã tận dụng khả năng của <copy filtering="true"...> của Ant để tạo tệp ràng buộc.

Đây là ràng buộc của tôi "mẫu" tập tin (bindings-common.xml):

<?xml version="1.0"?> 
<jaxb:bindings 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" 
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" 
    xmlns:inheritance="http://jaxb2-commons.dev.java.net/basic/inheritance" 
    xmlns:my="http://http://example.com/core" 
    jaxb:extensionBindingPrefixes="inheritance" 
    version="2.1"> 
    <jaxb:bindings> 
     <jaxb:globalBindings localScoping="toplevel"> 
      <jaxb:serializable/> 
      <xjc:simple/> 
     </jaxb:globalBindings> 
    </jaxb:bindings> 

    <jaxb:bindings 
     schemaLocation="@[email protected]" 
     node="/xs:schema"> 

     <jaxb:bindings node="//xs:complexType[@name='addressType']"> 
      <inheritance:implements>com.example.validator.ValidatableAddress</inheritance:implements> 
     </jaxb:bindings> 
    </jaxb:bindings> 

</jaxb:bindings> 

Lưu ý dòng này:

<jaxb:bindings 
      schemaLocation="@[email protected]" 
      node="/xs:schema"> 

Biến này sẽ được dân cư bởi Ant cho mỗi người trong số các lược đồ mà tôi đang xử lý:

<property name="jaxb.binding.template" value="../etc/form-schemas/bindings-common.xml"/> 
<property name="jaxb.binding.file" value="${jaxb.src.dir}/bindings-common${schema.version}.xml"/> 

<echo message="Filtering ${jaxb.binding.file} using template ${jaxb.binding.template}"/> 

<copy file="${jaxb.binding.template}" 
     tofile="${jaxb.binding.file}" 
     filtering="true"> 

    <filterset> 
     <filter token="bindingSchema" value="../../etc/form-schemas/${schema.version}/common.xsd"/> 
    </filterset> 
</copy> 

<xjc destdir="${jaxb.src.dir}" 
     extension="true" 
     schema="${schema.file}" 
     package="${package}" 
     binding="${jaxb.binding.file}"> 

    <arg value="-episode"/> 
    <arg value="${jaxb.src.dir}/common${schema.version}.episode"/> 
    <arg line="-Xinheritance"/> 

     <!-- Plugins --> 
     <classpath> 
      <fileset dir="../build-libs/"> 
       <!-- JAXB2 Basics library --> 
       <include name="jaxb2-basics-0.6.4.jar"/> 
       <!-- JAXB2 Basics library dependencies --> 
       <include name="jaxb2-basics-runtime-0.6.4.jar"/> 
       <include name="jaxb2-basics-tools-0.6.4.jar"/> 
       <include name="javaparser-1.0.8.jar"/> 
       <include name="commons-beanutils-*.jar"/> 
       <include name="commons-lang-*.jar"/> 
       <include name="commons-logging-*.jar"/> 
      </fileset> 
     </classpath> 
    </xjc> 
</target> 

Hy vọng điều này sẽ giúp các thế hệ nạn nhân JAXB trong tương lai.

4

Tác giả của tại đây.

Xem this issue trong XJC. Tóm lại, XJC vì một lý do nào đó không cho phép các phần tử tùy chỉnh/nhà cung cấp tùy chỉnh trong các ràng buộc SCD.
inheritance:implements là yếu tố tùy chỉnh như vậy.

Vì vậy không, điều này không hoạt động do sự cố trong XJC.

Cá nhân tôi ràng buộc qua schemaLocation và XPath nhưng sử dụng URI vị trí lược đồ "ảo" và viết lại nó qua danh mục.

SCD sẽ là lựa chọn tốt hơn nhiều (bạn hoàn toàn ở đây) nhưng nó không hoạt động.

Cập nhật trên vị trí và danh mục lược đồ ảo.

Dưới đây là một example of binding mà tùy một số loại phức tạp:

<jaxb:bindings 
    schemaLocation="http://schemas.opengis.net/wps/2.0/wpsCommon.xsd" 
    node="/xs:schema"> 
    <jaxb:bindings node="xs:element[@name='Data']/xs:complexType"> 
     <wildcard:lax/> 
    </jaxb:bindings> 
</jaxb:bindings> 

Nó được ràng buộc qua schemaLocation và XPath. Các schemaLocation là một existing URL, nhưng trong xây dựng nó được viết lại via catalog vào nguồn lực bên trong một vật Maven:

REWRITE_SYSTEM "http://schemas.opengis.net" "maven:org.jvnet.ogc:ogc-schemas:jar::!/ogc" 

Vì vậy, về cơ bản http://schemas.opengis.net/wps/2.0/wpsCommon.xsd sẽ được nạp từ ogc-schema.jar!/ogc/wps/2.0/wpsCommon.xsd.

Sử dụng bạn có thể refer to binding files inside Maven artifacts as well:

    <binding> 
         <dependencyResource> 
          <groupId>${project.groupId}</groupId> 
          <artifactId>ows-v_2_0</artifactId> 
          <resource>ows-v_2_0.jsonix.xjb</resource> 
          <version>${project.version}</version> 
         </dependencyResource> 
        </binding> 

Vì vậy, kết hợp, nó cho phép ghi file ràng buộc một lần và tái sử dụng chúng trên mô-đun.

Nhưng đây là một nỗi đau lớn để tìm ra. Tôi đã làm nó cho dự án ogc-schemas mà bây giờ là một số 50 lược đồ kết nối rất nhiều. Tôi rất đau khổ vì những hạn chế và vấn đề XJC, nhưng đây là điều tốt nhất có thể tại thời điểm này. Tôi thậm chí còn nghĩ đến khoảng forking and patching XJC, nhưng điều này vượt quá giới hạn nỗ lực tôi có thể mua được.

Vì vậy, tôi đã kết thúc bằng một số cách giải quyết khác nhau bằng cách nào đó thực hiện công việc vào cuối ngày.

+0

Cảm ơn từ vựng. Điều gì về việc kết hợp scd và xjc: superInterface ... Điều đó có hiệu quả không? Bất kỳ ý tưởng nào tại sao phương pháp này không tạo ra lỗi nào, nhưng cũng dường như không có bất kỳ ảnh hưởng nào đối với nguồn được tạo ra? – 6006604

+0

... hoặc là xjc: superInterface được coi là tùy chỉnh/nhà cung cấp tùy chỉnh giống như kế thừa: triển khai? – 6006604

+0

Nó thực sự là một phần mở rộng nhà cung cấp nhưng nó là một phần mở rộng nhà cung cấp "hạng nhất" được đặc biệt biết đến XJC (xem [ở đây] (https://github.com/gf-metro/jaxb/blob/69471fb27af6a9e990ef2a7873aab64a18e87640/jaxb-ri/ xjc/src/main/resources/com/sun/công cụ/xjc/reader/xmlschema/bindinfo/binding.xsd # L81)) - không giống như 'inheritance: implements'. Nhân tiện, không phải là 'xjc: superInterface' cho [global bindings only] (https://jaxb.java.net/nonav/2.1.15/docs/vendorCustomizations.html#superinterface)? Sẽ giải thích lý do tại sao nó bị bỏ qua trên lớp. – lexicore

Các vấn đề liên quan