// You can redistribute this software and/or modify it under the terms of
// the Ozone Library License version 1 published by ozone-db.org.
//
// The original code and portions created by SMB are
// Copyright (C) 1997-@year@ by SMB GmbH. All rights reserved.
//
// $Id: XMLContainerHelperImpl.java,v 1.1 2001/12/18 11:03:24 per_nyfelt Exp $
package org.ozoneDB.xml.util;
import java.io.IOException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import org.ozoneDB.OzoneObject;
import org.ozoneDB.xml.dom.DocumentProxy;
import org.infozone.tools.xml.queries.XObject;
import org.infozone.tools.xml.queries.XPathQuery;
import org.infozone.tools.xml.queries.XUpdateQuery;
import org.infozone.tools.xml.queries.XPathQueryFactory;
import org.infozone.tools.xml.queries.XUpdateQueryFactory;
/**
* This class provides the server side part of the XMLContainer. It mainly
* handles storing and retrieving of parts of the underlying XML document.
*
* @version $Revision: 1.1 $ $Date: 2001/12/18 11:03:24 $
* @author <a href="http://www.smb-tec.com">SMB</a>
*/
public final class XMLContainerHelperImpl
extends OzoneObject
implements XMLContainerHelper {
private final static long serialVersionUID = 4L;
private final static boolean debug = XMLContainer.debug;
private static XPathQueryFactory xpathQueryFactory;
private static XUpdateQueryFactory xupdateQueryFactory;
/** The underlying XML document. */
private Document document;
static {
// use Xt and Lexus for XPath and XUpdate
if (System.getProperties().get( "org.infozone.tools.xml.queries.XPathQueryFactory" ) == null) {
System.getProperties().put( "org.infozone.tools.xml.queries.XPathQueryFactory",
"org.infozone.tools.xml.queries.xt.XPathQueryFactoryImpl");
}
if (System.getProperties().get( "org.infozone.tools.xml.queries.XUpdateQueryFactory" ) == null ) {
System.getProperties().put( "org.infozone.tools.xml.queries.XUpdateQueryFactory",
"org.infozone.lexus.XUpdateQueryFactoryImpl");
}
xpathQueryFactory = XPathQueryFactory.newInstance();
xupdateQueryFactory = XUpdateQueryFactory.newInstance();
}
public XMLContainerHelperImpl() {
if (debug) {
System.out.println( "helper: ctor..." );
}
}
public final void onCreate() throws Exception {
if (debug) {
System.out.println( "helper: onCreate()..." );
}
document = (Document)database().createObject( org.ozoneDB.xml.dom.DocumentImpl.class.getName() );
((DocumentProxy)document).setContainer( this );
}
public final void onDelete() throws Exception {
if (debug) {
System.out.println( "helper: onDelete()..." );
}
if (document != null) {
database().deleteObject( (DocumentProxy)document );
}
}
public final void setDocument( Document _pdoc ) {
if (debug) {
System.out.println( "helper: setDocument..." );
}
if (document != null) {
throw new IllegalStateException( "Container helper is already assigned to a document." );
}
document = _pdoc;
((DocumentProxy)document).setContainer( this );
}
public final Document getDocument() {
if (debug) {
System.out.println( "helper: getDocument..." );
}
return document;
}
public final SAXChunkConsumer beginInputSequence( Node _pNode ) throws Exception {
if (debug) {
System.out.println("helper: beginInputSequence...");
}
if (_pNode == null) {
_pNode = getDocument();
((DocumentProxy)_pNode).clearDocument();
}
SAXChunkConsumer consumer = new SAXChunkConsumer( getDocument(), _pNode );
return consumer;
}
public final SAXChunkConsumer putChunk( byte[] _chunkData, SAXChunkConsumer _consumer )
throws SAXException, IOException {
_consumer.processChunk( _chunkData );
return _consumer;
}
public final void endInputSequence() throws Exception {
if (debug) {
System.out.println( "helper: endInputSequence..." );
}
}
/* public final SAXChunkProducer beginOutputSequence( Node _pnode, int _depth ) throws Exception {
if (_pnode == null) {
_pnode = getDocument();
}
ModifiableNodeList mnl = new ModifiableNodeList(1);
mnl.addNode(_pnode);
return new SAXChunkProducer( mnl, _depth );
}
*/
public final SAXChunkProducer beginOutputSequence( NodeList _pnodes, int _depth ) throws Exception {
if (_pnodes == null) {
_pnodes = new ModifiableNodeList(1);
((ModifiableNodeList)_pnodes).addNode(getDocument());
}
return new SAXChunkProducer( _pnodes, _depth );
}
public final SAXChunkProducer createNextChunk( SAXChunkProducer producer ) throws SAXException {
producer.createNextChunk();
return producer;
}
public final void endOutputSequence() throws Exception {
if (debug) {
System.out.println( "helper: endOutputSequence..." );
}
}
public final XObject executeXPath( OzoneXPathQuery _query ) throws Exception {
if (_query.rootNode == null) {
_query.rootNode = getDocument();
}
XPathQuery query = xpathQueryFactory.newXPathQuery();
query.setQString( _query.qstring );
if (_query.filter != null) {
query.setNodeFilter( _query.filter );
}
if (_query.namespace != null) {
query.setNamespace( _query.namespace );
}
return query.execute( _query.rootNode );
}
public final void executeXUpdate( OzoneXUpdateQuery _query ) throws Exception {
if (_query.rootNode == null) {
_query.rootNode = getDocument();
}
XUpdateQuery query = xupdateQueryFactory.newXUpdateQuery();
query.setQString( _query.qstring );
if (_query.filter != null) {
query.setNodeFilter( _query.filter );
}
if (_query.namespace != null) {
query.setNamespace( _query.namespace );
}
System.out.println( query.getClass().getName() );
System.out.println( _query.qstring );
System.out.println( _query.rootNode );
query.execute( _query.rootNode );
}
/**
* Determines the absolute XPath for the given node.
* @param node The W3C DOM node whose XPath is to determine.
* @return The string representing the absolute XPath for this node.
*/
public final String xpathForNode( Node _pnode ) {
if (_pnode == null) {
throw new IllegalArgumentException( "_pnode == null." );
}
StringBuffer xpath = new StringBuffer();
xpath = iterateBack( _pnode, xpath );
return xpath.toString();
}
// internal stuff
private final StringBuffer iterateBack( Node node, StringBuffer buffer ) {
int nthChild = 1;
String nodeName = node.getNodeName();
Node prevNode = node;
while ((prevNode = prevNode.getPreviousSibling()) != null) {
if (prevNode.getNodeName().equals( nodeName ) && prevNode.getNodeType() == node.getNodeType()) {
nthChild++;
}
}
if (node.getNodeType() == Node.TEXT_NODE) {
nodeName = "text()";
} else if (node.getNodeType() == Node.COMMENT_NODE) {
nodeName = "comment()";
} else {
if (node.getNodeType() == Node.DOCUMENT_NODE) {
nodeName = "";
}
}
buffer.insert( 0, "/" + nodeName + (nodeName.length() > 0 ? "[" + nthChild + "]" : "") );
node = node.getParentNode();
if (node != null && node.getNodeType() != Node.DOCUMENT_NODE) {
buffer = iterateBack( node, buffer );
}
return buffer;
}
}