Search in sources :

Example 1 with StringSource

use of org.exist.source.StringSource in project exist by eXist-db.

the class Eval method doEval.

private Sequence doEval(final XQueryContext evalContext, final Sequence contextSequence, final Sequence[] args) throws XPathException {
    if (evalContext.getProfiler().isEnabled()) {
        evalContext.getProfiler().start(this);
        evalContext.getProfiler().message(this, Profiler.DEPENDENCIES, "DEPENDENCIES", Dependency.getDependenciesName(this.getDependencies()));
        if (contextSequence != null) {
            evalContext.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT SEQUENCE", contextSequence);
        }
    }
    int argCount = 0;
    Sequence exprContext = null;
    if (isCalledAs(FS_EVAL_INLINE_NAME)) {
        // the current expression context
        exprContext = args[argCount++];
    }
    // get the query expression
    final Item expr = args[argCount++].itemAt(0);
    final Source querySource;
    if (Type.subTypeOf(expr.getType(), Type.ANY_URI)) {
        querySource = loadQueryFromURI(expr);
    } else {
        final String queryStr = expr.getStringValue();
        if (queryStr.trim().isEmpty()) {
            return new EmptySequence();
        }
        querySource = new StringSource(queryStr);
    }
    final NodeValue contextInit;
    if (isCalledAs(FS_EVAL_WITH_CONTEXT_NAME)) {
        // set the context initialization param for later use
        contextInit = (NodeValue) args[argCount++].itemAt(0);
    } else {
        contextInit = null;
    }
    // should the compiled query be cached?
    final boolean cache;
    if (isCalledAs(FS_EVAL_AND_SERIALIZE_NAME)) {
        cache = true;
    } else if (argCount < getArgumentCount()) {
        cache = ((BooleanValue) args[argCount++].itemAt(0)).effectiveBooleanValue();
    } else {
        cache = false;
    }
    // save some context properties
    evalContext.pushNamespaceContext();
    final LocalVariable mark = evalContext.markLocalVariables(false);
    // save the static document set of the current context, so it can be restored later
    final DocumentSet oldDocs = evalContext.getStaticDocs();
    if (exprContext != null) {
        evalContext.setStaticallyKnownDocuments(exprContext.getDocumentSet());
    }
    if (evalContext.isProfilingEnabled(2)) {
        evalContext.getProfiler().start(this, "eval: " + expr);
    }
    // fixme! - hook for debugger here /ljo
    final XQuery xqueryService = evalContext.getBroker().getBrokerPool().getXQueryService();
    final XQueryContext innerContext;
    final Sequence initContextSequence;
    if (contextInit != null) {
        // eval-with-context: initialize a new context
        innerContext = new XQueryContext(context.getBroker().getBrokerPool());
        initContextSequence = initContext(contextInit.getNode(), innerContext);
    } else {
        // use the existing outer context
        // TODO: check if copying the static context would be sufficient???
        innerContext = evalContext.copyContext();
        innerContext.setShared(true);
        // innerContext = context;
        initContextSequence = null;
    }
    // set module load path
    if (Type.subTypeOf(expr.getType(), Type.ANY_URI)) {
        String uri = null;
        if (querySource instanceof DBSource) {
            final XmldbURI documentPath = ((DBSource) querySource).getDocumentPath();
            uri = XmldbURI.EMBEDDED_SERVER_URI.append(documentPath).removeLastSegment().toString();
        } else if (querySource instanceof FileSource) {
            uri = ((FileSource) querySource).getPath().getParent().toString();
        }
        if (uri != null) {
            innerContext.setModuleLoadPath(uri);
        }
    }
    // bind external vars?
    if (isCalledAs(FS_EVAL_NAME) && getArgumentCount() >= 3) {
        final Sequence externalVars = args[argCount++];
        for (int i = 0; i < externalVars.getItemCount(); i++) {
            final Item varName = externalVars.itemAt(i);
            if (varName.getType() == Type.QNAME) {
                final Item varValue = externalVars.itemAt(++i);
                innerContext.declareVariable(((QNameValue) varName).getQName(), varValue);
            }
        }
    }
    // determine if original line/column number are passed on
    final boolean pass;
    if (isCalledAs(FS_EVAL_NAME) && getArgumentCount() == 4) {
        pass = args[3].itemAt(0).toJavaObject(Boolean.class);
    } else if (isCalledAs(FS_EVAL_WITH_CONTEXT_NAME) && getArgumentCount() == 5) {
        pass = args[4].itemAt(0).toJavaObject(Boolean.class);
    } else if (isCalledAs(FS_EVAL_INLINE_NAME) && getArgumentCount() == 4) {
        pass = args[3].itemAt(0).toJavaObject(Boolean.class);
    } else if (isCalledAs(FS_EVAL_AND_SERIALIZE_NAME) && getArgumentCount() == 5) {
        pass = args[4].itemAt(0).toJavaObject(Boolean.class);
    } else {
        // default
        pass = false;
    }
    // fixme! - hook for debugger here /ljo
    try {
        if (isCalledAs(FS_EVAL_WITH_CONTEXT_NAME) && getArgumentCount() >= 4) {
            final Item contextItem = args[argCount++].itemAt(0);
            if (contextItem != null) {
                // TODO : sort this out
                if (exprContext != null) {
                    LOG.warn("exprContext and contextItem are not null");
                }
                exprContext = contextItem.toSequence();
            }
        }
        if (initContextSequence != null) {
            exprContext = initContextSequence;
        }
        Sequence result = null;
        try {
            if (!isCalledAs(FS_EVAL_AND_SERIALIZE_NAME)) {
                result = execute(evalContext.getBroker(), xqueryService, querySource, innerContext, exprContext, cache, null);
                return result;
            } else {
                // get the default serialization options
                final Properties defaultOutputOptions;
                if (getArgumentCount() >= 2 && !args[1].isEmpty()) {
                    defaultOutputOptions = FunSerialize.getSerializationProperties(this, args[1].itemAt(0));
                } else {
                    defaultOutputOptions = new Properties();
                }
                // execute the query, XQuery prolog serialization options are collected into `xqueryOutputProperties`
                final Properties xqueryOutputProperties = new Properties();
                result = execute(evalContext.getBroker(), xqueryService, querySource, innerContext, exprContext, cache, xqueryOutputProperties);
                // do we need to subsequence the results?
                if (getArgumentCount() > 2) {
                    result = FunSubSequence.subsequence(result, ((DoubleValue) getArgument(2).eval(contextSequence, null).convertTo(Type.DOUBLE)), getArgumentCount() == 3 ? null : ((DoubleValue) getArgument(3).eval(contextSequence, null).convertTo(Type.DOUBLE)));
                }
                // override the default options with the ones from the xquery prolog
                final Properties serializationProperties = new Properties();
                serializationProperties.putAll(defaultOutputOptions);
                serializationProperties.putAll(xqueryOutputProperties);
                // serialize the results
                try (final StringWriter writer = new StringWriter()) {
                    final XQuerySerializer xqSerializer = new XQuerySerializer(context.getBroker(), serializationProperties, writer);
                    final Sequence seq;
                    if (xqSerializer.normalize()) {
                        seq = FunSerialize.normalize(this, context, result);
                    } else {
                        seq = result;
                    }
                    xqSerializer.serialize(seq);
                    return new StringValue(writer.toString());
                } catch (final IOException | SAXException e) {
                    throw new XPathException(this, FnModule.SENR0001, e.getMessage());
                }
            }
        } finally {
            cleanup(evalContext, innerContext, oldDocs, mark, expr, result);
        }
    } catch (final XPathException e) {
        try {
            e.prependMessage("Error while evaluating expression: " + querySource.getContent() + ". ");
        } catch (final IOException e1) {
        }
        if (!pass) {
            e.setLocation(line, column);
        }
        throw e;
    }
}
Also used : XQuerySerializer(org.exist.util.serializer.XQuerySerializer) Properties(java.util.Properties) StringSource(org.exist.source.StringSource) Source(org.exist.source.Source) DBSource(org.exist.source.DBSource) InputSource(org.xml.sax.InputSource) FileSource(org.exist.source.FileSource) SAXException(org.xml.sax.SAXException) StringWriter(java.io.StringWriter) DBSource(org.exist.source.DBSource) XmldbURI(org.exist.xmldb.XmldbURI) FileSource(org.exist.source.FileSource) FunSubSequence(org.exist.xquery.functions.fn.FunSubSequence) IOException(java.io.IOException) StringSource(org.exist.source.StringSource) DocumentSet(org.exist.dom.persistent.DocumentSet)

