Search in sources :

Example 51 with Item

use of org.exist.xquery.value.Item in project exist by eXist-db.

the class DeferredFunctionCallTest method ensure_argumentsToDeferredFunctionCall_AreNotLost_AfterReset_And_BeforeEval.

/**
 * resetState() make be called on the UserDefinedFunction of a DeferredFunctionCall
 * before the function is eval'd, this is because the evaluation is deferred!
 * resetState() clears the currentArguments to the function, however for a deferred
 * function call we must ensure that we still have these when eval() is called
 * otherwise we will get an NPE!
 *
 * This test tries to prove that eval can be called after resetState without
 * causing problems for a DeferredFunctionCall
 *
 * The test implementation, due to the nature of the code under test, is rather horrible
 * and mostly consists of tightly coupled mocking code making it very brittle.
 * The interesting aspect of this test case is at the bottom of the function itself.
 */
@Test
public void ensure_argumentsToDeferredFunctionCall_AreNotLost_AfterReset_And_BeforeEval() throws XPathException {
    // mocks for FunctionCall constructor
    XQueryContext mockContext = EasyMock.createNiceMock(XQueryContext.class);
    // mocks for evalFunction()
    Sequence mockContextSequence = EasyMock.createMock(Sequence.class);
    Item mockContextItem = EasyMock.createMock(Item.class);
    Sequence[] mockSeq = { Sequence.EMPTY_SEQUENCE };
    int nextExpressionId = 1234;
    SequenceType[] mockArgumentTypes = { new SequenceType(Type.NODE, Cardinality.EMPTY_SEQUENCE) };
    // mock for functionDef
    FunctionSignature mockFunctionSignature = EasyMock.createMock(FunctionSignature.class);
    SequenceType mockReturnType = EasyMock.createMock(SequenceType.class);
    LocalVariable mockMark = EasyMock.createMock(LocalVariable.class);
    Expression mockExpression = EasyMock.createMock(Expression.class);
    // expectations for UserDefinedFunction constructor
    expect(mockContext.nextExpressionId()).andReturn(nextExpressionId++);
    expect(mockExpression.simplify()).andReturn(mockExpression);
    // expectations for FunctionCall constructor
    expect(mockContext.nextExpressionId()).andReturn(nextExpressionId++);
    // expectations for FunctionCall.setFunction
    expect(mockFunctionSignature.getReturnType()).andReturn(mockReturnType);
    expect(mockReturnType.getCardinality()).andReturn(Cardinality.ZERO_OR_MORE);
    expect(mockReturnType.getPrimaryType()).andReturn(Type.NODE).times(4);
    expect(mockContext.nextExpressionId()).andReturn(nextExpressionId++);
    // expectations for functionCall.evalFunction
    expect(mockContext.isProfilingEnabled()).andReturn(false);
    // expectations for DeferredFunctionCallImpl.setup
    expect(mockFunctionSignature.getReturnType()).andReturn(mockReturnType);
    expect(mockReturnType.getCardinality()).andReturn(Cardinality.ZERO_OR_MORE);
    expect(mockReturnType.getPrimaryType()).andReturn(Type.NODE).times(4);
    expect(mockContext.nextExpressionId()).andReturn(nextExpressionId++);
    // expectations for DeferredFunctionCall.execute
    mockContext.pushDocumentContext();
    mockContext.functionStart(mockFunctionSignature);
    mockContext.stackEnter((Expression) anyObject());
    expect(mockContext.declareVariableBinding((LocalVariable) anyObject())).andReturn(null);
    expect(mockFunctionSignature.getArgumentTypes()).andReturn(mockArgumentTypes);
    expect(mockExpression.eval(null, null)).andReturn(Sequence.EMPTY_SEQUENCE);
    mockExpression.resetState(true);
    mockContext.stackLeave((Expression) anyObject());
    mockContext.functionEnd();
    mockContext.popDocumentContext();
    replay(mockContext, mockFunctionSignature, mockReturnType, mockExpression);
    UserDefinedFunction userDefinedFunction = new UserDefinedFunction(mockContext, mockFunctionSignature);
    userDefinedFunction.addVariable("testParam");
    userDefinedFunction.setFunctionBody(mockExpression);
    FunctionCall functionCall = new FunctionCall(mockContext, userDefinedFunction);
    // ensure DeferredFunction
    functionCall.setRecursive(true);
    /**
     * this is the interesting bit **
     */
    // 1) Call reset, this should set current arguments to null
    functionCall.resetState(true);
    // ensure DeferredFunction
    functionCall.setRecursive(true);
    // 2) check UserDefinedFunction.currentArguments == null
    assertNull(userDefinedFunction.getCurrentArguments());
    // so the currentArguments have been set to null, but deferredFunction should have its own copy
    // 3) Call functionCall.eval, if we dont get an NPE on reading currentArguments, then success :-)
    DeferredFunctionCall dfc = (DeferredFunctionCall) functionCall.evalFunction(mockContextSequence, mockContextItem, mockSeq);
    dfc.execute();
    /**
     * end interesting bit **
     */
    verify(mockContext, mockFunctionSignature, mockReturnType, mockExpression);
}
Also used : Sequence(org.exist.xquery.value.Sequence) SequenceType(org.exist.xquery.value.SequenceType) Item(org.exist.xquery.value.Item) Test(org.junit.Test)

