// $Id: Client.java,v 1.1 2001/12/17 17:45:08 per_nyfelt Exp $
import java.util.Vector;
import java.io.PrintWriter;
import java.io.Writer;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.parsers.*;
import org.xml.sax.helpers.*;
import org.ozoneDB.ExternalDatabase;
import org.ozoneDB.ExternalTransaction;
import org.ozoneDB.xml.util.*;
import org.infozone.tools.xml.queries.*;
import org.apache.xml.serialize.*;
/**
* Simple XML sample application that demonstrates the use of the ozone/XML API.
* Each command (store, domstore, print, etc.) is handled by a corresponding
* method.
*
* @version $Revision: 1.1 $ $Date: 2001/12/17 17:45:08 $
* @author <a href="http://www.smb-tec.com">SMB</a>
* @see org.ozoneDB.xml.util.XMLContainer
*/
public class Client {
final static String COMMAND_STORE_SAX = "store";
final static String COMMAND_STORE_DOM = "domstore";
final static String COMMAND_XPATH = "xpath";
final static String COMMAND_XUPDATE = "xupdate";
final static String COMMAND_PRINT = "print";
final static String COMMAND_DUMP = "dump";
final static String COMMAND_RENAME = "rename";
final static String COMMAND_DELETE = "delete";
/**
* Create a Xerces specific DocumentBuilderFactory.
*/
static DocumentBuilderFactory builderFactory = new org.apache.xerces.jaxp.DocumentBuilderFactoryImpl();
/**
* Create a Xerces specific SAXParserFactory.
*/
static SAXParserFactory parserFactory = new org.apache.xerces.jaxp.SAXParserFactoryImpl();
static String dbURL = "ozonedb:remote://localhost:3333";
static ExternalDatabase db;
static Vector filenames;
static String targetFile;
static String qstring;
static boolean printResult;
static int depth = -1;
static String newName;
static boolean waitOnExit = false;
public static void main( String[] args ) throws Exception {
if (args.length == 0) {
printUsage();
System.exit( 1 );
}
String command = args[0];
filenames = new Vector();
qstring = "";
printResult = false;
targetFile = null;
// check command line arguments
for (int i = 1; i < args.length; i++) {
String arg = args[i];
if (!arg.startsWith( "-" )) {
filenames.addElement( arg );
}
else if (arg.startsWith( "-q" )) {
qstring = arg.substring( 2 );
System.out.println ("query string: " + qstring);
}
else if (arg.startsWith( "-n" )) {
newName = arg.substring( 2 );
System.out.println ("new name: " + newName);
}
else if (arg.startsWith( "-f" )) {
targetFile = arg.substring( 2 );
}
else if (arg.equals( "-p" )) {
printResult = true;
System.out.println ("print: " + printResult);
}
else if (arg.equals( "-w" )) {
waitOnExit = true;
System.out.println ("waitOnExit: " + waitOnExit);
}
else if (arg.startsWith( "-u" )) {
dbURL = arg.substring( 2 );
System.out.println ("dbURL: " + dbURL);
}
else if (arg.startsWith( "-d" )) {
try {
depth = Integer.parseInt( arg.substring( 2 ) );
} catch (NumberFormatException e) {
System.err.println( "argument -d requires an integer value" );
throw e;
}
}
}
if (filenames.size() == 0) {
printUsage();
System.exit( 1 );
}
db = ExternalDatabase.openDatabase( dbURL );
db.reloadClasses();
try {
// execute corresponding method on all given documents/files
for (int i = 0; i < filenames.size(); i++) {
if (command.equals( COMMAND_STORE_SAX )) {
saxStore( (String)filenames.elementAt( i ) );
}
else if (command.equals( COMMAND_STORE_DOM )) {
domStore( (String)filenames.elementAt( i ) );
}
else if (command.equals( COMMAND_XPATH )) {
xpathQuery( (String)filenames.elementAt( i ) );
}
else if (command.equals( COMMAND_XUPDATE )) {
xupdateQuery( (String)filenames.elementAt( i ) );
}
else if (command.equals( COMMAND_PRINT )) {
print( (String)filenames.elementAt( i ) );
}
else if (command.equals( COMMAND_DUMP )) {
dump( (String)filenames.elementAt( i ), targetFile );
}
else if (command.equals( COMMAND_RENAME )) {
rename( (String)filenames.elementAt( i ) );
}
else if (command.equals( COMMAND_DELETE )) {
delete( (String)filenames.elementAt( i ) );
}
else {
System.out.println( "Unknown command: " + command );
printUsage();
}
}
} finally {
db.close();
}
if (waitOnExit) {
System.out.println( "press any key..." );
InputStreamReader is = new InputStreamReader( System.in );
while (!is.ready()) {
Thread.sleep( 1000 );
}
}
}
protected static void domStore( String filename ) throws Exception {
System.out.println( "DOM store: filename=" + filename );
XMLContainer container = XMLContainer.forName( db, filename );
boolean newDoc = true;
if (container != null) {
System.out.println( "Document already found in Database." );
System.out.print( "Would you like to overwrite the existing Document? [y/N]: " );
int answer = System.in.read();
if (answer == 'y' || answer == 'Y') {
System.out.println( "ATTENTION: Existing Document will be overwritten!" );
newDoc = false;
}
else
return;
}
ExternalTransaction tx = db.newTransaction();
tx.begin();
try {
long start;
if (newDoc) {
start = System.currentTimeMillis();
container = XMLContainer.newContainer( db, filename );
System.out.println( "DOM store: new container time: " + (System.currentTimeMillis() - start) + " ms" );
}
start = System.currentTimeMillis();
DocumentBuilder documentBuilder = builderFactory.newDocumentBuilder();
Document doc = documentBuilder.parse( filename );
// printNodeTree (doc, new StringBuffer (" "));
System.out.println( "DOM store: parse time: " + (System.currentTimeMillis() - start) + " ms" );
start = System.currentTimeMillis();
if (newDoc)
container.storeDOM( doc );
else
container.storeDOM( null, doc );
System.out.println( "DOM store: store time: " + (System.currentTimeMillis() - start) + " ms" );
start = System.currentTimeMillis();
tx.commit();
System.out.println( "DOM store: commit time: " + (System.currentTimeMillis() - start) + " ms" );
} catch (Exception e) {
tx.rollback();
throw e;
}
}
protected static void saxStore( String filename ) throws Exception {
System.out.println( "SAX store: filename=" + filename );
XMLContainer container = XMLContainer.forName( db, filename );
if (container != null) {
System.out.println( "Document already found in Database." );
return;
}
ExternalTransaction tx = db.newTransaction();
tx.begin();
try {
long start = System.currentTimeMillis();
container = XMLContainer.newContainer( db, filename );
System.out.println( "SAX store: new container time: " + (System.currentTimeMillis() - start) + " ms" );
start = System.currentTimeMillis();
SAXParser parser = parserFactory.newSAXParser();
ParserAdapter adapter = new ParserAdapter( parser.getParser() );
adapter.setContentHandler( container.storeSAX() );
adapter.parse( filename );
System.out.println( "SAX store: parse+store time: " + (System.currentTimeMillis() - start) + " ms" );
start = System.currentTimeMillis();
tx.commit();
System.out.println( "SAX store: commit time: " + (System.currentTimeMillis() - start) + " ms" );
} catch (Exception e) {
tx.rollback();
throw e;
}
}
protected static void xupdateQuery( String filename ) throws Exception {
String prefix = "XUpdate query: ";
// all files and names are hard wired yet
filename = "address.xml";
qstring = "<lexus:updates version=\"1.0\" xmlns:lexus=\"http://www.xmldb.org/xupdate\"><lexus:remove select=\"//*[@name='Lars']\"/></lexus:updates>"; /* */
System.out.println( prefix + "filename=" + filename + ", qstring=" + qstring );
// delete the document if it's already there
XMLContainer container = XMLContainer.forName( db, filename );
if (container != null) {
System.out.println( prefix + "document already there; deleting..." );
container.delete();
}
// store the document
saxStore( filename );
// show the original document
// dump( filename, null );
printResult = true;
print( filename );
System.out.println( prefix + "dump ready." );
// do the query
container = XMLContainer.forName( db, filename );
System.out.println( prefix + "forName() ready." );
OzoneXUpdateQuery query = container.newXUpdateQuery();
query.setQString( qstring );
System.out.println( prefix + "query init ready." );
long start = System.currentTimeMillis();
query.execute( );
System.out.println( prefix + "update time: " + (System.currentTimeMillis() - start) + " ms" );
// show modified file
print( filename );
System.out.println( prefix + "2nd dump ready." );
}
protected static void xpathQuery( String filename ) throws Exception {
System.out.println( "XPath query: filename=" + filename + ", qstring=" + qstring );
XMLContainer container = XMLContainer.forName( db, filename );
if (container == null) {
System.out.println( "No such document." );
return;
}
// String path = container.xpathForNode( container.getPDocument().getFirstChild() );
// System.out.println( "XPath query: xpathForNode=" + path );
long start = System.currentTimeMillis();
OzoneXPathQuery query = container.newXPathQuery();
query.setQString( qstring );
XObject result = query.execute();
System.out.println( "XPath query: query time: " + (System.currentTimeMillis() - start) + " ms" );
if (printResult) {
if (result == null) {
System.out.println( "XPath query: result: null" );
}
else {
System.out.print( "XPATH query: result: " );
// cast the query result to
switch (result.getType()) {
case XObject.CLASS_BOOLEAN:
System.out.println( "(Boolean): " + result.bool() );
break;
case XObject.CLASS_NUMBER:
System.out.println( "(Number): " + result.num() );
break;
case XObject.CLASS_STRING:
System.out.println( "(String): " + result.str() );
break;
case XObject.CLASS_RTREEFRAG:
System.out.println( "(DocumentFragment): -" );
break;
case XObject.CLASS_NODESET:
NodeList nodeList = result.nodeset();
System.out.println( "(NodeList): " + nodeList.getLength() + " Entries" );
DocumentBuilder documentBuilder = builderFactory.newDocumentBuilder();
for (int i = 0; i < nodeList.getLength(); i++) {
System.out.print( i + 1 + " Entry: " );
ExternalTransaction tx = db.newTransaction();
tx.begin();
// extract the result node from the persistent document first
start = System.currentTimeMillis();
Document doc = documentBuilder.newDocument();
Node extractedNode = container.extractDOM( doc, nodeList.item( i ), null, depth );
System.out.println( "[extract time: " + (System.currentTimeMillis() - start) + " ms]" );
tx.commit();
printNodeTree( extractedNode, new StringBuffer( " " ) );
}
break;
default:
System.out.println( "(Unknown): -" );
break;
}
}
}
}
protected static void dump( String filename, String targetFile ) throws Exception {
System.out.println( "Dump: filename=" + filename + " -> target=" + (targetFile == null
? "#stdout"
: targetFile) );
XMLContainer container = XMLContainer.forName( db, filename );
if (container == null) {
System.out.println( "No such document." );
return;
}
ExternalTransaction tx = db.newTransaction();
tx.begin();
try {
PrintWriter writer = new PrintWriter( System.out, false );
if (targetFile != null) {
writer = new PrintWriter( new FileOutputStream( targetFile ), false );
}
XMLSerializer serializer = new XMLSerializer( writer, new OutputFormat( "xml", "UTF-8", true ) );
long start = System.currentTimeMillis();
container.extractSAX( serializer.asContentHandler(), null, depth );
System.out.println( "Dump: extract/serialize time: " + (System.currentTimeMillis() - start) + " ms" );
writer.close();
tx.commit();
} catch (Exception e) {
tx.rollback();
throw e;
}
}
protected static void print( String filename ) throws Exception {
System.out.println( "Print: filename=" + filename );
XMLContainer container = XMLContainer.forName( db, filename );
if (container == null) {
System.out.println( "No such document." );
return;
}
DocumentBuilder documentBuilder = builderFactory.newDocumentBuilder();
Document doc = documentBuilder.newDocument();
Node resultNode = null;
ExternalTransaction tx = db.newTransaction();
tx.begin();
try {
long start = System.currentTimeMillis();
resultNode = container.extractDOM( doc, (Node)null /*container.getPDocument().getFirstChild()*/, null, depth );
System.out.println( "Print: with depth: " + depth );
System.out.println( "Print: extract DOM time: " + (System.currentTimeMillis() - start) + " ms" );
tx.commit();
}
catch (Exception e) {
tx.rollback();
throw e;
}
if (printResult) {
System.out.println( "Print: result: " );
printNodeTree( resultNode, new StringBuffer( " " ) );
}
}
/**
* Prints a short hierarchical summary of the specified node and all sub
* nodes.
*/
protected static void printNodeTree( Node node, StringBuffer indent ) {
System.out.print( indent.toString() );
System.out.println( "Node name [" + node.getNodeName() + "] value [" + node.getNodeValue() + "]" );
Node _child = (Node)node.getFirstChild();
for (; _child != null; _child = (Node)_child.getNextSibling()) {
indent.append( " " );
printNodeTree( _child, indent );
indent.setLength( indent.length() - 3 );
}
}
protected static void rename( String filename ) throws Exception {
System.out.println( "Rename: filename=" + filename );
XMLContainer container = XMLContainer.forName( db, filename );
if (container == null) {
System.out.println( "No such document." );
return;
}
if (newName == null) {
System.out.println( "No target name specified." );
return;
}
container.setName( newName );
}
protected static void delete( String filename ) throws Exception {
System.out.println( "Delete: filename=" + filename );
XMLContainer container = XMLContainer.forName( db, filename );
if (container == null) {
System.out.println( "No such document." );
return;
}
container.delete();
}
static void printUsage() {
System.err.println( "Usage: ojvm Client <command> [options] file|document" );
System.err.println( "Commands: " + COMMAND_STORE_SAX + " " + COMMAND_STORE_DOM + " " + COMMAND_XPATH + " " + COMMAND_XUPDATE + " "
+ COMMAND_DUMP + " " + COMMAND_PRINT + " " + COMMAND_RENAME + " " + COMMAND_DELETE );
System.err.println( "Options:" );
System.err.println( " -q<qstring> The XPath query string." );
System.err.println( " -p Print the results of the operation." );
System.err.println( " -f<filename> Write the result to this file instead of stdout." );
System.err.println( " -n<name> The new name of the specified document." );
System.err.println( " -u<dbURL> The URL of the database. (default: " + dbURL + ")" );
}
}