package org.exist; import org.exist.collections.Collection; import org.exist.dom.persistent.DefaultDocumentSet; import org.exist.dom.persistent.DocumentSet; import org.exist.security.PermissionDeniedException; import org.exist.storage.DBBroker; import org.exist.storage.serializers.Serializer; import org.exist.util.FileUtils; import org.exist.util.serializer.SAXSerializer; import org.exist.xquery.CompiledXQuery; import org.exist.xquery.XPathException; import org.exist.xquery.XQuery; import org.exist.xquery.XQueryContext; import org.exist.xquery.value.*; import org.xml.sax.SAXException; import org.xmldb.api.base.CompiledExpression; import org.xmldb.api.base.ResourceIterator; import org.xmldb.api.base.ResourceSet; import org.xmldb.api.base.XMLDBException; import org.xmldb.api.modules.XMLResource; import org.xmldb.api.modules.XQueryService; import javax.xml.transform.OutputKeys; import java.io.*; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.util.Properties; /** * Helper class to generate test documents from a given XQuery. */ public class TestDataGenerator { private final static Properties outputProps = new Properties(); static { outputProps.setProperty(OutputKeys.INDENT, "yes"); } private final static String IMPORT = "import module namespace pt='http://exist-db.org/xquery/test/performance' " + "at 'java:org.exist.performance.xquery.PerfTestModule';\n" + "declare variable $filename external;\n" + "declare variable $count external;\n"; private String prefix; private int count; private Path[] generatedFiles; public TestDataGenerator(final String prefix, final int count) { this.prefix = prefix; this.count = count; this.generatedFiles = new Path[count]; } public Path[] generate(final DBBroker broker, final Collection collection, final String xqueryContent) throws SAXException { try { final DocumentSet docs = collection.allDocs(broker, new DefaultDocumentSet(), true); final XQuery service = broker.getBrokerPool().getXQueryService(); final XQueryContext context = new XQueryContext(broker.getBrokerPool()); context.declareVariable("filename", ""); context.declareVariable("count", "0"); context.setStaticallyKnownDocuments(docs); final String query = IMPORT + xqueryContent; final CompiledXQuery compiled = service.compile(broker, context, query); for (int i = 0; i < count; i++) { generatedFiles[i] = Files.createTempFile(prefix, ".xml"); context.declareVariable("filename", generatedFiles[i].getFileName().toString()); context.declareVariable("count", new Integer(i)); final Sequence results = service.execute(broker, compiled, Sequence.EMPTY_SEQUENCE); final Serializer serializer = broker.getSerializer(); serializer.reset(); try(final Writer out = Files.newBufferedWriter(generatedFiles[i], StandardCharsets.UTF_8)) { final SAXSerializer sax = new SAXSerializer(out, outputProps); serializer.setSAXHandlers(sax, sax); for (final SequenceIterator iter = results.iterate(); iter.hasNext(); ) { final Item item = iter.nextItem(); if (!Type.subTypeOf(item.getType(), Type.NODE)) { continue; } serializer.toSAX((NodeValue) item); } } } } catch (final XPathException | PermissionDeniedException | IOException e) { e.printStackTrace(); throw new SAXException(e.getMessage(), e); } return generatedFiles; } public Path[] generate(final org.xmldb.api.base.Collection collection, final String xqueryContent) throws SAXException { final String query = IMPORT + xqueryContent; try { final XQueryService service = (XQueryService) collection.getService("XQueryService", "1.0"); service.declareVariable("filename", ""); service.declareVariable("count", "0"); final CompiledExpression compiled = service.compile(query); for (int i = 0; i < count; i++) { generatedFiles[i] = Files.createTempFile(prefix, ".xml"); service.declareVariable("filename", generatedFiles[i].getFileName().toString()); service.declareVariable("count", new Integer(i)); final ResourceSet result = service.execute(compiled); try(final Writer out = Files.newBufferedWriter(generatedFiles[i], StandardCharsets.UTF_8)) { final SAXSerializer sax = new SAXSerializer(out, outputProps); for (ResourceIterator iter = result.getIterator(); iter.hasMoreResources(); ) { XMLResource r = (XMLResource) iter.nextResource(); r.getContentAsSAX(sax); } } } } catch (final XMLDBException | IOException e) { e.printStackTrace(); throw new SAXException(e.getMessage(), e); } return generatedFiles; } public void releaseAll() { for(final Path generatedFile : generatedFiles) { FileUtils.deleteQuietly(generatedFile); } } }