Project

Profile

Help

Bug #2546 ยป StreamingXQuery.java

Gunther Rademacher, 2015-12-17 09:45

 
import java.io.IOException;
import java.io.InputStream;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;

import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import com.saxonica.config.EnterpriseConfiguration;

import net.sf.saxon.lib.ModuleURIResolver;
import net.sf.saxon.lib.StandardURIResolver;
import net.sf.saxon.s9api.Processor;
import net.sf.saxon.s9api.SaxonApiException;
import net.sf.saxon.s9api.XQueryCompiler;
import net.sf.saxon.s9api.XQueryEvaluator;
import net.sf.saxon.s9api.XQueryExecutable;
import net.sf.saxon.s9api.XdmSequenceIterator;
import net.sf.saxon.trans.XPathException;

public class StreamingXQuery {
private Processor saxonProcessor;
private XQueryCompiler xqueryCompiler;
private DocumentBuilderFactory documentBuilderFactory;
@BeforeClass
public void beforeClass() throws NoSuchFieldException, ParserConfigurationException {
EnterpriseConfiguration configuration = new EnterpriseConfiguration();
saxonProcessor = new Processor(configuration);

xqueryCompiler = saxonProcessor.newXQueryCompiler();
xqueryCompiler.setModuleURIResolver(new ModuleURIResolver() {

@Override
public StreamSource[] resolve(String moduleURI, String baseURI, String[] locations) throws XPathException {
ClassLoader classLoader = StreamingXQuery.class.getClassLoader();
InputStream moduleInputStream = classLoader.getResourceAsStream(moduleURI);
return moduleInputStream == null ? null : new StreamSource[]{new StreamSource(moduleInputStream, classLoader.getResource(moduleURI).toExternalForm())};
}
});
documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true);
documentBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
}

@DataProvider(name="streamingQueries")
public Object[][] streamingQueries() {
long limit = 32 * 1024;
return new Object[][] {
{"for $x in saxon:stream(doc('uriresolver:resolve')/*/*) return string($x)", limit},
{"for $x in saxon:stream(doc('uriresolver:resolve')/*/*) return $x", limit},
{"for $x in saxon:stream(doc('uriresolver:resolve')/*/*) return $x/*", limit},
{"saxon:stream(doc('uriresolver:resolve')/*/*)/string()", limit},
{"saxon:stream(doc('uriresolver:resolve')/*/*)", limit},
{"saxon:stream(doc('uriresolver:resolve')/*/*)/*", limit},
{"for $x in saxon:stream(doc('uriresolver:resolve')/*/*)/* return $x", limit},
};
}
@Test(dataProvider="streamingQueries")
public void testStreamingQueries(String query, long limit) throws SaxonApiException {
XQueryExecutable xqueryExecutable = xqueryCompiler.compile(query);

long start = System.currentTimeMillis();
long count = 0;
long nextStop = 1;

XQueryEvaluator xqueryEvaluator = xqueryExecutable.load();
xqueryEvaluator.setURIResolver(new StandardURIResolver() {
@Override
public Source resolve(String href, String base) throws XPathException {
return new StreamSource(new InputStream() {
private static final String intro =
"<song>\n";
private static final String chorus =
" <chorus>\n" +
" <line>Let me take you down</line>\n" +
" <line>Cause I'm going to Strawberry Fields</line>\n" +
" <line>Nothing is real</line>\n" +
" <line>And nothing to get hung about</line>\n" +
" <line>Strawberry Fields forever</line>\n" +
" </chorus>\n";
private int i = - intro.length();

@Override
public int read() throws IOException {
if (i++ < 0) {
return intro.charAt(i + intro.length() - 1);
}
else {
i %= chorus.length();
return chorus.charAt(i);
}
}
});
}
});
XdmSequenceIterator xdmSequenceIterator = xqueryEvaluator.iterator();
try {
while (xdmSequenceIterator.hasNext()) {
xdmSequenceIterator.next();
if (++count == nextStop) {
long elapsed = System.currentTimeMillis() - start;
System.out.println("t(" + count + "): " + elapsed + " msec");
nextStop = nextStop == 1 ? 1024 : nextStop << 1;
}
if (count >= limit)
break;
}
}
finally {
xdmSequenceIterator.close();
xqueryEvaluator.close();
}
Assert.assertEquals(count, limit);
}
}
    (1-1/1)