package org.exist.fluent;
import java.io.*;
import org.exist.dom.*;
import org.exist.storage.DBBroker;
import org.exist.xquery.value.Sequence;
import org.xml.sax.SAXException;
/**
* An XML document from the database.
*
* @author <a href="mailto:piotr@ideanest.com">Piotr Kaminski</a>
*/
public class XMLDocument extends Document {
private final NodeProxy proxy;
/**
* Create a new XML document wrapper for the given document, and start tracking
* the node.
*
* @param dimpl the document implementation to wrap
* @param namespaceBindings the namespace bindings to use
* @param db the database the document is part of
*/
XMLDocument(DocumentImpl dimpl, NamespaceMap namespaceBindings, Database db) {
super(dimpl, namespaceBindings, db);
if (dimpl instanceof BinaryDocument) throw new IllegalArgumentException("binary document impl passed to XML document constructor");
proxy = new NodeProxy(dimpl);
// no need to track a DocumentImpl proxy, since its gid cannot change
}
@Override Sequence convertToSequence() {
staleMarker.check();
return proxy;
}
/**
* Return this XML document.
*
* @return this document
*/
@Override public XMLDocument xml() {
return this;
}
/**
* Return the root element node of this document.
*
* @return the root element node of this document
*/
public org.exist.fluent.Node root() {
staleMarker.check();
return query().single("*").node();
}
/**
* Return a query service that executes queries in the context of this document.
*
* @return a query service over this document
*/
@Override public QueryService query() {
staleMarker.check();
return super.query();
}
@Override QueryService createQueryService() {
// must explicitly return null here to avoid getting stuck with a NULL from superclass
return null;
}
/**
* Return a string representation of the reference to this document. The representation will
* list the document's path, but will not include its contents.
*
* @return a string representation of this XML document
*/
@Override
public String toString() {
return "XML " + super.toString();
}
@Override public XMLDocument copy(Folder destination, Name name) {
return (XMLDocument) super.copy(destination, name);
}
/**
* Return the serialized contents of this XML document.
*
* @return the serialized contents of this XML document
*/
public String contentsAsString() {
StringWriter writer = new StringWriter();
write(writer);
return writer.toString();
}
/**
* Serialize this document to the given output stream using the default encoding specified
* for the database. If you wish to control the encoding at a finer granularity, use
* {@link #write(Writer)}.
*
* @see Database#setDefaultCharacterEncoding(String)
* @param stream the output stream to write to
* @throws IOException in case of problems with the encoding
* @throws DatabaseException in case of I/O problems
*/
@Override public void write(OutputStream stream) throws IOException {
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(stream, db.defaultCharacterEncoding);
write(outputStreamWriter);
outputStreamWriter.flush();
}
/**
* Serialize this document to the given writer.
*
* @param writer destination writer
*/
public void write(Writer writer) {
staleMarker.check();
DBBroker broker = null;
try {
broker = db.acquireBroker();
broker.getSerializer().serialize(doc, writer);
} catch (SAXException e) {
throw new DatabaseException(e);
} finally {
db.releaseBroker(broker);
}
}
}