use of org.exist.xquery.value.ValueSequence in project exist by eXist-db.
the class SequenceConstructor method eval.
@Override
public Sequence eval(final Sequence contextSequence, final Item contextItem) throws XPathException {
if (context.getProfiler().isEnabled()) {
context.getProfiler().start(this);
context.getProfiler().message(this, Profiler.DEPENDENCIES, "DEPENDENCIES", Dependency.getDependenciesName(this.getDependencies()));
if (contextSequence != null) {
context.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT SEQUENCE", contextSequence);
}
if (contextItem != null) {
context.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT ITEM", contextItem.toSequence());
}
}
final ValueSequence result = new ValueSequence();
result.keepUnOrdered(unordered);
for (final Expression step : steps) {
context.pushDocumentContext();
try {
final Sequence temp = step.eval(contextSequence, contextItem);
if (temp != null && !temp.isEmpty()) {
result.addAll(temp);
}
} finally {
context.popDocumentContext();
}
}
if (context.getProfiler().isEnabled()) {
context.getProfiler().end(this, "", result);
}
return result;
}
use of org.exist.xquery.value.ValueSequence in project exist by eXist-db.
the class Predicate method selectByPosition.
/**
* @param outerSequence the outer sequence
* @param contextSequence the context sequence
* @param mode the mode
* @param innerSeq the inner sequence
*
* @return The result of the positional evaluation of the predicate.
*
* @throws XPathException if an error occurs
*/
private Sequence selectByPosition(final Sequence outerSequence, final Sequence contextSequence, final int mode, final Sequence innerSeq) throws XPathException {
if (outerSequence != null && !outerSequence.isEmpty() && Type.subTypeOf(contextSequence.getItemType(), Type.NODE) && contextSequence.isPersistentSet() && outerSequence.isPersistentSet()) {
final Sequence result = new NewArrayNodeSet();
final NodeSet contextSet = contextSequence.toNodeSet();
switch(mode) {
case Constants.CHILD_AXIS:
case Constants.ATTRIBUTE_AXIS:
case Constants.DESCENDANT_AXIS:
case Constants.DESCENDANT_SELF_AXIS:
case Constants.DESCENDANT_ATTRIBUTE_AXIS:
{
final NodeSet outerNodeSet = outerSequence.toNodeSet();
// TODO: in some cases, especially with in-memory nodes,
// outerSequence.toNodeSet() will generate a document
// which will be different from the one(s) in contextSet
// ancestors will thus be empty :-(
// A special treatment of VirtualNodeSet does not seem to be
// required anymore
final Sequence ancestors = outerNodeSet.selectAncestors(contextSet, true, getExpressionId());
if (contextSet.getDocumentSet().intersection(outerNodeSet.getDocumentSet()).getDocumentCount() == 0) {
LOG.info("contextSet and outerNodeSet don't share any document");
}
final NewArrayNodeSet temp = new NewArrayNodeSet();
for (final SequenceIterator i = ancestors.iterate(); i.hasNext(); ) {
NodeProxy p = (NodeProxy) i.nextItem();
ContextItem contextNode = p.getContext();
temp.reset();
while (contextNode != null) {
if (contextNode.getContextId() == getExpressionId()) {
temp.add(contextNode.getNode());
}
contextNode = contextNode.getNextDirect();
}
p.clearContext(getExpressionId());
// TODO : understand why we sort here...
temp.sortInDocumentOrder();
for (final SequenceIterator j = innerSeq.iterate(); j.hasNext(); ) {
final NumericValue v = (NumericValue) j.nextItem();
// Non integers return... nothing, not even an error !
if (!v.hasFractionalPart() && !v.isZero()) {
// ... whereas we don't want a sorted array here
// TODO : rename this method as getInDocumentOrder ? -pb
p = temp.get(v.getInt() - 1);
if (p != null) {
result.add(p);
}
// TODO : does null make sense here ? Well... sometimes ;-)
}
}
}
break;
}
default:
for (final SequenceIterator i = outerSequence.iterate(); i.hasNext(); ) {
NodeProxy p = (NodeProxy) i.nextItem();
Sequence temp;
boolean reverseAxis = true;
switch(mode) {
case Constants.ANCESTOR_AXIS:
temp = contextSet.selectAncestors(p, false, Expression.IGNORE_CONTEXT);
break;
case Constants.ANCESTOR_SELF_AXIS:
temp = contextSet.selectAncestors(p, true, Expression.IGNORE_CONTEXT);
break;
case Constants.PARENT_AXIS:
// TODO : understand why the contextSet is not involved
// here
// NodeProxy.getParent returns a *theoretical* parent
// which is *not* guaranteed to be in the context set !
temp = p.getParents(Expression.NO_CONTEXT_ID);
break;
case Constants.PRECEDING_AXIS:
temp = contextSet.selectPreceding(p, Expression.IGNORE_CONTEXT);
break;
case Constants.PRECEDING_SIBLING_AXIS:
temp = contextSet.selectPrecedingSiblings(p, Expression.IGNORE_CONTEXT);
break;
case Constants.FOLLOWING_SIBLING_AXIS:
temp = contextSet.selectFollowingSiblings(p, Expression.IGNORE_CONTEXT);
reverseAxis = false;
break;
case Constants.FOLLOWING_AXIS:
temp = contextSet.selectFollowing(p, Expression.IGNORE_CONTEXT);
reverseAxis = false;
break;
case Constants.SELF_AXIS:
temp = p;
reverseAxis = false;
break;
default:
throw new IllegalArgumentException("Tried to test unknown axis");
}
if (!temp.isEmpty()) {
for (final SequenceIterator j = innerSeq.iterate(); j.hasNext(); ) {
final NumericValue v = (NumericValue) j.nextItem();
// Non integers return... nothing, not even an error !
if (!v.hasFractionalPart() && !v.isZero()) {
final int pos = (reverseAxis ? temp.getItemCount() - v.getInt() : v.getInt() - 1);
// Other positions are ignored
if (pos >= 0 && pos < temp.getItemCount()) {
final NodeProxy t = (NodeProxy) temp.itemAt(pos);
// for the current context: filter out those
// context items not selected by the positional predicate
ContextItem ctx = t.getContext();
t.clearContext(Expression.IGNORE_CONTEXT);
while (ctx != null) {
if (ctx.getContextId() == outerContextId) {
if (ctx.getNode().getNodeId().equals(p.getNodeId())) {
t.addContextNode(outerContextId, ctx.getNode());
}
} else {
t.addContextNode(ctx.getContextId(), ctx.getNode());
}
ctx = ctx.getNextDirect();
}
result.add(t);
}
}
}
}
}
}
return result;
} else {
final boolean reverseAxis = Type.subTypeOf(contextSequence.getItemType(), Type.NODE) && (mode == Constants.ANCESTOR_AXIS || mode == Constants.ANCESTOR_SELF_AXIS || mode == Constants.PARENT_AXIS || mode == Constants.PRECEDING_AXIS || mode == Constants.PRECEDING_SIBLING_AXIS);
final Set<NumericValue> set = new TreeSet<>();
final ValueSequence result = new ValueSequence();
for (final SequenceIterator i = innerSeq.iterate(); i.hasNext(); ) {
final NumericValue v = (NumericValue) i.nextItem();
// Non integers return... nothing, not even an error !
if (!v.hasFractionalPart() && !v.isZero()) {
final int pos = (reverseAxis ? contextSequence.getItemCount() - v.getInt() : v.getInt() - 1);
// Other positions are ignored
if (pos >= 0 && pos < contextSequence.getItemCount() && !set.contains(v)) {
result.add(contextSequence.itemAt(pos));
set.add(v);
}
}
}
return result;
}
}
use of org.exist.xquery.value.ValueSequence in project exist by eXist-db.
the class GrammarTooling method eval.
/**
* @see org.exist.xquery.BasicFunction#eval(Sequence[], Sequence)
*/
public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {
final GrammarPool grammarpool = (GrammarPool) config.getProperty(XMLReaderObjectFactory.GRAMMAR_POOL);
if (isCalledAs("clear-grammar-cache")) {
final Sequence result = new ValueSequence();
final int before = countTotalNumberOfGrammar(grammarpool);
LOG.debug("Clearing {} grammars", before);
clearGrammarPool(grammarpool);
final int after = countTotalNumberOfGrammar(grammarpool);
LOG.debug("Remained {} grammars", after);
final int delta = before - after;
result.add(new IntegerValue(delta));
return result;
} else if (isCalledAs("show-grammar-cache")) {
context.pushDocumentContext();
try {
final MemTreeBuilder builder = context.getDocumentBuilder();
final NodeImpl result = writeReport(grammarpool, builder);
return result;
} finally {
context.popDocumentContext();
}
} else if (isCalledAs("pre-parse-grammar")) {
if (args[0].isEmpty()) {
return Sequence.EMPTY_SEQUENCE;
}
// Setup for XML schema support only
final XMLGrammarPreparser parser = new XMLGrammarPreparser();
parser.registerPreparser(TYPE_XSD, null);
final List<Grammar> allGrammars = new ArrayList<>();
// iterate through the argument sequence and parse url
for (final SequenceIterator i = args[0].iterate(); i.hasNext(); ) {
String url = i.nextItem().getStringValue();
// Fix database urls
if (url.startsWith("/")) {
url = "xmldb:exist://" + url;
}
LOG.debug("Parsing {}", url);
// parse XSD grammar
try {
if (url.endsWith(".xsd")) {
final InputStream is = new URL(url).openStream();
final XMLInputSource xis = new XMLInputSource(null, url, url, is, null);
final Grammar schema = parser.preparseGrammar(TYPE_XSD, xis);
is.close();
allGrammars.add(schema);
} else {
throw new XPathException(this, "Only XMLSchemas can be preparsed.");
}
} catch (final Exception ex) {
LOG.debug(ex);
throw new XPathException(this, ex);
}
}
LOG.debug("Successfully parsed {} grammars.", allGrammars.size());
// Send all XSD grammars to grammarpool
Grammar[] grammars = new Grammar[allGrammars.size()];
grammars = allGrammars.toArray(grammars);
grammarpool.cacheGrammars(TYPE_XSD, grammars);
// Construct result to end user
final ValueSequence result = new ValueSequence();
for (final Grammar one : grammars) {
result.add(new StringValue(one.getGrammarDescription().getNamespace()));
}
return result;
} else {
// oh oh
LOG.error("function not found error");
throw new XPathException(this, "function not found");
}
}
use of org.exist.xquery.value.ValueSequence in project exist by eXist-db.
the class Jaxv method eval.
public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {
// Check input parameters
if (args.length != 2 && args.length != 3) {
return Sequence.EMPTY_SEQUENCE;
}
final ValidationReport report = new ValidationReport();
StreamSource instance = null;
StreamSource[] grammars = null;
String schemaLang = XMLConstants.W3C_XML_SCHEMA_NS_URI;
try {
report.start();
// Get inputstream for instance document
instance = Shared.getStreamSource(args[0].itemAt(0), context);
// Validate using resource speciefied in second parameter
grammars = Shared.getStreamSource(args[1], context);
// Check input
for (final StreamSource grammar : grammars) {
final String grammarUrl = grammar.getSystemId();
if (grammarUrl != null && !grammarUrl.endsWith(".xsd") && !grammarUrl.endsWith(".rng")) {
throw new XPathException("Only XML schemas (.xsd) and RELAXNG grammars (.rng) are supported" + ", depending on the used XML parser.");
}
}
// Fetch third argument if available, and override defailt value
if (args.length == 3) {
schemaLang = args[2].getStringValue();
}
// Get language specific factory
SchemaFactory factory = null;
try {
factory = SchemaFactory.newInstance(schemaLang);
} catch (final IllegalArgumentException ex) {
final String msg = "Schema language '" + schemaLang + "' is not supported. " + ex.getMessage();
LOG.error(msg);
throw new XPathException(msg);
}
// Create grammar
final Schema schema = factory.newSchema(grammars);
// Setup validator
final Validator validator = schema.newValidator();
validator.setErrorHandler(report);
// Perform validation
validator.validate(instance);
} catch (final MalformedURLException ex) {
LOG.error(ex.getMessage());
report.setException(ex);
} catch (final Throwable ex) {
LOG.error(ex);
report.setException(ex);
} finally {
report.stop();
Shared.closeStreamSource(instance);
Shared.closeStreamSources(grammars);
}
// Create response
if (isCalledAs("jaxv")) {
final Sequence result = new ValueSequence();
result.add(new BooleanValue(report.isValid()));
return result;
} else /* isCalledAs("jaxv-report") */
{
context.pushDocumentContext();
try {
final MemTreeBuilder builder = context.getDocumentBuilder();
final NodeImpl result = Shared.writeReport(report, builder);
return result;
} finally {
context.popDocumentContext();
}
}
}
use of org.exist.xquery.value.ValueSequence in project exist by eXist-db.
the class Jaxp method eval.
public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {
XMLEntityResolver entityResolver = null;
GrammarPool grammarPool = null;
final ValidationReport report = new ValidationReport();
ContentHandler contenthandler = null;
MemTreeBuilder instanceBuilder = null;
InputSource instance = null;
if (isCalledAs("jaxp-parse")) {
instanceBuilder = context.getDocumentBuilder();
// (namespace?)
contenthandler = new DocumentBuilderReceiver(instanceBuilder, true);
} else {
contenthandler = new ValidationContentHandler();
}
try {
report.start();
// Get initialized parser
final XMLReader xmlReader = getXMLReader();
// Setup validation reporting
xmlReader.setContentHandler(contenthandler);
xmlReader.setErrorHandler(report);
// Get inputstream for instance document
instance = Shared.getInputSource(args[0].itemAt(0), context);
// Handle catalog
if (args.length == 2) {
LOG.debug("No Catalog specified");
} else if (args[2].isEmpty()) {
// Use system catalog
LOG.debug("Using system catalog.");
final Configuration config = brokerPool.getConfiguration();
entityResolver = (eXistXMLCatalogResolver) config.getProperty(XMLReaderObjectFactory.CATALOG_RESOLVER);
setXmlReaderEnitityResolver(xmlReader, entityResolver);
} else {
// Get URL for catalog
final String[] catalogUrls = Shared.getUrls(args[2]);
final String singleUrl = catalogUrls[0];
if (singleUrl.endsWith("/")) {
// Search grammar in collection specified by URL. Just one collection is used.
LOG.debug("Search for grammar in {}", singleUrl);
entityResolver = new SearchResourceResolver(catalogUrls[0], brokerPool);
setXmlReaderEnitityResolver(xmlReader, entityResolver);
} else if (singleUrl.endsWith(".xml")) {
LOG.debug("Using catalogs {}", getStrings(catalogUrls));
entityResolver = new eXistXMLCatalogResolver();
((eXistXMLCatalogResolver) entityResolver).setCatalogList(catalogUrls);
setXmlReaderEnitityResolver(xmlReader, entityResolver);
} else {
LOG.error("Catalog URLs should end on / or .xml");
}
}
// Use grammarpool
final boolean useCache = ((BooleanValue) args[1].itemAt(0)).getValue();
if (useCache) {
LOG.debug("Grammar caching enabled.");
final Configuration config = brokerPool.getConfiguration();
grammarPool = (GrammarPool) config.getProperty(XMLReaderObjectFactory.GRAMMAR_POOL);
xmlReader.setProperty(XMLReaderObjectFactory.APACHE_PROPERTIES_INTERNAL_GRAMMARPOOL, grammarPool);
}
// Jaxp document
LOG.debug("Start parsing document");
xmlReader.parse(instance);
LOG.debug("Stopped parsing document");
// Distill namespace from document
if (contenthandler instanceof ValidationContentHandler) {
report.setNamespaceUri(((ValidationContentHandler) contenthandler).getNamespaceUri());
}
} catch (final MalformedURLException ex) {
LOG.error(ex.getMessage());
report.setException(ex);
} catch (final IOException ex) {
LOG.error(ex.getCause());
report.setException(ex);
} catch (final Throwable ex) {
LOG.error(ex);
report.setException(ex);
} finally {
report.stop();
Shared.closeInputSource(instance);
}
// Create response
if (isCalledAs("jaxp")) {
final Sequence result = new ValueSequence();
result.add(new BooleanValue(report.isValid()));
return result;
} else /* isCalledAs("jaxp-report or jaxp-parse ") */
{
if (report.getThrowable() != null) {
throw new XPathException(report.getThrowable().getMessage(), report.getThrowable());
}
if (contenthandler instanceof DocumentBuilderReceiver) {
// DocumentBuilderReceiver dbr = (DocumentBuilderReceiver) contenthandler;
return instanceBuilder.getDocument().getNode(0);
} else {
context.pushDocumentContext();
try {
final MemTreeBuilder builder = context.getDocumentBuilder();
return Shared.writeReport(report, builder);
} finally {
context.popDocumentContext();
}
}
}
}
Aggregations