A client application handles XML documents by using an accessor to pass
TXMLObject
instances to Tamino.
TXMLObject
supports DOM and JDOM as object models, but
you can add other object models as well. This document explains the steps
involved using DOM4J as an example.
The underlying XML object model is represented by the abstract base
class TXMLObject
. Using a factory method you can
instantiate a TXMLObject
that serves as an adapter to
the object model. DOM and JDOM are directly supported as object models, but you
can dynamically plug in other object models provided that the client offers an
implementation for TXMLObjectModel
.
TXMLObjectModel
provides meta-information that defines
the object model so that it can be used within the API.
In the context of the Tamino API, you use an XML object model as follows (xxx here stands for an arbitrary object model):
Use a TConnectionFactory
to create a
TConnection
instance for establishing a connection to a
Tamino database
Create an instance of the
TxxxObjectModel
.
Let the TConnection
create an Accessor for the
TxxxObjectModel
.
Now you can use the Accessor to send a query to Tamino.
The resulting TResponse
instance is able to
create the Document
instance specific to that object
model.
An object model is defined by the following classes:
the generic class or interface of the underlying object model that
represents the root node type for an XML document; for DOM4J this is the
Element
interface.
TXMLObject
adapter implementation which adapts
some interfaces of the underlying object model
an implementation for interpreting the input stream
As a consequence, the abstract base class
TXMLObjectModel
defines operations to access the meta
class for the node type, the TXMLObject
adapter and the
TResponseBuilder
. To use a new object model you need to
provide the appropriate TXMLObjectModel
implementation
along with the TXMLObject
adapter and the
TxxxInputStreamInterpreter
implementation.
The TxxxObjectModel
describes which xxx specific Document
,
Element
,
TxxxAdapter
and
TxxxInputStreamInterpreter
is
used by the xxx object model.
To use this object model it must be registered in the
TXMLObjectModel
with the method:
TXMLObjectModel.register(TXMLObjectModel
xmlObjectModel)
.
A
TxxxElementIterator
is needed
to navigate unidirectional and type safe over the xxx specific Elements.
TxxxInputStreamInterpreter
interprets the TAMINO Stream and creates the xxx specific
Document
instance
The TxxxAdapter
adapts to the xxx specific object model to the generic
TXMLObject
interface.
In this section we use DOM4J as an example to show which classes are needed for the implementation of a new object model. You can use the example code available with this documentation ( <Tamino installaion directory>/SDK/TaminoAPI4J/Documentation/inoapi/listings/dom4j/ ) as a template for supporting another object model in the Tamino API.
In the following sections we discuss the implementation of the classes needed based on the DOM4J object model implementation.
First, you must determine a short name for the object model, by which all classes are recognized as belonging to the adapter implementation of the same object model. Here, we use "xxx" as name to refer to the new object model adapter.
You need to create two packages, one containing the complete implementation of the object model adapter and another package with the implementation of the input stream interpreter. Using "xxx" the package names are as follows:
com.softwareag.tamino.db.api.objectModel.xxx
com.softwareag.tamino.db.api.response.xxx
TXMLObject
is the abstract super class to
represent an XML object. To create the specific adapter class, this class must
be extended. Example:
com.softwareag.tamino.db.api.objectModel.dom4j.TDOM4JAdapter
How to implement the
TxxxAdapter
Copy the class
com.softwareag.tamino.db.api.objectModel.dom4j.TDOM4JAdapter
to the new package:
com.softwareag.tamino.db.api.objectModel.xxx
Rename the adapter class to:
com.softwareag.tamino.db.api.objectModel.TxxxAdapter
Replace the references to org.dom4j.Element
and org.dom4j.Document
with references to appropriate
classes of the object model "xxx".
In the implementation of the object model, identify and use the methods that perform the following tasks:
get the related Document
remove an Attribute
get an Attribute
add an Attribute
set a value
get the qualified name
get the root element
You also need a way to read an InputStream and create your specific
Document instance. In DOM4J this is SAXReader
, which is
used in the readFrom()
methods.
The best way to make these changes is to replace the import instructions in your new Adapter class (e.g. replace dom4j specific imports by imports for your new model), and to check any compiler messages about missing methods.
How to implement the
TxxxInputStreamInterpreter
Copy the class
com.softwareag.tamino.db.api.response.dom4j.TDOM4JInputStreamInterpreter
to the new package:
com.softwareag.tamino.db.api.response.xxx
Rename the class to:
com.softwareag.tamino.db.api.response.TxxxInputStreamInterpreter
In the import instructions replace the following classes
org.dom4j.Document; org.dom4j.Element; org.dom4j.Namespace; org.dom4j.QName; org.dom4j.DocumentException; org.dom4j.io.SAXReader;
with the corresponding classes of the new object model.
In the implementation of the new object model, identify these
classes and methods of DOM4J and change it appropriately for
TxxxInputStreamInterpreter
:
Class | Method |
---|---|
org.dom4j.Document |
getRootElement() |
org.dom4j.Element |
element() |
elements() |
|
attributeValue() |
|
getText() |
|
org.dom4j.Namespace |
get() |
org.dom4j.QName |
|
org.dom4j.DocumentException |
|
org.dom4j.io.SAXReader |
read() |
TXMLObjectModel
contains operations needed to
define and control an XML object model. Each XML object model is defined by
four class instances:
Element
An Element
class represents either an element
or a fragment of the document tree.
Document
A Document
class represents the complete
document.
Adapter
An Adapter
class adapts the physical object
model to TXMLObject
.
InputStreamAdapter
An InputStreamInterpreter
class determines
for a physical object model the way to handle response documents returned by
Tamino.
How to implement the
TxxxObjectModel
Copy the class
com.softwareag.tamino.db.api.objectModel.dom4j.TDOM4JObjectModel
to the new package:
com.softwareag.tamino.db.api.objectModel.xxx.TxxxObjectModel
Change the constructor
protected TxxxObjectModel() { super( "xxx" , xxx.Document.class , xxx.Element.class , com.softwareag.tamino.db.api.objectModel.xxx.TxxxAdapter.class , com.softwareag.tamino.db.api.response.xxx.TxxxInputStreamInterpreter.class ); }
You must use your specific Document
,
Element
, Adapter
and
InputStreamInterpreter
classes.
Change occurrences of TDOM4JObjectModel
to
TxxxObjectModel
.
If your object model does not provide a class to serialize XML into a string, you have to write your own class.
How to implement an outputter class:
Copy the classes
com.softwareag.tamino.db.api.objectModel.dom4j.TDOM4JXMLOutputter com.softwareag.tamino.db.api.objectModel.dom4j.TDOM4JNamespaceStack
into the package
com.softwareag.tamino.db.api.objectModel.xxx
Rename these classes as:
com.softwareag.tamino.db.api.objectModel.xxx.TxxxXMLOutputter com.softwareag.tamino.db.api.objectModel.xxx.TxxxNamespaceStack
You must replace the following classes and methods:
Class | Method / Constant |
---|---|
org.dom4j.Attribute |
getNamespace()
|
getQualifiedName()
|
|
getValue() |
|
org.dom4j.CDATA |
asXML() |
org.dom4j.Comment |
asXML() |
org.dom4j.DocumentType |
getPublicID()
|
getSystemID()
|
|
getElementName()
|
|
org.dom4j.Document |
getRootElement()
|
org.dom4j.Element |
getDocument()
|
getNamespacePrefix()
|
|
getParent() |
|
elements() |
|
getQualifiedName()
|
|
getNamespace()
|
|
additionalNamespace()
|
|
attributes()
|
|
getTextTrim()
|
|
getText() |
|
org.dom4j.Entity |
asXML() |
org.dom4j.Namespace |
get() |
XML_NAMESPACE()
|
|
NO_NAMESPACE()
|
|
getUri() |
|
getPrefix() |
|
org.dom4j.ProcessingInstruction |
In the implementation of
TxxxXMLOutputter
replace
occurrences of TDOM4JNamespaceStack
with
TxxxNamespaceStack
.
At this point, you have a complete implementation of all necessary classes. Compile these classes, include them and those of the original object model in the class path. You can then use the new object model in your client applications.
To use the implementation for the DOM4J object model you need the DOM4J implementation which you can download at http://www.dom4j.org/. You need to include the DOM4J classes and the adapter classes in your classpath. You will find the adapter classes in the file JavaTaminoAPIExamples.jar in the directory <TaminoAPIDir>/examples.
In the sample below you can see how to register the new object model so that the Tamino API knows about it. In the last line, an accessor is instantiated that uses the new object model.
// Constant for the database URI. Please edit to use your URI of interest. private final static String DATABASE_URI = "http://localhost/tamino/mydb"; // Obtain the connection factory TConnectionFactory connectionFactory = TConnectionFactory.getInstance(); // Obtain the connection to the database TConnection connection = connectionFactory.newConnection( databaseURI ); // Instantiate the specific TxxxObjectModel TxxxObjectModel xxxObjectModel = TxxxObjectModel.getInstance(); // Register the object model TXMLObjectModel.register( xxxObjectModel ); // Obtain the concrete TxxxObjectAccessor with an underlying xxx object model TXMLAccessor accessor = connection.newXMLObjectAccessor( TAccessLocation.newInstance( "ino:etc" , xxxObjectModel );