2015-06-16 13 views
5

मैं XSDs से जावा POJOs उत्पन्न करने के लिए XJC उपयोग करने वाले ऐप्लिकेशन पर काम कर रहा हूँ को लागू करने में कुछ विशेष प्रकार की कक्षाओं उत्पन्न। दर्जनों स्कीमा हैं, और वह संख्या बढ़ेगी। एप्लिकेशन को एक ही स्कीमा के विभिन्न संस्करणों को संभालने में सक्षम होना चाहिए, जिसका अर्थ है कि मेरे पास सामान्य प्रकारों को परिभाषित करने वाले कई स्कीमा होंगे। मैं बाइंडिंग को कस्टमाइज़ करने की कोशिश कर रहा हूं ताकि कुछ कोर प्रकार एक सामान्य इंटरफेस को कार्यान्वित कर सकें। जेएक्सबी 2 मूल बातें की विरासत प्लगइन मुझे जो चाहिए वह करना प्रतीत होता है, लेकिन मुझे सही वाक्यविन्यास को नाखून नहीं लग रहा है।JAXB एक कस्टम इंटरफ़ेस

यहाँ मेरी स्कीमा के प्रासंगिक हिस्सा है:

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

... और इस तरह क्या अपने कस्टम बाध्यकारी फ़ाइल लग रहा है:

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

मैं SCD दृष्टिकोण का उपयोग कर रहा हूँ , क्योंकि सभी "पारंपरिक" बाध्यकारी उदाहरणों में जो दिखाते हैं कि विरासत प्लगइन का उपयोग कैसे करें, स्कीमालोकेशन निर्दिष्ट है। मैं स्कीमा की हमारी बड़ी (और बढ़ती) संख्या के कारण स्कीमालोकेशन निर्दिष्ट करने से बचना चाहता हूं। हर बार जब हम एक नई स्कीमा जोड़ते हैं तो मैं बाध्यकारी फ़ाइल को बदलना नहीं चाहता हूं। तो, scd ऐसा लगता है कि यह इस आवश्यकता को पूरा करेगा।

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

अगर मैं बाहर टिप्पणी विरासत: लाइन लागू करता है और uncomment xjc: superInterface लाइन, त्रुटि चला जाता है

लेकिन जब मैं ऊपर का उपयोग कर बाध्यकारी निर्माण चलाने के लिए, मैं इस मिल दूर और निर्माण सफलतापूर्वक पूरा हो जाता है, लेकिन मेरा पता टाइप कक्षाएं ValidatableAddress प्रकार को लागू नहीं करती हैं।

उत्तराधिकारी प्लगइन का उपयोग scd के साथ किया जा सकता है? Xjc: superInterface केवल कुछ तत्वों तक ही सीमित हो सकता है?

चीयर्स।

उत्तर

4

त्वरित और विस्तृत उत्तरों के लिए लेक्सिकोयर के लिए धन्यवाद। हालांकि यह दृष्टिकोण मेरे लिए काम नहीं कर रहा था, इसलिए मैंने निम्नलिखित समाधान के साथ समाप्त किया ...

क्योंकि मैं एक्सजेसी का आह्वान करने के लिए चींटी का उपयोग कर रहा हूं, इसलिए मैंने बाध्यकारी फ़ाइल को गतिशील रूप से उत्पन्न करने के लिए चींटियों की <copy filtering="true"...> क्षमताओं का लाभ उठाया।

यहाँ