Example 52 with Item

use of org.exist.xquery.value.Item in project exist by eXist-db.

the class IntersectTest method persistent_intersect_memtree.

/**
 * Tests the XQuery `intersect` operator against a
 * persistent node on the left and an in-memory node on the right
 */
@Test
public void persistent_intersect_memtree() throws XPathException, NoSuchMethodException {
    final XQueryContext mockContext = createMock(XQueryContext.class);
    final PathExpr mockLeft = createMock(PathExpr.class);
    final PathExpr mockRight = createMock(PathExpr.class);
    final Sequence mockContextSequence = createMock(Sequence.class);
    final Item mockContextItem = createMock(Item.class);
    final Profiler mockProfiler = createMock(Profiler.class);
    final DocumentImpl mockPersistentDoc = createMock(DocumentImpl.class);
    final NodeProxy mockPersistentNode = createMockBuilder(NodeProxy.class).withConstructor(DocumentImpl.class, NodeId.class).withArgs(mockPersistentDoc, new DLN(1)).addMockedMethods(NodeProxy.class.getMethod("isEmpty", new Class[] {}), NodeProxy.class.getMethod("getItemType", new Class[] {}), NodeProxy.class.getMethod("equals", new Class[] { Object.class })).createMock();
    expect(mockContext.nextExpressionId()).andReturn(1);
    expect(mockContext.getProfiler()).andReturn(mockProfiler);
    // persistent node
    expect(mockLeft.eval(mockContextSequence, mockContextItem)).andReturn(mockPersistentNode);
    // memtree node
    expect(mockRight.eval(mockContextSequence, mockContextItem)).andReturn((org.exist.dom.memtree.ElementImpl) createInMemoryDocument().getDocumentElement());
    expect(mockPersistentNode.isEmpty()).andReturn(false);
    expect(mockPersistentNode.getItemType()).andReturn(Type.NODE);
    expect(mockPersistentDoc.getDocId()).andReturn(1).times(2);
    expect(mockContext.getProfiler()).andReturn(mockProfiler);
    replay(mockPersistentDoc, mockPersistentNode, mockRight, mockLeft, mockContext);
    // test
    final Intersect intersect = new Intersect(mockContext, mockLeft, mockRight);
    final Sequence result = intersect.eval(mockContextSequence, mockContextItem);
    assertEquals(0, ((ValueSequence) result).size());
    verify(mockPersistentDoc, mockPersistentNode, mockRight, mockLeft, mockContext);
}
Also used : Item(org.exist.xquery.value.Item) DLN(org.exist.numbering.DLN) NodeId(org.exist.numbering.NodeId) ValueSequence(org.exist.xquery.value.ValueSequence) Sequence(org.exist.xquery.value.Sequence) DocumentImpl(org.exist.dom.persistent.DocumentImpl) NodeProxy(org.exist.dom.persistent.NodeProxy) Test(org.junit.Test)

Example 53 with Item

use of org.exist.xquery.value.Item in project exist by eXist-db.

the class DecodeExiFunction method eval.

