package org.exist.xmldb;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXResult;
import org.exist.test.ExistXmldbEmbeddedServer;
import org.junit.ClassRule;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xmldb.api.DatabaseManager;
import org.xmldb.api.base.*;
import org.xmldb.api.modules.CollectionManagementService;
import org.xmldb.api.modules.XMLResource;
import org.xmldb.api.modules.XPathQueryService;
import static java.nio.charset.StandardCharsets.UTF_8;
/**
* @author jmv
*/
public class DOMTest {
@ClassRule
public static final ExistXmldbEmbeddedServer existEmbeddedServer = new ExistXmldbEmbeddedServer(false, true);
private static String name = "test.xml";
/**
* - Storing XML resource from XML string
* - simple XQuery
* - removing resource
* - shutdownDB with the DatabaseInstanceManager
*/
@Test
public void test1() throws XMLDBException {
CollectionManagementService cms =
(CollectionManagementService) existEmbeddedServer.getRoot().getService(
"CollectionManagementService",
"1.0");
cms.createCollection("A"); // jmv
cms.removeCollection("A");
cms.createCollection("A");
Collection coll = existEmbeddedServer.getRoot().getChildCollection("A");
XMLResource r =
(XMLResource) coll.createResource(
name,
XMLResource.RESOURCE_TYPE);
r.setContent(
"<properties><property key=\"type\">Table</property></properties>");
coll.storeResource(r);
XPathQueryService xpqs =
(XPathQueryService) coll.getService("XPathQueryService", "1.0");
ResourceSet rs =
xpqs.query(
"//properties[property[@key='type' and text()='Table']]");
for (ResourceIterator i = rs.getIterator();
i.hasMoreResources();
) {
r = (XMLResource) i.nextResource();
String s = (String) r.getContent();
Node content = r.getContentAsDOM();
coll.removeResource(r);
}
cms.removeCollection("A");
}
/**
* - create and fill a simple document via DOM and JAXP
* - store it with setContentAsDOM()
* - simple access via getContentAsDOM()
* */
@Test
public void test2() throws XMLDBException, InstantiationException, IllegalAccessException, ClassNotFoundException, ParserConfigurationException {
for (int i = 0; i < 2; i++) {
XMLResource resource = (XMLResource) existEmbeddedServer.getRoot().getResource(name);
if (resource == null) {
resource =
(XMLResource) existEmbeddedServer.getRoot().createResource(
name,
XMLResource.RESOURCE_TYPE);
DocumentBuilderFactory dbf =
DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.newDocument();
Element rootElem = doc.createElement("element");
doc.appendChild(rootElem);
resource.setContentAsDOM(doc);
existEmbeddedServer.getRoot().storeResource(resource);
resource = (XMLResource) existEmbeddedServer.getRoot().getResource(name);
}
String s = (String) resource.getContent();
Node content = resource.getContentAsDOM();
}
existEmbeddedServer.restart();
XMLResource resource = (XMLResource) existEmbeddedServer.getRoot().getResource(name);
existEmbeddedServer.getRoot().removeResource(resource);
}
/** like test 2 but add attribute and text as well */
@Test
public void test3() throws XMLDBException, ParserConfigurationException {
Collection coll = existEmbeddedServer.getRoot();
XMLResource resource =
(XMLResource) coll.createResource(
name,
XMLResource.RESOURCE_TYPE);
Document doc =
DocumentBuilderFactory
.newInstance()
.newDocumentBuilder()
.newDocument();
Element rootElem = doc.createElement("element");
Element propertyElem = doc.createElement("property");
propertyElem.setAttribute("key", "value");
propertyElem.appendChild(doc.createTextNode("text"));
rootElem.appendChild(propertyElem);
doc.appendChild(rootElem);
resource.setContentAsDOM(doc);
coll.storeResource(resource);
coll.close();
coll = DatabaseManager.getCollection(XmldbURI.LOCAL_DB, "admin", "");
resource = (XMLResource) coll.getResource(name);
String s = (String) resource.getContent();
Node n = resource.getContentAsDOM();
coll.removeResource(resource);
}
/** like test 3 but uses the DOM as input to an (identity) XSLT transform */
@Test
public void test4_getContentAsString() throws XMLDBException, ParserConfigurationException, IOException, SAXException, TransformerException {
_test4(false);
}
@Test
public void test4_getContentAsDOM() throws XMLDBException, ParserConfigurationException, IOException, SAXException, TransformerException {
_test4(true);
}
private void _test4(boolean getContentAsDOM) throws TransformerException, ParserConfigurationException, XMLDBException, IOException, SAXException {
Collection coll = existEmbeddedServer.getRoot();
XMLResource resource =
(XMLResource) coll.createResource(
name,
XMLResource.RESOURCE_TYPE);
Document doc =
DocumentBuilderFactory
.newInstance()
.newDocumentBuilder()
.newDocument();
Element rootElem = doc.createElement("element");
Element propertyElem = doc.createElement("property");
propertyElem.setAttribute("key", "value");
propertyElem.appendChild(doc.createTextNode("text"));
rootElem.appendChild(propertyElem);
doc.appendChild(rootElem);
resource.setContentAsDOM(doc);
coll.storeResource(resource);
coll.close();
coll = DatabaseManager.getCollection(XmldbURI.LOCAL_DB, "admin", "");
resource = (XMLResource) coll.getResource(name);
Node n;
if (getContentAsDOM) {
n = resource.getContentAsDOM();
} else {
String s = (String) resource.getContent();
byte[] bytes;
bytes = s.getBytes(UTF_8);
try(final ByteArrayInputStream bais = new ByteArrayInputStream(bytes)) {
DocumentBuilder db =
DocumentBuilderFactory.newInstance().newDocumentBuilder();
n = db.parse(bais);
}
}
Transformer t = TransformerFactory.newInstance().newTransformer();
DOMSource source = new DOMSource(n);
SAXResult result = new SAXResult(new DOMTest.SAXHandler());
t.transform(source, result);
coll.removeResource(resource);
}
public static class SAXHandler implements ContentHandler {
SAXHandler() {
}
public void characters(char[] ch, int start, int length) {
System.out.println(
"SAXHandler.characters("
+ new String(ch)
+ ", "
+ start
+ ", "
+ length
+ ")");
}
public void endDocument() {
System.out.println("SAXHandler.endDocument()");
}
public void endElement(
String namespaceURI,
String localName,
String qName) {
System.out.println(
"SAXHandler.endElement("
+ namespaceURI
+ ", "
+ localName
+ ", "
+ qName
+ ")");
}
public void endPrefixMapping(String prefix) {
System.out.println("SAXHandler.endPrefixMapping(" + prefix + ")");
}
public void ignorableWhitespace(char[] ch, int start, int length) {
System.out.println(
"SAXHandler.ignorableWhitespace("
+ new String(ch)
+ ", "
+ start
+ ", "
+ length
+ ")");
}
public void processingInstruction(String target, String data) {
System.out.println(
"SAXHandler.processingInstruction("
+ target
+ ", "
+ data
+ ")");
}
public void setDocumentLocator(Locator locator) {
System.out.println(
"SAXHandler.setDocumentLocator(" + locator + ")");
}
public void skippedEntity(String name) {
System.out.println("SAXHandler.skippedEntity(" + name + ")");
}
public void startDocument() {
System.out.println("SAXHandler.startDocument()");
}
public void startElement(
String namespaceURI,
String localName,
String qName,
Attributes atts) {
System.out.println(
"SAXHandler.startElement("
+ namespaceURI
+ ", "
+ localName
+ ", "
+ qName
+ ","
+ atts
+ ")");
}
public void startPrefixMapping(String prefix, String xuri) {
System.out.println(
"SAXHandler.startPrefixMapping(" + prefix + ", " + xuri + ")");
}
}
}