Example 2 with StringSource

use of org.exist.source.StringSource in project exist by eXist-db.

the class SendEmailIT method sendEmailJavaMail.

@Test
public void sendEmailJavaMail() throws EXistException, XPathException, PermissionDeniedException, IOException, MessagingException {
    final String from = "sender@place1.com";
    final String to = "recipient@place2.com";
    final String subject = "some email subject";
    final String messageText = UUIDGenerator.getUUIDversion4();
    final String query = "import module namespace mail = \"http://exist-db.org/xquery/mail\";\n" + "let $session := mail:get-mail-session(\n" + "    <properties>\n" + "        <property name=\"mail.transport.protocol\" value=\"smtp\"/>\n" + "        <property name=\"mail.smtp.port\" value=\"" + smtpPort + "\"/>\n" + "        <property name=\"mail.smtp.host\" value=\"127.0.0.1\"/>\n" + "    </properties>\n" + ")\n" + "return\n" + "    mail:send-email(\n" + "        $session,\n" + "        <mail><from>" + from + "</from><to>" + to + "</to><subject>" + subject + "</subject><message><text>" + messageText + "</text></message></mail>\n" + "    )";
    // send the email from XQuery via SMTP
    final BrokerPool pool = existEmbeddedServer.getBrokerPool();
    final Source source = new StringSource(query);
    try (final DBBroker broker = pool.getBroker();
        final Txn transaction = pool.getTransactionManager().beginTransaction()) {
        // execute query
        final Boolean sendResult = withCompiledQuery(broker, source, compiledXQuery -> {
            executeQuery(broker, compiledXQuery);
            return true;
        });
        transaction.commit();
        assertTrue(sendResult.booleanValue());
    }
    // check the SMTP server received the email
    final MimeMessage[] receivedMessages = greenMail.getReceivedMessages();
    assertEquals(1, receivedMessages.length);
    final MimeMessage receivedMessage = receivedMessages[0];
    // final Address sender = receivedMessage.getSender();
    // assertEquals(from, sender.toString());
    final Address[] recipients = receivedMessage.getRecipients(Message.RecipientType.TO);
    assertEquals(1, recipients.length);
    assertEquals(to, recipients[0].toString());
    assertEquals(subject, receivedMessage.getSubject());
    assertEquals(messageText, GreenMailUtil.getBody(receivedMessage));
}
Also used : DBBroker(org.exist.storage.DBBroker) Address(jakarta.mail.Address) MimeMessage(jakarta.mail.internet.MimeMessage) StringSource(org.exist.source.StringSource) Txn(org.exist.storage.txn.Txn) BrokerPool(org.exist.storage.BrokerPool) StringSource(org.exist.source.StringSource) Source(org.exist.source.Source) Test(org.junit.Test)