@Override
public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {
    if (args[0].isEmpty()) {
        return Sequence.EMPTY_SEQUENCE;
    }
    try {
        BinaryValue exiBinary = ((BinaryValue) args[0].itemAt(0));
        context.pushDocumentContext();
        try {
            MemTreeBuilder builder = context.getDocumentBuilder();
            // create default factory and EXI grammar for schema
            EXIFactory exiFactory = DefaultEXIFactory.newInstance();
            if (args.length > 1) {
                if (!args[1].isEmpty()) {
                    Item xsdItem = args[1].itemAt(0);
                    try (InputStream xsdInputStream = EXIUtils.getInputStream(xsdItem, context)) {
                        GrammarFactory grammarFactory = GrammarFactory.newInstance();
                        Grammars grammar = grammarFactory.createGrammars(xsdInputStream);
                        exiFactory.setGrammars(grammar);
                    }
                }
            }
            SAXDecoder decoder = new SAXDecoder(exiFactory);
            SAXAdapter adapter = new AppendingSAXAdapter(builder);
            decoder.setContentHandler(adapter);
            try (InputStream inputStream = exiBinary.getInputStream()) {
                decoder.parse(new InputSource(inputStream));
            }
            return (NodeValue) builder.getDocument().getDocumentElement();
        } finally {
            context.popDocumentContext();
        }
    } catch (EXIException | SAXException | IOException exie) {
        throw new XPathException(this, new JavaErrorCode(exie.getCause()), exie.getMessage());
    }
}
Also used : NodeValue(org.exist.xquery.value.NodeValue) InputSource(org.xml.sax.InputSource) SAXDecoder(com.siemens.ct.exi.api.sax.SAXDecoder) XPathException(org.exist.xquery.XPathException) InputStream(java.io.InputStream) BinaryValue(org.exist.xquery.value.BinaryValue) GrammarFactory(com.siemens.ct.exi.GrammarFactory) EXIException(com.siemens.ct.exi.exceptions.EXIException) IOException(java.io.IOException) SAXException(org.xml.sax.SAXException) JavaErrorCode(org.exist.xquery.ErrorCodes.JavaErrorCode) Item(org.exist.xquery.value.Item) MemTreeBuilder(org.exist.dom.memtree.MemTreeBuilder) AppendingSAXAdapter(org.exist.dom.memtree.AppendingSAXAdapter) SAXAdapter(org.exist.dom.memtree.SAXAdapter) AppendingSAXAdapter(org.exist.dom.memtree.AppendingSAXAdapter) Grammars(com.siemens.ct.exi.grammars.Grammars) DefaultEXIFactory(com.siemens.ct.exi.helpers.DefaultEXIFactory) EXIFactory(com.siemens.ct.exi.EXIFactory)

Example 54 with Item

use of org.exist.xquery.value.Item in project exist by eXist-db.

the class FunResolveURI method eval.

public Sequence eval(Sequence contextSequence, 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());
        }
    }
    if (contextItem != null) {
        contextSequence = contextItem.toSequence();
    }
    AnyURIValue base;
    if (getArgumentCount() == 1) {
        if (!context.isBaseURIDeclared()) {
            throw new XPathException(this, ErrorCodes.FONS0005, "base URI of the static context has not been assigned a value.");
        }
        base = context.getBaseURI();
    } else {
        try {
            final Item item = getArgument(1).eval(contextSequence).itemAt(0).convertTo(Type.ANY_URI);
            base = (AnyURIValue) item;
        } catch (final XPathException e) {
            throw new XPathException(this, ErrorCodes.FORG0002, "invalid argument to fn:resolve-uri(): " + e.getMessage(), null, e);
        }
    }
    Sequence result;
    final Sequence seq = getArgument(0).eval(contextSequence);
    if (seq.isEmpty()) {
        result = Sequence.EMPTY_SEQUENCE;
    } else {
        AnyURIValue relative;
        try {
            final Item item = seq.itemAt(0).convertTo(Type.ANY_URI);
            relative = (AnyURIValue) item;
        } catch (final XPathException e) {
            throw new XPathException(this, ErrorCodes.FORG0002, "invalid argument to fn:resolve-uri(): " + e.getMessage(), seq, e);
        }
        URI relativeURI;
        URI baseURI;
        try {
            relativeURI = new URI(relative.getStringValue());
            baseURI = new URI(base.getStringValue());
        } catch (final URISyntaxException e) {
            throw new XPathException(this, ErrorCodes.FORG0009, "unable to resolve a relative URI against a base URI in fn:resolve-uri(): " + e.getMessage(), null, e);
        }
        if (relativeURI.isAbsolute()) {
            result = relative;
        } else {
            result = new AnyURIValue(baseURI.resolve(relativeURI));
        }
    }
    if (context.getProfiler().isEnabled()) {
        context.getProfiler().end(this, "", result);
    }
    return result;
}
Also used : Item(org.exist.xquery.value.Item) XPathException(org.exist.xquery.XPathException) AnyURIValue(org.exist.xquery.value.AnyURIValue) Sequence(org.exist.xquery.value.Sequence) URISyntaxException(java.net.URISyntaxException) URI(java.net.URI)

Example 55 with Item

use of org.exist.xquery.value.Item in project exist by eXist-db.

the class FunSort method sort.

