Introduction
XTAS XML Java API aimed to *manipulation* XML data from both: non-persistent source that can be generated programmatically (Java stream, DOM, Mapped Java-Object for instance) and
persistent source that can be retrieved/stored in/from some XML-enabled "Resource" (XML file or XML enabled DB for instance) with or without validation rules,
locally or remotely. Manipulation means selection/modification an XML tree part.
Query
The core XTAS entity is Query - command by which XTAS manipulates data.
It is possible to use the core xtas.Query class for local query execution or
some implementation of xtas.client.QuerySupport interface for local/remote query execution (flexible way).
The most common way of query using is:
- Query[Support] query = new Query[SupportImplementation]();
- query.prepare(statement, [context]); // use some implementation of Statement for query preparation.
- query.setInput(tree); //OPTIONAL sets some non-persistent source (UniFormTree object) for query
- query.execute(); //executes query
- UniFormTree result = query.getResult(); //retrieves query result
AND/OR
- query.serialize(); //stores the result tree
Statement
Statement (xtas.Statement) - object describes what this query have to do.
For the time being there are two concrete subclasses of Statement:
xtas.SimpleStatement describes one Intruction to execute and xtas.XTASMLStatement describes what to do over an XML.
Each Statement MUST have Instruction (may be the list of instruction in prospect) and MAY have source and destination IDs -
links to persistent input/output resources.
Query.prepare() can use Statement along with java.Object called resource context that can be neccessary for source/destination Resources (see below).
There are two kinds of instructions: Content (XML) and Resource instructions.
Every Content instruction in Query run-time retrieves XML from source Resource or uses XML from query.setInput(tree)
using XPath statement (like WHERE in SQL's SELECT query). For a good tutorial on XPath you could try this XPath-Tutorial.
Resulting XML as xtas.UniFormTree can be retrieved from Query through query.getResult() or stored to destination Resource.
There are 4 types Content instructions handling XML data:
- SELECT - selects XML fragment without modification.
- DELETE - deletes XML fragment.
- APPEND - inserts new XML fragment.
- UPDATE - updates XML fragment.
In XML Statement with Content instruction looks like:
<query [destination="resourceId"] [source="resourceId"]>
<select|append|update|delete xpath=Xpath-Expression>
[new value for update|append]
</select|append|update|delete>
</query>
Every Resource instruction requires resourceId and, for CREATE - initial XML tree.
There are 2 types of Resource instructions handling XTAS Resources:
- CREATE - creates Resource (on execute stage) and writes initial XML tree there.
- DROP - deletes Resource.
In XML Statement with Resource instruction looks like:
<query>
<create|drop resource="resourceId">
[Initial-XML-tree]
</create|drop>
</query>
Resource
Resource (xtas.Resource) encapsulates persistence storage for XML data.
Query deals with source and destination Resources by such a way:
- In prepare() - recognizes resource(s) type by resource identifier in Statement (see below)
and creates source, destination and resource context objects. Loads resource content.
- In execute() - executes Resource Instructions (without saving an Initial-Tree for CREATE).
- In serialize() - saves query result to Resource.
Resource type can be recognized by its prefix.
The list of resources types as for XTAS 0.6 beta (stay tuned):
type | prefix | context type | example |
xtas.resource.LocalFile | no | no | /test/xml/test.xml |
xtas.resource.ServletResource | servlet: | javax.servlet. ServletContext | servlet://xml/test.xml |
xtas.resource.XmlDbResource | xmldb: | org.xmldb.api.base. Database | xmldb:xindice-embed://db/ my_collect#my_resource |
XML Tree (UniFormTree)
Whichever fomat is used for the in/out XML tree it will be thansformed to the some subclass of
xtas.UniFormTree class. There are 2 subclasses: WellFormedUniFormTree and UniFormTreeFragment.
WellFormedUniFormTree is generally used for the XTAS query input and output dataflow
(your always read Query's InputSource as well as serialize the result to this type of object) and represents well-formed XML
that can be validated and transformed to the DOM Node or SAX InputSource.
UniFormTreeFragment is used as the query result (query.getResult()) and represents in common case an XML fragment.
So it can not be converted to the "strict" XML form and validated - only Stream or Collection types of conversion are usable in this case.
NOTE:
- In spite of the fact that Query.setInput(UniFormTree input) uses abstract UniFormTree as a parameter so it is possible to set an UniFormTreeFragment here - this object MUST be convertable to WellFormedUniFormTree (contains well-formed XML inside).
- Actually UniFormTree Query.getResult() returns an UniFormTreeFragment object but this object MAY be convertable to WellFormedUniFormTree.
(see JavaAPI documentation for details)
XML/Java Object marshalling
It is possible to use some Java Bean as source for XTAS query as well as transform resulting tree to the Collection of Java Objects (Beans).
Third party (Exolab Castor at the moment) marshaller/unmarshaller/mapper is used for these purposes. There are two options of JavaObject/XML mapping:
Internal (or implicit) mapping - use objects class introspection and mapped classes properties using internal (Mapper implementation dependend) mechanism for property-XML nodes/attributes mapping.
External (or explicit) mapping - use some (Mapper implementation dependend) description for property-XML nodes/attributes mapping
(see JavaAPI documentation for details)
Client/Server
XTAS' architecture provides possibility of using client/server environment so it is possible to manage remote XML data
For the time being there is an XML-RPC based server-side (xtas.server.XmlRpcServlet) so provided xtas-xmlrpc.war Web-archive that is simply deployed in Servlet/JSP container (Tomcat for instance).
It is possible to call RPC execute with a corresponding message ("prepare", "execute", "serialize", "getResult", "setInput") directly or simply use xtas.client.XmlRpcQuery object as helper.