1 / 48

The Java Architecture For XML Binding (JAXB)

The Java Architecture For XML Binding (JAXB). By: Yoav Zibin Sharon Krisher. Motivation for JAXB. The main purpose of XML Schema is: Validation of XML documents Any other purposes? Hint 1: determinism requirement Hint 2: the “ default ” attribute has nothing to do with validation

kynan
Download Presentation

The Java Architecture For XML Binding (JAXB)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. The Java Architecture For XML Binding (JAXB) By: Yoav Zibin Sharon Krisher

  2. Motivation for JAXB • The main purpose of XML Schema is: • Validation of XML documents • Any other purposes? • Hint 1: determinism requirement • Hint 2: the “default” attribute has nothing to do with validation <xs:attribute name="country" use=“optional” default="Israel“ /> • Answer: Given a valid XML document, its schema defines a uniquedata model

  3. Motivation for JAXB • Problem: How to manipulate this data model? • DOM (data object model) solution: • Pros: simple, general (a schema is not even required) • Cons: no types, no compile-time checking • I wish to write … DOM pseudo-code example root.getChild("Address").getChild("Number").getText() returns a string root.getAddress().getNumber() returns a number

  4. JAXB solution: Mapping XML Schema to Java interfaces Binding Compiler Source schema Java interfaces Pros: preserve types, compile-time checking Cons: complex, specific to a certain schema

  5. Binding Compiler <xs:complexType name="AddressType"> <xs:sequence> <xs:element name="Number" type="xs:unsignedInt"/> <xs:element name="Street" type="xs:string"/> </xs:sequence> </xs:complexType> public interface AddressType { long getNumber(); void setNumber(long value); String getStreet(); void setStreet(String value); } Must be non-negative Must be non-null

  6. Talk Outline • How is XML Schema mapped to Java interfaces? • What is the default mapping? • How to customize this mapping? • Second part of the lecture • How do I use those Java interfaces? • Next slides and a Demo!

  7. Main Features • Unmarshal: xml  objects • Create / Read / Update / Delete objects • Validate objects • Marshal: objects  xml • No roundtrip guarantees • Marshal( Unmarshal(xml) ) ≠ xml • We found that order is not always preserved • But usually roundtrip holds

  8. Step 1: Create XML Schema Demo.xsd <xs:element name="Person" type="PersonType"/> <xs:complexType name="PersonType"> <xs:sequence> <xs:element name=“Name" type="xs:string"/> <xs:element name="Address" type="AddressType" minOccurs="1" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> <xs:complexType name="AddressType"> <xs:sequence> <xs:element name="Number" type="xs:unsignedInt"/> <xs:element name="Street" type="xs:string"/> </xs:sequence> </xs:complexType>

  9. Step 2: Create XML Document Demo.xml <Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="C:\JAXB Demo\demo.xsd"> <Name>Sharon Krisher</Name> <Address> <Street>Iben Gevirol</Street> <Number>57</Number> </Address> <Address> <Street>Moshe Sharet</Street> <Number>89</Number> </Address> </Person> Check that your XML conforms to the Schema

  10. Step 3: Run the binding compiler • %JWSDP_HOME%\jaxb\bin\xjc -p demo demo.xsd • A package named demo is created (in the directory demo) • The package contains (among other things): • interface AddressType • interface PersonType

  11. AddressType and PersonType public interface AddressType { long getNumber(); void setNumber(long value); String getStreet(); void setStreet(String value); } Must be non-negative Must be non-null Must be non-null public interface PersonType { String getName(); void setName(String value); /* List of AddressType */ java.util.List getAddress(); } Must contain at least one item In Java1.5: List<AddressType>

  12. Step 4: Create Context • The context is the entry point to the API • Contains methods to create Marshaller, Unmarshaller and Validator instances JAXBContext context = JAXBContext.newInstance("demo"); The package name is demo (Recall: xjc -p demo demo.xsd)

  13. Step 5: Unmarshal: xml -> objects Enable validation of xml according to the schema while unmarshalling Unmarshallerunmarshaller = context.createUnmarshaller(); unmarshaller.setValidating(true); PersonTypeperson = (PersonType) unmarshaller.unmarshal( new FileInputStream("demo.xml") );

  14. Step 6: Read System.out.println("Person name=" + person.getName() ); AddressTypeaddress = (AddressType) person.getAddress().get(0); System.out.println("First Address: " + " Street=" + address.getStreet() + " Number=" + address.getNumber() );

  15. What happens if we validate there? // Create ObjectFactoryobjectFactory = new ObjectFactory(); AddressTypenewAddr = objectFactory.createAddressType(); newAddr.setStreet("Hanoter"); newAddr.setNumber(5); addressList.add( newAddr ); part of the demo package uses the factory pattern Step 7: Manipulate objects // Update person.setName("Yoav Zibin"); // Delete ListaddressList = person.getAddress(); addressList.clear();

  16. Step 8: Validate on-demand Validatorvalidator = context.createValidator(); validator.validate(newAddr); validator.validate(person); Check that we have set Street and Number, and that Number is non-negative Check that we have set Name, and that Address contains at least one item

  17. Step 9: Marshal: objects -> xml Marshallermarshaller = context.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,Boolean.TRUE); marshaller.marshal(person, new FileOutputStream("output.xml")); output.xml <Person> <Name>Yoav Zibin</Name> <Address> <Street>Hanoter</Street> <Number>5</Number> </Address> </Person>

  18. And now, the Demo!

  19. First Part Summary

  20. Similar Technologies • Liquid XML Data Binding • Similar to JAXB • Supports all Schema constructs • In addition to Java: C#, C++, Visual Basic 6 • Relaxer • Instead of Schema uses Relax • Castor.org

  21. Second Part Outline • Validation • Mapping XML Schema to Java • Naming • Java Properties • Simple and Complex Types • Customization of the default mapping

  22. Validation Constraints • Three categories of constraints • Type constraints: Legal values in simple types • E.g., in every address, number is a non-negative integer • Local structural constraints • E.g., in every person, address contains at least one item • Global structural constraints • E.g., ID and IDREF

  23. Validation • Three forms of validation • Unmarshal time validation (at unmarshal time) • On-demand validation (at any chosen point in time) • validateRoot(object) vs. validate(object) • validateRoot includes global constraint checking • Fail-fast validation (at all times) • Currently not implemented • Checks that the value provided to a set method is legal • When validation errors occur an event is raised (no exception) and validation continues, so that several validation errors can be handled. • Default handler raises an exception on first error

  24. Unsupported Schema Concepts • Substitution groups • Type substitutions (xsi:type, block) • Key, keyref, and unique • anyAttribute • No support for XPath or any other query langauge 

  25. Element vs. Type • An element also has a qualified name • When is the difference important? (next) <xs:element name=“ugly_man" type="PersonType"/> <xs:element name=“pretty_woman" type="PersonType"/> <xs:complexType name="PersonType"> … </xs:complexType> an empty interface which marks the existence of a static QName interface UglyMan extends PersonType, Element {} interface PrettyWoman extends PersonType, Element {} interface PersonType { … }

  26. When must I use elements? • Marshal: • General content marshaller.marshal(Object, OutputStream) E.g., when we marshal a PersonType: <Name>Sharon Krisher</Name> <Address> <Street>Iben Gevirol</Street> <Number>57</Number> </Address> must be an element, otherwise the resulting output is not a legal XML Object getAny(); void setAny(Object elementOrValue); <xs:any/>

  27. Naming • Problem: sometimes XML names • are not legal java names • do not comply to java naming standards • The binding compiler creates proper names

  28. Java Properties • Local schema components are mapped to: • Simple property (get, set) • With customization: isSetName , unsetName • List property • Indexed property (next) String getName(); void setName(String value); In Java1.5: List<AddressType> java.util.List getAddress();

  29. Indexed Property • Used instead of a list property when a proper customization is applied AddressType[] getAddress(); void setAddress(AddressType[] value); AddressType getAddress(int index); void setAddress(int index, AddressType value);

  30. General Content Property • The most general content property • Can represent any content, however complex • A list that can contain element interfaces and values • Used for “problematic cases” : • Name collisions due to derivation • Mixed content • Another example: <xs:any maxOccurs="unbounded"/> Each item can be some element or value List getAny();

  31. Simple Types (partial diagram) List Next (1) Represented as validation constraints String/Object Calendar BigInteger int Next (2)

  32. Simple Type: Union <xs:complexType name="Date"> <xs:sequence> <xs:element name="Month"> <xs:simpleType> <xs:union memberTypes="xs:intxs:string"/> </xs:simpleType> </xs:element> </xs:sequence> </xs:complexType> Common supertype of (Integer, String) is Object Public interface Date { Object getMonth(); void setMonth(Object); }

  33. Type Safe Enumeration <xs:simpleType name="USState"> <xs:restriction base="xs:NCName"> <xs:enumeration value="AK"/> <xs:enumeration value="NY"/> </xs:restriction> </xs:simpleType> public class USState { protected USSate(String v) {…} public static final USStateAK = …; public static final USStateNY = …; public String getValue(); public static USState fromValue(String v) {…} }

  34. * ( ) Next XML Schema Type System Represented as a Java interface finished * * * * Elements abstract nillable minOccurs maxOccurs Attributes use default fixed * * The interfaceextends the base type’s interface Represented as Java properties

  35. Complex Types • Represented as a Java interface • Anonymous type • An interface is created. • The name is derived from the name of the schema element + “Type”, e.g Foo FooType • Abstract types: no create method in ObjectFactory

  36. Complex Type: Simple Content <xs:complexType name=“InternationalPrice"> <xs:simpleContent> <xs:extension base="xs:int"> <xs:attribute name="currency“ type="xs:string"/> </xs:extension> </xs:simpleContent> </xs:complexType> interface InternationalPrice { int getValue(); void setValue(int); String getCurrency(); void setCurrency(String); }

  37. Complex Type: Aggregation <xs:element name="A" type="xs:int"/> <xs:complexType name="Foo"> <xs:sequence> <xs:element ref="A"/> <xs:sequence> <xs:element ref="B"/> <xs:element ref="C"/> </xs:sequence> </xs:sequence> </xs:complexType> <xs:complexType name="Foo"> <xs:sequence> <xs:element ref="A"/> <xs:element ref="B"/> <xs:element ref="C"/> </xs:sequence> </xs:complexType> interface Foo { int getA(); void setA(int); int getB(); void setB(int); int getC(); void setC(int); }

  38. XML fragment Dear Mr.<name>Robert Smith</name>, … Complex Type: Mixed Content <xs:complexType name=“LetterBody" mixed="true"> <xs:sequence> <xs:element name="name" type="xs:string"/> … </xs:sequence> </xs:complexType> interface LetterBody { interface Name extends Element { String getValue(); void setValue(String); } … List getContent(); } LetterBody lb = ObjectFactory.createLetterBody(); List gcl = lb.getContent(); gcl.add("Dear Mr."); gcl.add(ObjectFactory.createLetterBodyName("Robert Smith")); The list may contain elements and strings

  39. Complex Type: Choice <xs:complexType name="FooBarType"> <xs:choice> <xs:element name="Foo" type="xs:int"/> <xs:element name="Bar" type="xs:string"/> </xs:choice> </xs:complexType> The programmer is responsible to only set one of Foo or Bar Default public interface FooBarType { int getFoo(); void setFoo(int value); String getBar(); void setBar(String value); boolean isSetFoo(); void unsetFoo(); boolean isSetBar(); void unsetBar(); } Customization (Not implemented yet) public interface FooBarType { Object getFooOrBar(); void setFooOrBar(Object); } Common supertype of (Integer, String) is Object Similar to union

  40. When maxOccurs>1 <xs:complexType name="FooBarType"> <xs:choicemaxOccurs="unbounded"> <xs:element name="Foo" type="xs:int"/> <xs:element name="Bar" type="xs:string"/> </xs:choice> </xs:complexType> public interface FooBarType { interface Foo extends Element {…} interface Bar extends Element {…} // Items are instances of Foo and Bar List getFooOrBar(); } For asequence: List getFooAndBar() The programmer needs to make sure thatthe list contains sequences of <A,B>.

  41. Objects in memory XML XML ≠ Complex Type: All • Mapped like Sequence • Can’t have maxOccurs > 1 • No way to specify the order of elements • Round trip doesn’t hold (order is not preserved): unmarshal marshal

  42. Java: or setAge( new Integer(25) ) setAge(null) XML: or <age>25</age> <agexsi:nil="true"/> Nillable elements <xs:element name=“age" type=“xs:int" nillable="true"/> Integer getAge(); void setAge(Integer value);

  43. Customization • Used to augment the default mapping • Customizations declared via special xml tags • May appear inside the source schema or in a separate file

  44. Uses of Customization • Change default names of interfaces and properties • For a specific schema construct • For an entire namespace • Add a suffix or a prefix • Change the types of properties • Add javadoc declarations

  45. Software Engineering Issues • Weak Typing Our suggestions: • Marshal / Unmarshal : Object  Element • IDREF: Object  Identifiable • Sometimes JAXB doesn’t allow us to control the order of elements • Example 1: xs:all • Example 2: next slide

  46. Element Order Example <xs:complexType name=“ABType"> <xs:choice> <xs:sequence> <xs:element name="A" type="xs:int"/> <xs:element name="B" type="xs:string"/> </xs:sequence> <xs:sequence> <xs:element name="B" type="xs:string"/> <xs:element name="A" type="xs:int"/> </xs:sequence> </xs:choice> </xs:complexType> obj.setA(5); obj.setB(“a”); What happens when we marshal obj? public interface ABType { int getA(); void setA(int value); String getB(); void setB(String value); } No roundtrip

  47. xs:choice between Foo and Bar obj.setFoo(42); obj.setBar("A"); System.out.println( obj.isSetFoo() ); It’s the programmer’s fault • Taken from JAXB specification: • “The caller must be sure …” • “There is an expectation …” • “User is responsible …” • “… unexpected behavior may occur.” Question: What is the output ? 42 true obj.setAge(42); obj.unsetAge(); System.out.println( obj.getAge() );

  48. The END • Any questions?

More Related