private Sequence sort(Sequence seq, ArrayList<Sequence> keys, Collator collator) throws XPathException {
    final Holder<XPathException> exception = new Holder<>();
    // preparing
    final int size = seq.getItemCount();
    final Integer[] order = new Integer[size];
    for (int i = 0; i < size; i++) order[i] = i;
    // sorting
    try {
        Arrays.sort(order, (i1, i2) -> {
            Sequence seq1 = keys.get(i1);
            Sequence seq2 = keys.get(i2);
            int size1 = seq1.getItemCount();
            int size2 = seq2.getItemCount();
            int minSize = Math.min(size1, size2);
            if (size1 == 0) {
                return -size2;
            }
            for (int pos = 0; pos < minSize; pos++) {
                Item item1 = seq1.itemAt(pos);
                Item item2 = seq2.itemAt(pos);
                // int res;
                // if (item1 instanceof org.exist.dom.memtree.NodeImpl && (!(item2 instanceof org.exist.dom.memtree.NodeImpl))) {
                // res = Constants.INFERIOR;
                // } else if (item1 instanceof Comparable && item2 instanceof Comparable) {
                // res = ((Comparable) item1).compareTo(item2);
                // } else {
                // res = Constants.INFERIOR;
                // }
                int res = Constants.EQUAL;
                if (FunDeepEqual.deepEquals(item1, item2, collator)) {
                    continue;
                }
                if (Type.subTypeOfUnion(item1.getType(), Type.NUMBER) && ((NumericValue) item1).isNaN()) {
                    res = Constants.INFERIOR;
                } else if (Type.subTypeOf(item1.getType(), Type.STRING) && Type.subTypeOf(item2.getType(), Type.STRING)) {
                    try {
                        res = Collations.compare(collator, item1.getStringValue(), item2.getStringValue());
                    } catch (XPathException e) {
                        exception.set(e);
                    }
                } else if (item1 instanceof AtomicValue && item2 instanceof AtomicValue) {
                    try {
                        // throw type error if values cannot be compared with lt
                        ValueComparison.compareAtomic(collator, (AtomicValue) item1, (AtomicValue) item2, Constants.StringTruncationOperator.NONE, Constants.Comparison.LT);
                        res = ((AtomicValue) item1).compareTo(collator, (AtomicValue) item2);
                    } catch (XPathException e) {
                        exception.set(e);
                        throw new IllegalArgumentException();
                    }
                // } else if (item1 instanceof Comparable && item2 instanceof Comparable) {
                // res = ((Comparable) item1).compareTo(item2);
                } else {
                    res = Constants.INFERIOR;
                }
                if (res != Constants.EQUAL) {
                    return res;
                }
            }
            return (size1 - size2);
        });
    } catch (IllegalArgumentException e) {
        if (exception.get() != null) {
            throw new XPathException(FunSort.this, ErrorCodes.XPTY0004, exception.get());
        } else {
            throw new XPathException(FunSort.this, ErrorCodes.XPTY0004, e.getMessage());
        }
    }
    // form final sequence
    final ValueSequence result = new ValueSequence(seq.getItemCount());
    result.keepUnOrdered(true);
    for (int i = 0; i < size; i++) {
        result.add(seq.itemAt(order[i]));
    }
    return result;
}
Also used : Item(org.exist.xquery.value.Item) ValueSequence(org.exist.xquery.value.ValueSequence) AtomicValue(org.exist.xquery.value.AtomicValue) ValueSequence(org.exist.xquery.value.ValueSequence) Sequence(org.exist.xquery.value.Sequence)

Aggregations

Item (org.exist.xquery.value.Item)88 Sequence (org.exist.xquery.value.Sequence)69 SequenceIterator (org.exist.xquery.value.SequenceIterator)36 XPathException (org.exist.xquery.XPathException)26 DBBroker (org.exist.storage.DBBroker)18 NodeValue (org.exist.xquery.value.NodeValue)17 XQuery (org.exist.xquery.XQuery)16 ValueSequence (org.exist.xquery.value.ValueSequence)16 BrokerPool (org.exist.storage.BrokerPool)14 NumericValue (org.exist.xquery.value.NumericValue)12 SAXException (org.xml.sax.SAXException)11 Properties (java.util.Properties)10 StringValue (org.exist.xquery.value.StringValue)10 Node (org.w3c.dom.Node)10 MemTreeBuilder (org.exist.dom.memtree.MemTreeBuilder)9 AtomicValue (org.exist.xquery.value.AtomicValue)9 Txn (org.exist.storage.txn.Txn)8 IOException (java.io.IOException)7 StringWriter (java.io.StringWriter)7 EXistException (org.exist.EXistException)7