package org.exist;
import org.exist.collections.Collection;
import org.exist.dom.DefaultDocumentSet;
import org.exist.dom.DocumentSet;
import org.exist.security.xacml.AccessContext;
import org.exist.storage.DBBroker;
import org.exist.storage.serializers.Serializer;
import org.exist.util.serializer.SAXSerializer;
import org.exist.xquery.CompiledXQuery;
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.modules.XMLResource;
import org.xmldb.api.modules.XQueryService;
import javax.xml.transform.OutputKeys;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
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 File[] generatedFiles;
public TestDataGenerator(String prefix, int count) {
this.prefix = prefix;
this.count = count;
this.generatedFiles = new File[count];
}
public File[] generate(DBBroker broker, Collection collection, String xqueryContent) throws SAXException {
try {
DocumentSet docs = collection.allDocs(broker, new DefaultDocumentSet(), true, false);
XQuery service = broker.getXQueryService();
XQueryContext context = service.newContext(AccessContext.TEST);
context.declareVariable("filename", "");
context.declareVariable("count", "0");
context.setStaticallyKnownDocuments(docs);
String query = IMPORT + xqueryContent;
System.out.println("query: " + query);
CompiledXQuery compiled = service.compile(context, query);
for (int i = 0; i < count; i++) {
generatedFiles[i] = File.createTempFile(prefix, ".xml");
context.declareVariable("filename", generatedFiles[i].getName());
context.declareVariable("count", new Integer(i));
Sequence results = service.execute(compiled, Sequence.EMPTY_SEQUENCE);
Serializer serializer = broker.getSerializer();
serializer.reset();
Writer out = new OutputStreamWriter(new FileOutputStream(generatedFiles[i]), "UTF-8");
SAXSerializer sax = new SAXSerializer(out, outputProps);
serializer.setSAXHandlers(sax, sax);
for (SequenceIterator iter = results.iterate(); iter.hasNext(); ) {
Item item = iter.nextItem();
if (!Type.subTypeOf(item.getType(), Type.NODE))
continue;
serializer.toSAX((NodeValue) item);
}
out.close();
}
} catch (Exception e) {
e.printStackTrace();
throw new SAXException(e.getMessage(), e);
}
return generatedFiles;
}
public File[] generate(org.xmldb.api.base.Collection collection, String xqueryContent) throws SAXException {
String query = IMPORT + xqueryContent;
System.out.println("query: " + query);
try {
XQueryService service = (XQueryService) collection.getService("XQueryService", "1.0");
service.declareVariable("filename", "");
service.declareVariable("count", "0");
CompiledExpression compiled = service.compile(query);
for (int i = 0; i < count; i++) {
generatedFiles[i] = File.createTempFile(prefix, ".xml");
service.declareVariable("filename", generatedFiles[i].getName());
service.declareVariable("count", new Integer(i));
ResourceSet result = service.execute(compiled);
Writer out = new OutputStreamWriter(new FileOutputStream(generatedFiles[i]), "UTF-8");
SAXSerializer sax = new SAXSerializer(out, outputProps);
for (ResourceIterator iter = result.getIterator(); iter.hasMoreResources(); ) {
XMLResource r = (XMLResource) iter.nextResource();
r.getContentAsSAX(sax);
}
out.close();
}
} catch (Exception e) {
e.printStackTrace();
throw new SAXException(e.getMessage(), e);
}
return generatedFiles;
}
public void releaseAll() {
for (int i = 0; i < generatedFiles.length; i++) {
File file = generatedFiles[i];
file.delete();
generatedFiles[i] = null;
}
}
}