The InoManager, which is responsible for accessing the
Tamino database, can
Deleting a document requires a document ID. The default
implementation uses the ino:id. This behaviour can hardly
be recommended, but there is no other possible key for
a default implementation. Thus it is suggested that you
use your own key (for example an attribute myid,
which all documents must have) and derive some subclass from
the InoManager.
Reading data from a Tamino database
First of all, like any application using Tamino, we have to
specify some values, in particular the Tamino database URL
(including the collection!). This is done in an XML file:
<?xml version="1.0" encoding="UTF-8" ?>
<JMManagerConfiguration
xmlns="http://jaxme.ispsoft.de/namespaces/JMManagerConfiguration">
<Defaults>
<InoManager>
<DbURL>http://127.0.0.1/tamino/test</DbURL>
<User>sa</User>
<Password/>
<ManagerClass>de.ispsoft.jaxme.tamino.InoManager</ManagerClass>
</InoManager>
</Defaults>
<Configuration
localName="Session"
namespaceURI="http://jaxme.ispsoft.de/namespaces/examples/Session">
<ElementClass>com.mycompany.session.ClsSession</ElementClass>
<HandlerClass>com.mycompany.session.ClsSessionHandler</HandlerClass>
</Configuration>
</JMManagerConfiguration>
Things you should note here:
- The configuration works much the same than the configuration
of the JDBC access.
Unlike the JDBC case, there is a generic manager for all
document types. In particular, you don't need the
XsdJdbcSchemaReader or the
JdbcJavaSourceWriter. The standard
XsdSchemaReader and the
JavaSourceWriter will do.
Of course you still have the
ability to derive your own subclass of InoManager and
configure that. And, as the JDBC reader and writer are
upwards compatible, you can still use these, if you like.
- As in the JDBC manager case, you do not need to use this
XML file. You might as well create your own instance of
InoManager, configure that with
setDbURL()
,
setJmAnyElementClassName()
and
setJmContentHandlerClassName()
and be happy
with it. This is more straightforward, but you pay in
the long term, because finally you will find yourself
implementing a similar configuration scheme. (Experience
shows :-)
- The values given in the defaults section can be
overwritten in the document type specific section.
The recommended behaviour is putting the XML file somewhere
into your classpath. Assuming, that your configuration file is
in com/mycompany/Configuration.xml, you could write the
following program, that writes all current HTTP sessions to System.out,
much like the "AddressPrinter":
import com.mycompany.session.ClsSession;
import de.ispsoft.jaxme.*;
public class SessionPrinter {
public static void main(String[] args) throws Exception {
System.setProperty("de.ispsoft.jaxme.JMManagerFactory.uri",
"resource:com/mycompany/Configuration.xml");
JMManagerFactory factory = new JMFactory.getJMManagerFactory();
JMManager manager = factory.getJMManager(ClsSession.NAMESPACE_URI,
ClsSession.LOCAL_NAME);
String query = "myprefix:Session[LASTACTION + EXPIRETIME > " +
JMAnyElement.formatDate(new java.util.Date());
for (java.util.Iterator iter = manager.select(query);
iter.hasNext(); ) {
ClsSession session = (ClsSession) iter.next();
System.out.println(session.toXML());
}
}
}
You could also read the configuration from a file or URL by changing
the property value to
file://c:\temp\Configuration.xml
or
http://configurations.company.com/Configuration.xml
And you could, of course, specify the property value from the command
line and not within the program.For details, see the
Tamino and SAX2
The current Tamino version (3.1.1.4, as of this writing) is
not namespace aware. That means, you either have not to use
namespaces at all (the exception being the ino:
prefix, of course) or you have to make sure, that the same
prefixes are used for any single instance of a given document
type, that is stored in the database.
For example, did you notice that there already was a problem
in the previous example? We formulated a query for documents
of type Session in the namespace
http://jaxme.ispsoft.de/namespaces/examples/Session.
But the query was asking for documents of type
myprefix:Session, assuming silently that this
prefix is used for the namespace.
The former works without any additional caveats, but the
latter requires some additional support. The best way is
specifying a list of namespace prefixes and URI's in the
manager configuration. Whenever the manager needs to convert
a namespace into a prefix, it uses the list. Let's take a
look at an example:
<?xml version="1.0" encoding="UTF-8" ?>
<JMManagerConfiguration
xmlns="http://jaxme.ispsoft.de/namespaces/JMManagerConfiguration">
<Defaults>
<InoManager>
<DbURL>http://127.0.0.1/tamino/test</DbURL>
<User>sa</User>
<Password/>
<ManagerClass>de.ispsoft.jaxme.tamino.InoManager</ManagerClass>
<Namespaces>
<Namespace prefix="s"
uri="http://jaxme.ispsoft.de/namespaces/examples/Session"/>
<Namespace prefix="" uri=""/>
</Namespaces>
</InoManager>
</Defaults>
<Configuration
localName="Session"
namespaceURI="http://jaxme.ispsoft.de/namespaces/examples/Session">
<ElementClass>com.mycompany.session.ClsSession</ElementClass>
<HandlerClass>com.mycompany.session.ClsSessionHandler</HandlerClass>
</Configuration>
</JMManagerConfiguration>
With one exception, this is the same configuration than above. The
exception is a list of namespaces in the defaults section. You may
use a namespace list in both the default and the document type specific
section. If both lists are present, they will be concatenated unless
the node Namespaces has an attribute
reset="true". For example:
<JMManagerConfiguration
xmlns="http://jaxme.ispsoft.de/namespaces/JMManagerConfiguration">
<Defaults>
<InoManager>
<Namespaces>
<Namespace prefix="x" uri="uriOfX"/>
</Namespaces>
</InoManager>
</Defaults>
<Configuration localName="a" namespaceURI="uriOfA"/>
<Configuration localName="b" namespaceURI="uriOfB">
<Namespaces>
<Namespace prefix="y" uri="uriOfY"/>
</Namespaces>
</Configuration>
<Configuration localName="c" namespaceURI="uriOfC">
<Namespaces reset="true"s>
<Namespace prefix="z" uri="uriOfZ"/>
</Namespaces>
</Configuration>
</JMManagerConfiguration>
This example configures three different namespace lists for
a, b and c: The first
element, a has the prefix x configured,
which it inherits from the defaults section. The second element,
b has an additional prefix y, but
the third element, c, has only the prefix z,
because it resets the default prefix list.
Writing data to a Tamino database
We'll now want to create a new HTTP session. It uses
the same property file as before:
import com.mycompany.session.ClsSession;
import de.ispsoft.jaxme.*;
public class SessionAdd {
public static void main(String[] args) throws Exception {
System.setProperty("de.ispsoft.jaxme.JMManagerFactory.uri",
"resource:com/mycompany/Configuration.xml");
JMManagerFactory factory = new JMFactory.getJMManagerFactory();
JMManager manager = factory.getJMManager(ClsSession.NAMESPACE_URI,
ClsSession.LOCAL_NAME);
ClsSession session = (ClsSession) manager.create();
session.eID = new Integer(126776);
session.eIPADDRESS = "134.23.1.7";
session.eLOGINTIME = new java.sql.Timestamp(System.currentTimeMillis());
session.eLASTACTION = session.eLOGINTIME;
session.eEXPIRETIME = new Short((short) 15*60);
session.eCOOKIE = "jH63fGdx";
session.eLANGUAGEID = new Integer(3);
manager.insert(session);
String id = session.getAttribute(InoResponseHandler.INO_RESPONSE2_URI,
"id");
System.out.println("Document with ID " + id + " was created.");
}
A similar example, the update of a row:
import com.mycompany.session.ClsSession;
import de.ispsoft.jaxme.*;
public class SessionUpdate {
public static void main(String[] args) throws Exception {
System.setProperty("de.ispsoft.jaxme.JMManagerFactory.uri",
"resource:com/mycompany/Configuration.xml");
JMManagerFactory factory = new JMFactory.getJMManagerFactory();
JMManager manager = factory.getJMManager(ClsSession.NAMESPACE_URI,
ClsSession.LOCAL_NAME);
java.util.Iterator iter = manager.select("myprefix:Session[@ino:id=37]");
if (iter.hasNext()) {
ClsSession session = (ClsSession) iter.next();
session.eLASTACTION = new java.sql.Timestamp(System.currentTimeMillis());
manager.update(session);
}
}
}
And finally, as you have probably guessed, an example for
deleting a row:
import com.mycompany.session.ClsSession;
import de.ispsoft.jaxme.*;
public class SessionDelete {
public static void main(String[] args) throws Exception {
System.setProperty("de.ispsoft.jaxme.JMManagerFactory.uri",
"resource:com/mycompany/Configuration.xml");
JMManagerFactory factory = new JMFactory.getJMManagerFactory();
JMManager manager = factory.getJMManager(ClsSession.NAMESPACE_URI,
ClsSession.LOCAL_NAME);
java.util.Iterator iter = manager.select("myprefix:Session[@ino:id=37]");
if (iter.hasNext()) {
ClsSession session = (ClsSession) iter.next();
manager.delete(session);
}
}
}
Noticed that these examples looked quite the same as their JDBC
counterparts did? Thats because the Tamino manager is just another
manager.