Simple
XML Protocol Binder
Design Specification
3.2 Undefined Attributes Values
3.3 Standard Methods and Attribute Names
This document describes the Simple XML Protocol Binder, a suite of Java classes providing the following functionality:
· generation of Java source files defining classes corresponding to simple XML message formats
· serializing objects of these generated classes into XML form (“marshalling”)
· deserializing the objects from XML to Java objects (“unmarshalling”)
· transmission of the XML messages between a server and client utilizing an HTTP transport
· routing of received messages on the server to appropriate handlers, and the retrieval of response messages for return to the client
The following rules define the range of message formats supported:
· messages are restricted to XML elements and enclosed text
· a message comprises XML elements, their attributes, and child elements, and enclosed text
· only one text string per element is allowed
· child elements may be specified as a single occurrence of an element type, or as an array of unspecified size
· attributes, child elements, and text can be optional or required, providing a basic validation capability
A simple XML schema language is defined for specifying message formats. It comprises five element types defined in the table below
Name |
Purpose |
Attributes |
<schema> |
Required
XML root element |
|
<element> |
Defines
a message element and a corresponding Java class |
type the XML element type. The corresponding Java class name
will consists of the element type string, with an optional standard prefix
for all classes. extends optional name of a parent class which the corresponding Java
class extends abstract boolean value declaring
the corresponding java class is abstract. Defaults to “false” |
<attribute> |
Defines
message attributes, and corresponding class members of the corresponding Java
class |
name the attribute name, and the name of the corresponding Java
class member type the
type of the Java class member requiredboolean value specifying if the attribute is
required. Defaults to “false” |
<child> |
Specifies
child elements |
name the name of the Java class member containing the reference to
the child object type the
type of the child element, corresponding to the type attribute of the
child <element> definition member required boolean value specifying if the attribute is
required. Defaults to “false” array boolean value specifying if multiple occurrences
of the child element are allowed. The corresponding class member will be
defined as an array of the child element type |
<data> |
Specifies
that the enclosing element can contain text data |
required Boolean value specifying if data is required or
optional. Default is false |
The type attribute of the <attribute> element specifies the Java type of the corresponding class member. The following common types are supported:
For clarity and simplicity, the following naming conventions are recommended. These are optional, but result in java source code adhering to the de facto standard Java naming conventions:
There is a set of reserved names that cannot be applied to child elements or attributes in the schema. These are listed in Section 3.3.
The following schema defines six element types required to assemble a “Family” message:
<schema>
<element type="Family">
<data
required="true"/>
<attribute name="command"
type="String" required="true"/>
<attribute
name="familyName" type="String"
required="true"/>
<attribute
name="description" type="String"/>
<child name="father"
type="Father" required="true"/>
<child name="sons"
type="Child" array="true" required="true"/>
<child name="daughters"
type="Child" array="true" required="false"/>
</element>
<element type="Person"
abstract="true">
<attribute name="name"
type="String" required="true"/>
<attribute
name="birthday" type="Date"/>
<child name="hobbies"
type="Hobby" array="true"/>
</element>
<element type="Adult"
abstract="true" extends ="Person">
<data
required="false"/>
</element>
<element type="Father"
extends="Adult">
<attribute
name="employer" type="String"
required="true"/>
</element>
<element type="Child"
extends="Person">
<data
required="false"/>
<attribute
name="nickname" type="String"
required="true"/>
</element>
<element type="Hobby">
<attribute
name="description" type="String"
required="true"/>
<attribute
name="hazardous" type="Boolean"/>
</element>
</schema>
Here is a message adhering to the above schema. Not shown are the transmitted attributes with the reserved names __class__ and __name__ , which are described in Section 3.3
<Family command="echo"
familyName="Smith" description="Nice folks">
This is Smith family data
<Father
employer="DisneyWorld" name="John">
<Hobby
description="Fishing" hazardous="false"/>
<Hobby
description="Hunting" hazardous="true"/>
</Father>
<Child nickname="Jambo"
name="James" birthday="Mon Nov 01 17:46:15 PST 2004">
<Hobby description="Chasing
girls" hazardous="true"/>
<Hobby description="Electric
Trains" hazardous="false"/>
<Hobby
description="Fishing" hazardous="false"/>
</Child>
<Child nickname="Ricky"
name="Richard" birthday="Tue Jan 15 17:55:00 PST 1867">
This is Ricky's stuff
<Hobby description="Chasing
girls" hazardous="true"/>
<Hobby description="Electric
Trains" hazardous="false"/>
</Child>
<Child nickname="Sal"
name="Sally">
This is Sally's stuff
<Hobby description="Dolls"
hazardous="false"/>
<Hobby
description="Skating" hazardous="true"/>
</Child>
<Child nickname="Sue"
name="Susan">
</Child>
</Family>
A few things to note:
One java class is generated for each XML message element declared in the schema. The left column in the table below shows the schema definitions introduced earlier. The right column shows the generated class declaration, and the members corresponding to element attributes, child elements, and enclosed text. Method code and class member access modifiers are not included, nor are the boolean flags which define which members are required.)
Schema Element |
Java Class
Definition |
<element
type="Family"> <data required="true"/> <attribute name="command"
type="String" <attribute name="familyName"
type="String" <attribute name="description"
type="String"/> <child name="father"
type="Father" <child name="sons"
type="Child" array="true" <child name="daughters"
type="Child" </element> |
public
class Family extends IdcAbstractElement { public java.lang.String command; public java.lang.String familyName; public java.lang.String description; public Father father; public Child[] sons; public Child[] daughters; public String __data__ = null; } |
<element
type="Person" abstract="true"> <attribute name="name"
type="String" <attribute name="birthday"
type="Date"/> <child name="hobbies"
type="Hobby" </element> |
public
abstract class Person public java.lang.String name; public java.util.Date birthday; public Hobby[] hobbies; } |
<element
type="Adult" abstract="true" <data required="false"/> </element> |
public
abstract class Adult extends Person { public String __data__ = null; } |
<element
type="Father" extends="Adult"> <attribute name="employer"
type="String" </element> |
public
class Father extends Adult { public java.lang.String employer; } |
<element
type="Child" extends="Person"> <data required="false"/> <attribute name="nickname"
type="String" </element> |
public
class Child extends Person { public java.lang.String nickname; public boolean __required__nickname =
true; public String __data__ = null; } |
<element
type="Hobby"> <attribute name="description"
type="String" <attribute name="hazardous"
type="Boolean"/> </element> |
public
class Hobby extends IdcAbstractElement { public java.lang.String description; public java.lang.Boolean hazardous; } |
Attributes specified as optional (by default or specifying required=”false” in the schema), are represented by null object references populated by unmarshalling from an XML message.
The Binder generates the following set of methods for each class. Most are required by the Marshaller, but they all have public access, and are usable by the application code:
The following two element attributes appear in the transmitted elements, have no correspondence to class members of the generated classes:
· __class__ carries the full class name
· __name__ class member name in the parent object to which the element is to be assigned
Note that elements should not be
defined which would cause conflicts with the standard method and reserved
attribute names; for example, an attribute named textElementData is
invalid. The Binder will throw an exception if such names are encountered.
System generation is the process of reading the schema file and generating the Java source code of the classes corresponding to the messages defined in the schema. This is performed by the com.protocol.xml.util.Binder class.
The following parameters are required by the Binder:
· path to a schema definition file
These parameters are provided to the Binder in a properties file. Refer to the javadoc of the main() method of the Binder class for more details.
On the client, the com.protocol.xml.client.Connector class is used to send all messages. It contains a single static send() method to perform the marshalling of Java objects into XML messages, and transmission of the messages to the server. This method employs Java reflection to determine the structure and format of the XML message. Thus the schema definition is required only at “system generation” time, when the Java source files are generated, but not at runtime.
Each XML element generated during marshalling includes an additional attribute not defined in the schema. The string “__class__” is reserved for the name of this attribute, which carries the fully qualified name of the Java class bound to the message type.
A single Servlet of class com.protocol.xml.server.Servlet receives the XML messages and unmarshalls them into Java objects of the class specified in the “__class__ attribute. The resulting objects are then dispatched to processing objects (Data Managers) via the com.protocol.xml.server.MessageProcessor interface. If a response object is returned by the MessageProcessor, the servlet marshals it into an XML message, and returns it to the client.
Mappings of messages to MessageProcessor objects are defined in a configuration file. The name and location of the file are specified in a web application <init-param> element in the web.xml file.
The Simple XML Protocol Binder consists of four packages:
· com.protocol.xml.util: contains the Binder class, which generates the Java source files according the XML message schema.
· com.protocol.xml.client: contains the Connector class for sending XML messages to the server
· com.protocol.xml.server: contains the Servlet class and the MessageProcessor interface for processing received messages
· com.protocol.xml.common: contains classes common to both the client and the server
The util package is not required at application runtime. The client and common packages must be included in the client. The server and common packages must be included in the server web application.
The client side Connector class is initialized with a single static URL as a destination for transmitted messages. Refer to the javadoc for more details.
The web application configuration file contains one required and one optional Servlet initialization parameter, as shown below:
<init-param>
<param-name>messageMapFile</param-name>
<param-value>WEB-INF\messageMap.xml</param-value>
</init-param>
<init-param>
<param-name>loggingEnabled</param-name>
<param-value>true</param-value>
</init-param>
The required messageMapFile parameter specifies the context-relative path to the message map file. The format of the map file is of the form:
<map>
<message type="MMMM" processor="PPPP"/>
<message ……etc.
</map>
where MMMM is the type of a message, and PPPP is the package qualified name of the corresponding MessageProcessor class
The optional loggingEnabled parameter turns logging on or off. The default is off. If turned on (true), then each received message is logged, after the successful creation of the Java object, in its full xml document form.