है मेरी बाइंडिंग "टेम्पलेट" फ़ाइल (बाइंडिंग-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> 

नोट इस लाइन:

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

यह चर स्कीमा में से प्रत्येक के लिए चींटी की आबादी हो जाएगी कि मैं प्रसंस्करण कर रहा हूं:

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

उम्मीद है कि यह जेएक्सबी पीड़ितों की भविष्य की पीढ़ियों की मदद करेगा।

4

यहाँ के लेखक।

XJC में this issue देखें। संक्षेप में, किसी कारण से एक्सजेसी एससीडी बाइंडिंग में कस्टम/विक्रेता अनुकूलन तत्वों की अनुमति नहीं देता है।
inheritance:implements ऐसे अनुकूलन तत्व है।

तो नहीं, इस XJC में एक समस्या की वजह से काम नहीं करता।

मैं व्यक्तिगत रूप से के माध्यम से schemaLocation और XPath बाँध लेकिन एक "आभासी" स्कीमा स्थान URI का उपयोग और कैटलॉग के माध्यम से इसे फिर से लिखने।

SCD एक बेहतर विकल्प (आप बिल्कुल सही यहाँ हो) हो गया होता, लेकिन यह सिर्फ काम नहीं करता।

वर्चुअल स्कीमा स्थान और कैटलॉग पर अद्यतन करें।

यहाँ एक example of binding जो कुछ जटिल प्रकार अनुकूलित है:

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

यह schemaLocation और XPath के माध्यम से बाध्य है। schemaLocation एक existing URL है, लेकिन निर्माण में यह एक Maven विरूपण साक्ष्य के अंदर संसाधन में via catalog फिर से लिखा है:

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

तो मूल रूप से http://schemas.opengis.net/wps/2.0/wpsCommon.xsdogc-schema.jar!/ogc/wps/2.0/wpsCommon.xsd से लोड किया जाएगा।

आप कर सकते हैं 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> 

तो, संयोजन में, यह बाध्यकारी फ़ाइलों लेखन एक बार और उन्हें मॉड्यूल भर में पुन: उपयोग की अनुमति देता है।

लेकिन यह पता लगाने के लिए यह एक बड़ा दर्द था। मैंने इसे ogc-schemas प्रोजेक्ट के लिए किया जो अब लगभग 50 भारी इंटरकनेक्टेड स्कीमा है। मैं एक्सजेसी की कमी और मुद्दों से काफी पीड़ित हूं, लेकिन इस समय यह सबसे अच्छा संभव है। मैंने forking and patching XJC के बारे में भी सोचा, लेकिन यह संभव है कि मैं कितनी कोशिश कर सकूं।

तो मैंने कई दिमागी ब्लॉगिंग वर्कअराउंड्स के साथ समाप्त कर दिया है जो किसी भी तरह के दिन के अंत में नौकरी करते हैं।

+0

धन्यवाद लेक्सिकोयर। एसडीडी और एक्सजेसी के संयोजन के बारे में क्या: superInterface ... क्या यह काम करना चाहिए? कोई विचार यह दृष्टिकोण क्यों कोई त्रुटि उत्पन्न नहीं करता है, लेकिन ऐसा लगता है कि जेनरेट किए गए स्रोत पर कोई प्रभाव नहीं पड़ता है? – 6006604

+0

... या xjc है: superInterface उत्तराधिकारी की तरह एक कस्टम/विक्रेता अनुकूलन माना जाता है: उपकरण? – 6006604

+0

यह वास्तव में एक विक्रेता विस्तार है लेकिन यह एक "प्रथम श्रेणी" विक्रेता विस्तार है जो विशेष रूप से एक्सजेसी के लिए जाना जाता है (देखें [यहां] (https://github.com/gf-metro/jaxb/blob/69471fb27af6a9e990ef2a7873aab64a18e87640/jaxb-ri/ xjc/src/main/resource/com/sun/tools/xjc/reader/xmlschema/bindinfo/binding.xsd # L81)) - 'विरासत: उपकरण' के विपरीत। वैसे, [xjc: superInterface' नहीं है [केवल वैश्विक बाइंडिंग] (https://jaxb.java.net/nonav/2.1.15/docs/vendorCustomizations.html#superinterface)? समझाएगा कि इसे कक्षा पर क्यों नजरअंदाज कर दिया गया है। – lexicore