Architectural Overview

This document explains the general architecture of the Tamino API. The following sections are provided:


API Overview

This section introduces key concepts that are required for an understanding of the Tamino API architecture. The general concept follows a component and object-oriented development approach and is described here without referring to the features of a specific object-oriented programming language.

The following graphic shows the Tamino API architecture:

Tamino API Architecture Overview

Tamino API Components

For the client application only the Connection, Accessor, Object Model and Response components are of interest. The Command Invocation component is only for internal use and is invisible to the client application.

Connection

The entry point to the API is the Connection component. It is needed to establish a connection to a Tamino database. Within the context of a Connection, Tamino specific services are executed and results are returned. An integral part of this component is to provide transaction support, i.e., the starting and finishing, by commit or rollback, of Tamino transactions.

Accessor

The Accessor provides high-level services to invoke specific operations on the Tamino database. This comprises insert, update, delete and query operations on Tamino XML documents as well as operations to access non-XML documents or meta data (e.g. what doctypes are stored under a specific collection).

In general, a distinction is made between access to XML or non-XML documents. The client uses an Accessor instance that is capable of accessing either XML or non-XML documents, but not both.

XML Object Model

This component describes how concrete documents that are storable in Tamino are represented. In general, XML and non-XML are treated differently. This is reflected by different classes within the object model. TXMLObject is the abstraction of XML documents whereas TNonXMLObject is used for the abstraction of non-XML documents.

Furthermore TXMLObject represents a facade to the underlying object model (DOM, JDOM, and others). This ensures a loose coupling between the API and the concrete XML object representation. Since each object model is represented by its own class, the client simply chooses the desired object model by instantiating the corresponding class such as TDOMObjectModel.

Response Builder

The role of this component is to build from low level results (XML or Non-XML documents within input streams) as they are returned by Tamino, high level response objects. Once the client has invoked a certain operation on an accessor, a high level Tamino response object is returned. The information that can be found in such a response object can be categorized as follows:

  • Response Information
    Each Tamino response document contains general context information that is related to the previous request. This includes information such as return values, message codes, session ids, session keys etc. Generally, response information is always contained within a Tamino response document.

  • Query-related XML documents
    XML documents that are returned in response to XML related queries are nested within Tamino's response documents. In this case the corresponding response object provides a TXMLObjectIterator that can be used to navigate in a type-safe manner over the resulting TXMLObject instances.

  • Query-related Non-XML documents
    Non-XML documents are returned in response to non-XML related queries. In this case the corresponding response object provides a TNonXMLObjectIterator that can be used to navigate in a type-safe manner over the resulting TNonXMLObject instances.

Exception Handling

Each component that is part of the architecture is responsible for its own exception handling. Exceptions that can be thrown to the outside are always component specific. Therefore, the client only receives component specific exceptions during the interaction with the component.

Each component defines a base class exception that contains more detailed component specific exceptions. The base class exception's name consists of the component name with the suffix Exception. For example, the Connections component base class exception is named TConnectionException. Furthermore each of these base class exceptions is derived from the most common API exception TException.

However, the situation is different when pre- or postconditions are violated for operations that are invoked by the client. In the case of contract violation, an ViolatedPrecondition or ViolatedPostcondition exception is thrown by the affected component. These exceptions are applied for any type of pre- and postcondition violations.

Each component can only throw either component specific exceptions or the API wide defined pre- and postcondition violation exceptions. It is not possible that a component directly throws an exception that originates from another internal client component. In these situations it is more likely that an exception that might be thrown is carried piggyback so that the client can retrieve it.

Interfaces

This section introduces component-specific interfaces that the application developer has to be aware of for an in depth understanding of the API. The term interface here means any type of class that is part of a component's facade. According to UML this can be a concrete class, abstract class or an interface class which only defines a set of abstract operations. The interfaces a component offers can be distinguished in service oriented interfaces and exception specific interfaces. The first generally defines the services a component offers while the second defines the component’s manner in exceptional conditions.

The UML component diagram shown below depicts the most relevant service interfaces that serve as facades to their owning components.

Tamino API Architecture Overview

Please note that you use different classes when you process non-XML data instead of XML data:

XML Data Non-XML Data
TXMLObjectAccessor TNonXMLObjectAccessor
TXMLObject TNonXMLObject
TXMLObjectIterator TNonXMLObjectIterator

Connection

A client always gets access to the API by acquiring a concrete TConnection instance from a TConnectionFactory. TConnection introduces all operations that are needed to access the concrete accessor objects, so that this is the entry point to the Accessor component. Furthermore it provides access to the TLocalTransaction instance that is bound to the client's connection. TLocalTransaction contains all the operations to work with Tamino in a transaction context, which means that transactions can be started, committed or rolled back.

Accessor

The high level access to Tamino is accomplished by using a concrete TAccessor instance. A concrete accessor class implements the common TAccessor interface and provides a set of logically grouped access operations. Currently, there are the following concrete accessor classes: TNonXMLObjectAccessor for access of non-XML objects, TXMLObjectAccessor for access of XML objects, TStreamAccessor for the stream-based access of XML objects, TSystemAccessor for access to system information, TSchemaDefinition2Accessor for accessing database schema information in TSD2, TSchemaDefinition3Accessor for accessing database schema information in the current schema language, based on XML Schema, and TAdministrationAccessor for issuing Tamino XML Server _admin commands.

A TNonXMLObjectAccessor uses a given TNonXMLObject instance as the non-XML document representation for an insert or delete operation. TQuery is used for the retrieval of non-XML documents stored in Tamino. In the same way a TXMLObjectAccessor uses a given TXMLObject instance for an insert, update or delete operation. TQuery is the representation of a Tamino X-Query expression and is used for the XML document retrieval.

