Using Abstract base class type to traverse entire JAXB Object tree
The system hardware I write software for is physically connect via hardware in a tree structure. The data model in our application is a Tree. For our new rewrite, we're using JAXB to create the data model.
We have three types of Devices, and they all share some properties, so I made an Abtract DeviceType in the XSD schema. My three devices (Pushers, Switchers, Receivers) are all extended from the DeviceType in the XSD like this:
<xs:complexType name="DeviceType" abstract="true">
<xs:sequence>
<xs:element name="atrr1" type="xs:int"></xs:element>
<xs:element name="attr2" type="xs:int"></xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="PusherType">
<xs:complexContent>
<xs:extension base="pts:DeviceType">
<xs:sequence>
<xs:element name="Switcher" type="pts:SwitcherType" minOccurs="1"></xs:element>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="SwitcherType">
<xs:complexContent>
<xs:extension base="pts:DeviceType">
<xs:sequence>
<xs:element name="switcher" type="pts:SwitcherType" minOccurs="1"></xs:element>
<xs:element name="receiver" type="pts:ReceiverType" minOccurs="1"></xs:element>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
Pushers have only switcher child elements, and switchers can have both switcher or receiver children. Receivers are the end of the line (leaf nodes). xjc builds the classes. I got the Unmarshaller to construct the object tree, but I can't figure out how to get a getter method for getDevice(). For tree traversal, I was hoping JAXB would provide something like "getChildren", but I'm not seeing in in the API. If I get a sw开发者_运维百科itcher object, I have the methods for getSwitcher() and getReceiver(), but no getDevice() method. But I'm trying to avoid using instanceof when I do a full tree traversal. The Java code that xjc builds, does extend from the Device class, but I just haven't learned how to get a generic getter method for all devices. I just started with Jaxb two days ago and I have a ton to learn about the Jaxb API.
Yesterday was my first day playing with JAXB, I think this tool suits our system incredible well. Our hardware is literally a tree,we have multiple deployments, and using XML as our site config file to build a state model would be ideal.
Any suggestions for a JAXB novice here?
JAXB (JSR-222) is the Java standard for mapping objects to XML. There are several implementations including: Metro, EclipseLink MOXy (I'm the tech lead), Apache JaxMe, etc.
JAXB is designed to map existing object structures to XML. In your example you are leveraging JAXB's ability to generate a class model from an XML schema. This produces something like a "typed DOM". There will be a Java class matching each complex type (with the necessary inheritance relationships), and a property matching each attribute/element. For example the following class corresponds to the SwitcherType complex type:
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "SwitcherType", propOrder = {
"switcher",
"receiver"
})
public class SwitcherType extends DeviceType
{
@XmlElement(required = true)
protected SwitcherType switcher;
@XmlElement(required = true)
protected ReceiverType receiver;
public SwitcherType getSwitcher() {
return switcher;
}
public void setSwitcher(SwitcherType value) {
this.switcher = value;
}
public ReceiverType getReceiver() {
return receiver;
}
public void setReceiver(ReceiverType value) {
this.receiver = value;
}
}
Unlike a DOM there are no generic getChildren() methods. Although you could implement these yourself by modifying the object model.
For more information on JAXB:
- http://blog.bdoughan.com/
精彩评论