Example 3 with StringSource

use of org.exist.source.StringSource in project exist by eXist-db.

the class SendEmailIT method sendEmailSmtpDirect.

@Test
public void sendEmailSmtpDirect() throws EXistException, XPathException, PermissionDeniedException, IOException, MessagingException {
    final String from = "sender@place1.com";
    final String to = "recipient@place2.com";
    final String subject = "some email subject";
    final String messageText = UUIDGenerator.getUUIDversion4();
    final String query = "import module namespace mail = \"http://exist-db.org/xquery/mail\";\n" + "mail:send-email(\n" + "    <mail><from>" + from + "</from><to>" + to + "</to><subject>" + subject + "</subject><message><text>" + messageText + "</text></message></mail>,\n" + "    '127.0.0.1:" + smtpPort + "',\n" + "    ()\n" + ")";
    // send the email from XQuery via SMTP
    final BrokerPool pool = existEmbeddedServer.getBrokerPool();
    final Source source = new StringSource(query);
    try (final DBBroker broker = pool.getBroker();
        final Txn transaction = pool.getTransactionManager().beginTransaction()) {
        // execute query
        final Boolean sendResult = withCompiledQuery(broker, source, compiledXQuery -> {
            final Sequence result = executeQuery(broker, compiledXQuery);
            return result.itemAt(0).toJavaObject(boolean.class);
        });
        transaction.commit();
        assertTrue(sendResult.booleanValue());
    }
    // check the SMTP server received the email
    final MimeMessage[] receivedMessages = greenMail.getReceivedMessages();
    assertEquals(1, receivedMessages.length);
    final MimeMessage receivedMessage = receivedMessages[0];
    // final Address sender = receivedMessage.getSender();
    // assertEquals(from, sender.toString());
    final Address[] recipients = receivedMessage.getRecipients(Message.RecipientType.TO);
    assertEquals(1, recipients.length);
    assertEquals(to, recipients[0].toString());
    assertEquals(subject, receivedMessage.getSubject());
    assertEquals(messageText, GreenMailUtil.getBody(receivedMessage));
}
Also used : DBBroker(org.exist.storage.DBBroker) Address(jakarta.mail.Address) MimeMessage(jakarta.mail.internet.MimeMessage) StringSource(org.exist.source.StringSource) Txn(org.exist.storage.txn.Txn) Sequence(org.exist.xquery.value.Sequence) BrokerPool(org.exist.storage.BrokerPool) StringSource(org.exist.source.StringSource) Source(org.exist.source.Source) Test(org.junit.Test)