To obtain a concrete accessor, the client always has to use a TConnection instance that defines the database session with Tamino. Each accessor instance is logically bound to a specific database session. Once the client starts a transaction on the connection’s TTransaction instance, the transaction context also affects all accessors that are currently running within the connection context. As a consequence a commit or rollback takes place on all accessor specific operations that have been invoked during the transaction context.

Object Model

Documents that are storable for Tamino are either represented by the class TXMLObject for XML or by the class TNonXMLObject for non-XML. The client uses a non-XML accessor to pass TNonXMLObject instances back and forth to Tamino and proceeds in the same way concerning XML accessors and TXMLObject instances.

The common abstraction to all Tamino documents is TDataObject which also serves as a base class to TNonXMLObject and TXMLObject. TNonXMLObject basically contains the non-XML data as an input stream. This can be provided by the client as input data for insert operations to Tamino or as an input stream which Tamino returned as the result of a query operation.

The abstract base class TXMLObject represents a facade to the concrete underlying XML object model. A factory method can be used to instantiate a concrete TXMLObject class that serves as an adapter to the object model. In Java, TXMLObject supports the instantiation of instances that use DOM or JDOM as object model. Other object models can be dynamically plugged in when the client provides implementations for TXMLObjectModel. The purpose behind TXMLObjectModel is to provide meta-information that defines the concrete object model so that the API is able to work with it on demand.

Response

Tamino responds to a command invocation such as _xquery, _xql, _process, _delete, etc. with an XML response document. It contains general response information as well as the result set, which consists of the documents returned from Tamino. You can access this response information by an instance of TResponse. It always contains information on the execution result such as the response code.

graphics/apiresp1.png

When the client invokes a query operation for XML documents, the TResponse instance provides a TXMLObjectIterator that can be used to navigate in a type-safe manner over the result set of TXMLObject instances. However, if the client only wants to obtain the first document, getFirstXMLObject on the TResponse instance is invoked to avoid the additional indirection with the iterator.

The situation changes when the client wants to access non-XML documents. In this case Tamino does not always respond with XML result documents. When non-XML documents are retrieved, Tamino directly returns the non-XML documents rather than responding with XML response documents. The API however hides this mechanism and behaves for non-XML in much the same way as with XML access. As a consequence, the client works with non-XML documents in the same way as when accessing XML documents. The non-XML classes are used to access Taminos non-XML documents. When the client invokes a query operation for non-XML documents with the TNonXMLObjectAccessor, the TResponse instance provides a TNonXMLObjectIterator that can be used to navigate in a type-safe manner over the result set of TNonXMLObject instances. If the client only wants to obtain a single non-XML document, the getFirstNonXMLObject operation on the TResponse instance can be used.

graphics/apiresp2.png

The API hides the fact that Tamino handles non-XML objects in a different way than XML objects.

Query

As already mentioned, a clear distinction is made between the handling and access of XML and non-XML documents.

An abstraction of Tamino query expressions formulated in X-Query is the class TQuery which is a single class needed to retrieve both XML documents and non-XML documents when using the SoftwareAG proprietary query language X-Query based on XPath.

For X-Query's successor XQuery there is the class TXQuery available to retrieve XML documents when using the query language XQuery propagated by the W3C. Retrieval of non-XML documents using XQuery is currently not implemented.

Access Methods and Response Processing

Access Methods

The Tamino API for Java provides several different ways to access and store documents in Tamino and different ways to process the response returned by Tamino. Different accessors offer access to Tamino on different abstraction levels.

The lowest level of access to Tamino is available through the TStreamAccessor. It treats all documents as streams of bytes or characters. It delivers the entire response document returned by Tamino as a single stream. The TStreamAccessor does not process or interpret the Tamino response document. The interpretation of the response document is up to the client program.

On a higher abstraction level, the Tamino API offers the interfaces TXMLObjectAccessor and TNonXMLObjectAccessor. These interfaces treat each document as a separate object represented by the TXMLObject and TNonXMLObject interfaces.These accessors process and interpret the response documents returned by Tamino and separate the result information (return value, message, cursor information etc.) from the result content. These accessors are capable of supporting different object models. An object model defines, how XML documents contained in Tamino responses are delivered to the client program and how the client program delivers documents to Tamino (DOM, JDOM, SAX, stream).

Note the differences between a TStreamAccessor and the stream object model. The stream object model offers stream access to XML documents contained in the result content, while the TStreamAccessor offers stream access to the whole Tamino response, without further interpretation of the response document. The stream object model works with TXMLObject instances, whereas TStreamAccessor works with TInputStream instances.

Note:
The TStreamAccessor delivers the Tamino XML Server response as a stream without any XML parsing, thus being considerably faster than all other object model based accessors. Notably, the largest part of processing time when using the Tamino API for Java is spent for parsing of XML documents. This should be taken into consideration when optimizing performance.

Apart from the previously mentioned accessors there are specialized accessors available which provide access to specific types of information. The TSchemaDefinition2Accessor and the TSchemaDefinition3Accessor provide methods to access and store schema information. The TSystemAccessor and the TAdministrationAccessor provide access to system information.

Response Processing

The result of a Tamino response is contained within the xql:result node of the Tamino response document. It can be a list of XML documents or a list of literals (strings, numbers etc.). The API offers access to a list of XML documents via the document iterators (TXMLObjectIterator and TNonXMLObjectIterator), which can be obtained from the TResponse class. However, there are convenience methods in the TResponse object to directly access the first document of such a list.

You can directly access literals in the result content with the TResponse method getQueryContentAsString(). Currently, the Tamino response does not contain any type information for literals, so they are always returned as strings and the client program has to convert them.