Individual DataBeans rely on an underlying binding framework that allows the components of a document to be mapped to in-memory objects reflecting the document’s structure. These objects can then be consumed, manipulated, and possibly serialized back into a document. The runtime classes making up the binding framework provide the implementation of all get() and set() methods exposed for access to class instances, attributes, and data. They also handle deserialization (parsing a document into a set of related classes), serialization (generating a document from the data stored in the related classes) and validation.
It is important to understand the DataBean object graph in order to access these features correctly. When a schema is imported into Message Bridge, a root element is identified directly by Message Bridge itself, or is selected by the user. When code is generated, Message Bridge creates two types of DataBeans::
A Root DataBean that represents the root element of a complete document described by a schema
Zero or more additional Element DataBeans that represent the document’s member elements, attributes, and data
Both Root and Element DataBeans expose various types of get() and set() methods that are used to navigate through objects in the object graph and to access or modify the content of those objects. All DataBeans extend class DataBeanElement.
Figure 2-1: DataBean object graph
Root DataBeans expose additional methods for interacting with the main document they represent. This main document is an instance of a document that conforms to a schema and has a given root. All Root DataBeans extend class DataBeanOpaque, which itself extends class DataBeanElement.
All DataBeans expose the following methods:
get() methods to access member class instances, attributes, and data
set() methods to modify member class instances, attributes, and data
Root DataBeans also expose the following additional methods:
Constructors to create a new DataBean object graph
get()and set() methods to identify and retrieve the main document
get() and set() methods to access and modify the root name and the location of the source schema for the main document
Methods to serialize and deserialize a document
A method to validate a document
The set of strings allowed in schemas is much larger than the set of valid Java class identifiers. Therefore, Message Bridge will change the names of schema components when generating DataBeans, according to the following approach. Message Bridge:
Splits the XML name into a word list by removing any leading and trailing punctuation characters and then searching for word breaks
Converts the first character of each word to uppercase
Converts the rest of the characters of each word to lowercase
A good way to illustrate DataBean is to work through an example. In this example, Message Bridge generates bindings for a Recipe schema defined in the following DTD:
The following DTD, called Recipe, is mapped to Java classes described in Table 2-1.
XML document instances conforming to this DTD can have two potential roots: recipe and comments. In this example, recipe is the root.
<!ELEMENT Recipe (#PCDATA | IndexCard | IngredientList StepList)* >
<!ELEMENT IndexCard (Name, Description, Source) >
<!ELEMENT Name (#PCDATA)>
<!ELEMENT Description (#PCDATA)>
<!ELEMENT Source (#PCDATA)>
<!ELEMENT IngredientList (Ingredient+)>
<!ATTLIST IngredientList serves CDATA #REQUIRED>
<!ELEMENT Ingredient (Food,Quantity) >
<!ELEMENT Food (#PCDATA)>
<!ELEMENT Quantity (#PCDATA)>
<!ELEMENT StepList (Step+) >
<!ELEMENT Step (#PCDATA)>
<!ELEMENT Comments (#PCDATA)>
A summary of how schemas are mapped to classes follows:
For each element in the schema there is a corresponding Java class.
If the element has data, setData() and getData() methods are provided to access and manipulate the element data.
An element containing attributes is mapped to a Java class containing an instance variable for the entire set of attributes.
Elements having attributes contain the methods setAttribute<attribute name>() and getAttribute<attribute name>() in their class for accessing and manipulating the attributes.
For elements with children, get() and set() methods are provided to access and modify child elements.
The get<element name>() methods are used to access child element class instances. They return opaque java.lang.Object. The get() methods always return a valid class instance, and through the hasValidElement() method, you can find out if the class instance holds a valid element.
The set<element name>() methods are available to access the existing child element class instances or create new child element class instances.
The root element class has more methods than member element classes because validation, serialization, deserialization and other methods are provided in the root class only.
The following table shows some highlights of the DataBeans generated for the Recipe DTD:
This section contains examples of code written using generated DataBeans from the previous Recipe DTD.
The following
example illustrates constructing instances of Recipe classes from
an XML document. In this example, false
means
there is no validation against a DTD document.
FileInputStream fiStream = new
FileInputStream
xmlFileName);
Recipe iRecipe = new Recipe(fiStream,
false);
or
FileInputStream fiStream = new
FileInputStream
xmlFileName);
Recipe iRecipe = new Recipe();
iRecipe.deserializeXML(fiStream, false);
IngredientList ingList = iRecipe.getIngredientList();
String serves = ingList.getAttributeServes();
To get the first ingredient:
Ingredient
ing = ingList.getIngredient(0);
if(
!ing.hasValidElement())
{
// We
are at the end of the list of Ingredients ing=null;
break;
}
To target all ingredients:
java.util.List ings=ingList.getIngredients();
Recipe oRecipe = new Recipe();
oRecipe.setIngredientList(0).setIngredient(0).
setFood().setData(“Onions”);
oRecipe.setIngredientList(0).setIngredient(0).
setQuantity().setData(“2”)
FileOutputStream foStream = new
FileOutputStream
(xmlFileName);
oRecipe.serializeXML(foStream);
FileInputStream fiStream =
new FileInputStream(xmlFileName);
DataBeanOpaque recipeVersionUnknown =
new DataBeanOpaque(fiStream, false);
String dtdName = recipeVersionUnknown.
getDocTypeSystemID();
if (dtdName.equals("recipe.dtd"))
{
// Do
something with version 1 recipes
.
com.cooksmart.v1.Recipe = new com.cooksmart.v1.Recipe(recipeVersionUnknown, true);
.
.
}
else
{
if
(dtdName.equals("recipe_v2.dtd"))
{
// Do
something with version 2 recipes
.
com.cooksmart.v2.Recipe = new com.cooksmart.v2.Recipe(recipeVersionUnknown, true);
.
.
}
}
Copyright © 2005. Sybase Inc. All rights reserved. |