Example 4 with StringSource

use of org.exist.source.StringSource in project exist by eXist-db.

the class ConnectionIT method getConnectionCanBeExplicitlyClosed.

@Test
public void getConnectionCanBeExplicitlyClosed() throws EXistException, XPathException, PermissionDeniedException, IOException {
    final String query = "import module namespace sql = \"http://exist-db.org/xquery/sql\";\n" + "let $conn := sql:get-connection(\"" + h2Database.getDriverClass().getName() + "\", \"" + h2Database.getUrl() + "\", \"" + h2Database.getUser() + "\", \"" + h2Database.getPassword() + "\")\n" + "return sql:close-connection($conn)";
    final BrokerPool pool = existEmbeddedServer.getBrokerPool();
    final Source source = new StringSource(query);
    try (final DBBroker broker = pool.getBroker();
        final Txn transaction = pool.getTransactionManager().beginTransaction()) {
        // execute query
        final Tuple2<XQueryContext, Boolean> contextAndResult = withCompiledQuery(broker, source, compiledXQuery -> {
            final Sequence result = executeQuery(broker, compiledXQuery);
            return Tuple(compiledXQuery.getContext(), result.itemAt(0).toJavaObject(boolean.class));
        });
        // check that the handle for the sql connection was closed
        assertTrue(contextAndResult._2);
        // check the connections were closed
        final int connectionsCount = ModuleUtils.readContextMap(contextAndResult._1, SQLModule.CONNECTIONS_CONTEXTVAR, Map::size);
        assertEquals(0, connectionsCount);
        transaction.commit();
    }
}
Also used : DBBroker(org.exist.storage.DBBroker) StringSource(org.exist.source.StringSource) Txn(org.exist.storage.txn.Txn) Sequence(org.exist.xquery.value.Sequence) Map(java.util.Map) BrokerPool(org.exist.storage.BrokerPool) StringSource(org.exist.source.StringSource) StringInputSource(org.exist.util.StringInputSource) Source(org.exist.source.Source) Test(org.junit.Test)

