XFireHome DocumentationJavadocs QuicklinksAegis Binding DevelopersDeveloper Space |
Aegis is the default XFire binding which maps XML to POJOs. It supports code first development only at this point - i.e. you write your service in POJOs and it will generate the XML schema/wsdl for you. Mapping OverviewAegis has a flexible mapping system so you can control how your beans are controlled. By default your POJOs are serialized based on their name and namespaces. If you have a class in the "org.codehaus.xfire" package named "Employee" it would be serialized in namespace "http://xfire.codehaus.org" with the local name "YourBean." Fore example, the java class: public class Employee { private String name; private String title; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } } In XML this translates to: <Employee xmlns="http://xfire.codehaus.org"> <name>Santa Claus</name> <title>Chief Present Officer (CPO)</title> </Employee> In XML Schema this would become a complex type: <xsd:complexType name="Employee"> <xsd:sequence> <xsd:element name="name" type="xsd:string" minOccurs="0" maxOccurs="1/> <xsd:element name="title" type="xsd:string" minOccurs="0" maxOccurs="1/> </xsd:sequence> </xsd:complexType>
Controlling Mappings with XMLIts easy to control how your service and its beans are mapped to xml. If you are using Java 5.0 skip straight down to that section otherwise read on to learn how to configure serialization via mapping files. Mapping files sit next your bean or service on the class path. In the above example you would have a file named "/org/codehaus/xfire/YourBean.aegis.xml". They follow the general format: <mappings> <mapping uri="" name=""> <method name="methodName"> <return-type mappedName="" componentType=""/> <parameter index="" mappedName=""/> </method> <property name="" mappedName="" style="attribute|element" componentType=""/> </mapping> </mappings> Note that <method> is used to configure methods on your service and <property> is used to configure properties on your javabeans. Controlling NamingLets pretend that in the above example you would like the elements names to be capatilized and in the namespace "urn:north-pole:operations". You could achieve this through a mapping file like so: <mappings xmlns:np="urn:north-pole:operations"> <mapping name="np:Employee"> <property name="name" mappedName="Name"/> <property name="title" mappedName="Title"/> </mapping> </mappings> Notice that we declared the namespace on the mappings element and then used the prefix to specify the element QNames for the name/title properties. This will result in a mapping like so: <np:Employee xmlns:np="urn:north-pole:operations"> <np:Name>Santa Claus</np:Name> <np:Title>Chief Present Officer (CPO)</np:Title> </np:Employee> Ignoring propertiesIf you don't want to serialize a certain property it is easy to ignore it: <mappings> <mapping> <property name="propertyName" ignore="true"/> </mapping> </mappings> Handling CollectionsYou undoubted use Collections in your code. Pre Java 5 it is impossible to determine the "component type" of a Collection by introspection. So you need to give Aegis some hints. For a service which returned a Collection of employees like so: public class EmployeeService { Collection getEmployees(String id) { ... } } You would need to supply metadata which gave the component type in a mapping file like this one: <mappings> <mapping> <method name="getEmployees"> <return-type componentType="org.codehaus.xfire.Employee"> </method> </mapping> </mappings> Handling MapsJava Maps don't map well to XML Schema (no pun intended) because there is no Map concept in XML Schema so your clients. Maps are transformed to a collection of {key, value} tuples. In addition to providing the type of the value, you must also provide Aegis with the type of the key: public class GiftService
{
Map getGiftList() { /* returns a map of NiceChild => Present */ }
}
The mapping file should look like this: <mappings> <mapping> <method name="getGiftList"> <return-type keyType="org.codehaus.xfire.NiceChild" componentType="org.codehaus.xfire.Present"> </method> </mapping> </mappings> This will generate the following type: <xsd:complexType name="NiceChild2PresentMap"> <xsd:sequence> <xsd:element name="entry" minOccurs="0" maxOccurs="unbounded"> <xsd:complexType> <xsd:sequence> <xsd:element name="key" type="ns1:NiceChild" minOccurs="0" maxOccurs="1"/> <xsd:element name="value" type="ns1:Present" minOccurs="0" maxOccurs="1"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> |