Example 5 with StringSource

use of org.exist.source.StringSource in project exist by eXist-db.

the class ImplicitConnectionCloseIT method getJndiConnectionIsAutomaticallyClosed.

@Test
public void getJndiConnectionIsAutomaticallyClosed() throws EXistException, XPathException, PermissionDeniedException, IOException {
    final String mainQuery = "import module namespace sql = \"http://exist-db.org/xquery/sql\";\n" + "sql:get-jndi-connection(\"" + JNDI_DS_NAME + "\", \"" + STUB_JDBC_USER + "\", \"" + STUB_JDBC_PASSWORD + "\")";
    final BrokerPool pool = existEmbeddedServer.getBrokerPool();
    final Source mainQuerySource = new StringSource(mainQuery);
    try (final DBBroker broker = pool.getBroker();
        final Txn transaction = pool.getTransactionManager().beginTransaction()) {
        final XQueryContext escapedMainQueryContext = withCompiledQuery(broker, mainQuerySource, mainCompiledQuery -> {
            final XQueryContext mainQueryContext = mainCompiledQuery.getContext();
            // execute the query
            final Sequence result = executeQuery(broker, mainCompiledQuery);
            // check that the handle for the sql connection that was created was valid
            assertEquals(1, result.getItemCount());
            assertTrue(result.itemAt(0) instanceof IntegerValue);
            assertEquals(Type.LONG, result.itemAt(0).getType());
            final long connectionHandle = result.itemAt(0).toJavaObject(long.class);
            assertFalse(connectionHandle == 0);
            return mainQueryContext;
        });
        // check the connections map is empty
        final int connectionsCount = ModuleUtils.readContextMap(escapedMainQueryContext, SQLModule.CONNECTIONS_CONTEXTVAR, Map::size);
        assertEquals(0, connectionsCount);
        // check the connections from our StubDataSource, they should all be closed
        final Deque<StubDataSource> createdDataSources = StubDataSourceFactory.CREATED_DATA_SOURCES;
        assertEquals(1, createdDataSources.size());
        final StubDataSource stubDataSource = createdDataSources.peek();
        final Deque<StubConnection> createdConnections = stubDataSource.createdConnections;
        assertEquals(1, createdConnections.size());
        final StubConnection stubConnection = createdConnections.peek();
        assertTrue(stubConnection.isClosed());
        transaction.commit();
    }
}
Also used : IntegerValue(org.exist.xquery.value.IntegerValue) Txn(org.exist.storage.txn.Txn) Sequence(org.exist.xquery.value.Sequence) StringSource(org.exist.source.StringSource) StringInputSource(org.exist.util.StringInputSource) Source(org.exist.source.Source) DataSource(javax.sql.DataSource) DBBroker(org.exist.storage.DBBroker) StringSource(org.exist.source.StringSource) BrokerPool(org.exist.storage.BrokerPool) Test(org.junit.Test)

Aggregations

StringSource (org.exist.source.StringSource)59 Source (org.exist.source.Source)53 Txn (org.exist.storage.txn.Txn)41 BrokerPool (org.exist.storage.BrokerPool)40 DBBroker (org.exist.storage.DBBroker)40 Sequence (org.exist.xquery.value.Sequence)40 Test (org.junit.Test)37 StringInputSource (org.exist.util.StringInputSource)32 Collection (org.exist.collections.Collection)8 DBSource (org.exist.source.DBSource)8 IOException (java.io.IOException)7 Map (java.util.Map)7 EXistException (org.exist.EXistException)7 XmldbURI (org.exist.xmldb.XmldbURI)7 Element (org.w3c.dom.Element)7 InputSource (org.xml.sax.InputSource)7 Diff (org.xmlunit.diff.Diff)7 XQueryPool (org.exist.storage.XQueryPool)6 XQueryContext (org.exist.xquery.XQueryContext)6 IntegerValue (org.exist.xquery.value.IntegerValue)6