Search in sources :

Example 1 with ElementImpl

use of org.exist.dom.memtree.ElementImpl in project exist by eXist-db.

the class RESTServer method declareExternalAndXQJVariables.

private void declareExternalAndXQJVariables(final XQueryContext context, final ElementImpl variables) throws XPathException {
    final ValueSequence varSeq = new ValueSequence();
    variables.selectChildren(new NameTest(Type.ELEMENT, new QName(Variable.xmlKey(), Namespaces.EXIST_NS)), varSeq);
    for (final SequenceIterator i = varSeq.iterate(); i.hasNext(); ) {
        final ElementImpl variable = (ElementImpl) i.nextItem();
        // get the QName of the variable
        final ElementImpl qname = (ElementImpl) variable.getFirstChild(new NameTest(Type.ELEMENT, new QName("qname", Namespaces.EXIST_NS)));
        String localname = null, prefix = null, uri = null;
        NodeImpl child = (NodeImpl) qname.getFirstChild();
        while (child != null) {
            if ("localname".equals(child.getLocalName())) {
                localname = child.getStringValue();
            } else if ("namespace".equals(child.getLocalName())) {
                uri = child.getStringValue();
            } else if ("prefix".equals(child.getLocalName())) {
                prefix = child.getStringValue();
            }
            child = (NodeImpl) child.getNextSibling();
        }
        if (uri != null && prefix != null) {
            context.declareNamespace(prefix, uri);
        }
        if (localname == null) {
            continue;
        }
        final QName q;
        if (prefix != null && localname != null) {
            q = new QName(localname, uri, prefix);
        } else {
            q = new QName(localname, uri, XMLConstants.DEFAULT_NS_PREFIX);
        }
        // get serialized sequence
        final NodeImpl value = variable.getFirstChild(new NameTest(Type.ELEMENT, Marshaller.ROOT_ELEMENT_QNAME));
        final Sequence sequence;
        try {
            sequence = value == null ? Sequence.EMPTY_SEQUENCE : Marshaller.demarshall(value);
        } catch (final XMLStreamException xe) {
            throw new XPathException(xe.toString());
        }
        // now declare variable
        if (prefix != null) {
            context.declareVariable(q.getPrefix() + ":" + q.getLocalPart(), sequence);
        } else {
            context.declareVariable(q.getLocalPart(), sequence);
        }
    }
}
Also used : ElementImpl(org.exist.dom.memtree.ElementImpl) NodeImpl(org.exist.dom.memtree.NodeImpl) XMLStreamException(javax.xml.stream.XMLStreamException) QName(org.exist.dom.QName)

Example 2 with ElementImpl

use of org.exist.dom.memtree.ElementImpl in project exist by eXist-db.

the class RESTServer method doPost.

/**
 * Handles POST requests. If the path leads to a binary resource with
 * mime-type "application/xquery", that resource will be read and executed
 * by the XQuery engine. Otherwise, the request content is loaded and parsed
 * as XML. It may either contain an XUpdate or a query request.
 *
 * @param broker the database broker
 * @param transaction the database transaction
 * @param request the request
 * @param response the response
 * @param path the path of the request
 *
 * @throws BadRequestException if a bad request is made
 * @throws PermissionDeniedException if the request has insufficient permissions
 * @throws NotFoundException if the request resource cannot be found
 * @throws IOException if an I/O error occurs
 */
public void doPost(final DBBroker broker, final Txn transaction, final HttpServletRequest request, final HttpServletResponse response, final String path) throws BadRequestException, PermissionDeniedException, IOException, NotFoundException {
    // if required, set character encoding
    if (request.getCharacterEncoding() == null) {
        request.setCharacterEncoding(formEncoding);
    }
    final Properties outputProperties = new Properties(defaultOutputKeysProperties);
    final XmldbURI pathUri = XmldbURI.createInternal(path);
    LockedDocument lockedDocument = null;
    DocumentImpl resource = null;
    final String encoding = outputProperties.getProperty(OutputKeys.ENCODING);
    String mimeType = outputProperties.getProperty(OutputKeys.MEDIA_TYPE);
    try {
        // check if path leads to an XQuery resource.
        // if yes, the resource is loaded and the XQuery executed.
        final String xquery_mime_type = MimeType.XQUERY_TYPE.getName();
        final String xproc_mime_type = MimeType.XPROC_TYPE.getName();
        lockedDocument = broker.getXMLResource(pathUri, LockMode.READ_LOCK);
        resource = lockedDocument == null ? null : lockedDocument.getDocument();
        XmldbURI servletPath = pathUri;
        // xquery resource
        while (null == resource) {
            // traverse up the path looking for xquery objects
            servletPath = servletPath.removeLastSegment();
            if (servletPath == XmldbURI.EMPTY_URI) {
                break;
            }
            lockedDocument = broker.getXMLResource(servletPath, LockMode.READ_LOCK);
            resource = lockedDocument == null ? null : lockedDocument.getDocument();
            if (null != resource && (resource.getResourceType() == DocumentImpl.BINARY_FILE && xquery_mime_type.equals(resource.getMimeType()) || resource.getResourceType() == DocumentImpl.XML_FILE && xproc_mime_type.equals(resource.getMimeType()))) {
                // found a binary file with mime-type xquery or XML file with mime-type xproc
                break;
            } else if (null != resource) {
                // not an xquery or xproc resource. This means we have a path
                // that cannot contain an xquery or xproc object even if we keep
                // moving up the path, so bail out now
                lockedDocument.close();
                lockedDocument = null;
                resource = null;
                break;
            }
        }
        // either xquery binary file or xproc xml file
        if (resource != null) {
            if (resource.getResourceType() == DocumentImpl.BINARY_FILE && xquery_mime_type.equals(resource.getMimeType()) || resource.getResourceType() == DocumentImpl.XML_FILE && xproc_mime_type.equals(resource.getMimeType())) {
                // found an XQuery resource, fixup request values
                final String pathInfo = pathUri.trimFromBeginning(servletPath).toString();
                try {
                    if (xquery_mime_type.equals(resource.getMimeType())) {
                        // Execute the XQuery
                        executeXQuery(broker, transaction, resource, request, response, outputProperties, servletPath.toString(), pathInfo);
                    } else {
                        // Execute the XProc
                        executeXProc(broker, transaction, resource, request, response, outputProperties, servletPath.toString(), pathInfo);
                    }
                } catch (final XPathException e) {
                    if (MimeType.XML_TYPE.getName().equals(mimeType)) {
                        writeXPathException(response, HttpServletResponse.SC_BAD_REQUEST, encoding, null, path, e);
                    } else {
                        writeXPathExceptionHtml(response, HttpServletResponse.SC_BAD_REQUEST, encoding, null, path, e);
                    }
                }
                return;
            }
        }
    } finally {
        if (lockedDocument != null) {
            lockedDocument.close();
        }
    }
    // check the content type to see if its XML or a parameter string
    String requestType = request.getContentType();
    if (requestType != null) {
        final int semicolon = requestType.indexOf(';');
        if (semicolon > 0) {
            requestType = requestType.substring(0, semicolon).trim();
        }
    }
    // content type != application/x-www-form-urlencoded
    if (requestType == null || !requestType.equals(MimeType.URL_ENCODED_TYPE.getName())) {
        // third, normal POST: read the request content and check if
        // it is an XUpdate or a query request.
        int howmany = 10;
        int start = 1;
        boolean typed = false;
        ElementImpl variables = null;
        boolean enclose = true;
        boolean cache = false;
        String query = null;
        try {
            final String content = getRequestContent(request);
            final NamespaceExtractor nsExtractor = new NamespaceExtractor();
            final ElementImpl root = parseXML(broker.getBrokerPool(), content, nsExtractor);
            final String rootNS = root.getNamespaceURI();
            if (rootNS != null && rootNS.equals(Namespaces.EXIST_NS)) {
                if (Query.xmlKey().equals(root.getLocalName())) {
                    // process <query>xpathQuery</query>
                    String option = root.getAttribute(Start.xmlKey());
                    if (option != null) {
                        try {
                            start = Integer.parseInt(option);
                        } catch (final NumberFormatException e) {
                        // 
                        }
                    }
                    option = root.getAttribute(Max.xmlKey());
                    if (option != null) {
                        try {
                            howmany = Integer.parseInt(option);
                        } catch (final NumberFormatException e) {
                        // 
                        }
                    }
                    option = root.getAttribute(Enclose.xmlKey());
                    if (option != null) {
                        if ("no".equals(option)) {
                            enclose = false;
                        }
                    } else {
                        option = root.getAttribute(Wrap.xmlKey());
                        if (option != null) {
                            if ("no".equals(option)) {
                                enclose = false;
                            }
                        }
                    }
                    option = root.getAttribute(Method.xmlKey());
                    if ((option != null) && (!option.isEmpty())) {
                        outputProperties.setProperty(SERIALIZATION_METHOD_PROPERTY, option);
                    }
                    option = root.getAttribute(Typed.xmlKey());
                    if (option != null) {
                        if ("yes".equals(option)) {
                            typed = true;
                        }
                    }
                    option = root.getAttribute(Mime.xmlKey());
                    if ((option != null) && (!option.isEmpty())) {
                        mimeType = option;
                    }
                    if ((option = root.getAttribute(Cache.xmlKey())) != null) {
                        cache = "yes".equals(option);
                    }
                    if ((option = root.getAttribute(Session.xmlKey())) != null && option.length() > 0) {
                        outputProperties.setProperty(Serializer.PROPERTY_SESSION_ID, option);
                    }
                    final NodeList children = root.getChildNodes();
                    for (int i = 0; i < children.getLength(); i++) {
                        final Node child = children.item(i);
                        if (child.getNodeType() == Node.ELEMENT_NODE && child.getNamespaceURI().equals(Namespaces.EXIST_NS)) {
                            if (Text.xmlKey().equals(child.getLocalName())) {
                                final StringBuilder buf = new StringBuilder();
                                Node next = child.getFirstChild();
                                while (next != null) {
                                    if (next.getNodeType() == Node.TEXT_NODE || next.getNodeType() == Node.CDATA_SECTION_NODE) {
                                        buf.append(next.getNodeValue());
                                    }
                                    next = next.getNextSibling();
                                }
                                query = buf.toString();
                            } else if (Variables.xmlKey().equals(child.getLocalName())) {
                                variables = (ElementImpl) child;
                            } else if (Properties.xmlKey().equals(child.getLocalName())) {
                                Node node = child.getFirstChild();
                                while (node != null) {
                                    if (node.getNodeType() == Node.ELEMENT_NODE && node.getNamespaceURI().equals(Namespaces.EXIST_NS) && Property.xmlKey().equals(node.getLocalName())) {
                                        final Element property = (Element) node;
                                        final String key = property.getAttribute("name");
                                        final String value = property.getAttribute("value");
                                        LOG.debug("{} = {}", key, value);
                                        if (key != null && value != null) {
                                            outputProperties.setProperty(key, value);
                                        }
                                    }
                                    node = node.getNextSibling();
                                }
                            }
                        }
                    }
                }
                // execute query
                if (query != null) {
                    try {
                        search(broker, transaction, query, path, nsExtractor.getNamespaces(), variables, howmany, start, typed, outputProperties, enclose, cache, request, response);
                    } catch (final XPathException e) {
                        if (MimeType.XML_TYPE.getName().equals(mimeType)) {
                            writeXPathException(response, HttpServletResponse.SC_BAD_REQUEST, encoding, null, path, e);
                        } else {
                            writeXPathExceptionHtml(response, HttpServletResponse.SC_BAD_REQUEST, encoding, null, path, e);
                        }
                    }
                } else {
                    throw new BadRequestException("No query specified");
                }
            } else if (rootNS != null && rootNS.equals(XUpdateProcessor.XUPDATE_NS)) {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Got xupdate request: {}", content);
                }
                if (xupdateSubmission == EXistServlet.FeatureEnabled.FALSE) {
                    response.setStatus(HttpServletResponse.SC_FORBIDDEN);
                    return;
                } else if (xupdateSubmission == EXistServlet.FeatureEnabled.AUTHENTICATED_USERS_ONLY) {
                    final Subject currentSubject = broker.getCurrentSubject();
                    if (!currentSubject.isAuthenticated() || currentSubject.getId() == RealmImpl.GUEST_GROUP_ID) {
                        response.setStatus(HttpServletResponse.SC_FORBIDDEN);
                        return;
                    }
                }
                final MutableDocumentSet docs = new DefaultDocumentSet();
                final boolean isCollection;
                try (final Collection collection = broker.openCollection(pathUri, LockMode.READ_LOCK)) {
                    if (collection != null) {
                        isCollection = true;
                        collection.allDocs(broker, docs, true);
                    } else {
                        isCollection = false;
                    }
                }
                if (!isCollection) {
                    final DocumentImpl xupdateDoc = broker.getResource(pathUri, Permission.READ);
                    if (xupdateDoc != null) {
                        docs.add(xupdateDoc);
                    } else {
                        broker.getAllXMLResources(docs);
                    }
                }
                final XUpdateProcessor processor = new XUpdateProcessor(broker, docs);
                long mods = 0;
                try (final Reader reader = new StringReader(content)) {
                    final Modification[] modifications = processor.parse(new InputSource(reader));
                    for (Modification modification : modifications) {
                        mods += modification.process(transaction);
                        broker.flush();
                    }
                }
                // FD : Returns an XML doc
                writeXUpdateResult(response, encoding, mods);
            // END FD
            } else {
                throw new BadRequestException("Unknown XML root element: " + root.getNodeName());
            }
        } catch (final SAXException e) {
            Exception cause = e;
            if (e.getException() != null) {
                cause = e.getException();
            }
            LOG.debug("SAX exception while parsing request: {}", cause.getMessage(), cause);
            throw new BadRequestException("SAX exception while parsing request: " + cause.getMessage());
        } catch (final ParserConfigurationException e) {
            throw new BadRequestException("Parser exception while parsing request: " + e.getMessage());
        } catch (final XPathException e) {
            throw new BadRequestException("Query exception while parsing request: " + e.getMessage());
        } catch (final IOException e) {
            throw new BadRequestException("IO exception while parsing request: " + e.getMessage());
        } catch (final EXistException e) {
            throw new BadRequestException(e.getMessage());
        } catch (final LockException e) {
            throw new PermissionDeniedException(e.getMessage());
        }
    // content type = application/x-www-form-urlencoded
    } else {
        doGet(broker, transaction, request, response, path);
    }
}
Also used : XUpdateProcessor(org.exist.xupdate.XUpdateProcessor) Modification(org.exist.xupdate.Modification) InputSource(org.xml.sax.InputSource) JSONNode(org.exist.util.serializer.json.JSONNode) Node(org.w3c.dom.Node) Element(org.w3c.dom.Element) XMLReader(org.xml.sax.XMLReader) Properties(java.util.Properties) SAXException(org.xml.sax.SAXException) ElementImpl(org.exist.dom.memtree.ElementImpl) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException) XmldbURI(org.exist.xmldb.XmldbURI) NodeList(org.w3c.dom.NodeList) EXistException(org.exist.EXistException) Subject(org.exist.security.Subject) PermissionDeniedException(org.exist.security.PermissionDeniedException) XMLStreamException(javax.xml.stream.XMLStreamException) SAXException(org.xml.sax.SAXException) TriggerException(org.exist.collections.triggers.TriggerException) EXistException(org.exist.EXistException) TransformerConfigurationException(javax.xml.transform.TransformerConfigurationException) SAXParseException(org.xml.sax.SAXParseException) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException) Collection(org.exist.collections.Collection) PermissionDeniedException(org.exist.security.PermissionDeniedException)

Example 3 with ElementImpl

use of org.exist.dom.memtree.ElementImpl in project exist by eXist-db.

the class MessageFunctions method handlePart.

private void handlePart(Part part, MemTreeBuilder builder) throws MessagingException, IOException, XPathException, SAXException {
    Object content = part.getContent();
    if (content instanceof Multipart) {
        handleMultipart((Multipart) content, builder);
        return;
    }
    String disposition = part.getDisposition();
    String contentType = part.getContentType();
    // Check if plain
    if (contentType.contains("text/plain")) {
        builder.startElement(new QName("text", MailModule.NAMESPACE_URI, MailModule.PREFIX), null);
        mimeParamsToAttributes(builder, part.getContentType());
        builder.characters(part.getContent().toString());
        builder.endElement();
    } else if (contentType.contains("text/html")) {
        builder.startElement(new QName("xhtml", MailModule.NAMESPACE_URI, MailModule.PREFIX), null);
        mimeParamsToAttributes(builder, part.getContentType());
        // extract and clean up the html
        DocumentBuilderReceiver receiver = new DocumentBuilderReceiver(builder);
        try (InputStream inputStream = part.getInputStream()) {
            DocumentImpl html = ModuleUtils.htmlToXHtml(context, new StreamSource(inputStream), null, null);
            ElementImpl rootElem = (ElementImpl) html.getDocumentElement();
            html.copyTo(rootElem, receiver);
            builder.endElement();
        }
    } else if (disposition.equalsIgnoreCase(Part.ATTACHMENT)) {
        builder.startElement(new QName("attachment", MailModule.NAMESPACE_URI, MailModule.PREFIX), null);
        builder.addAttribute(new QName("filename", null, null), part.getFileName());
        mimeParamsToAttributes(builder, part.getContentType());
        handleBinaryContent(part, builder);
        builder.endElement();
    } else if (disposition.equalsIgnoreCase(Part.INLINE)) {
        builder.startElement(new QName("inline", MailModule.NAMESPACE_URI, MailModule.PREFIX), null);
        MimeBodyPart mbp = (MimeBodyPart) part;
        builder.addAttribute(new QName("filename", null, null), mbp.getFileName());
        // fix content id so that it matches the cid: format within the html
        if (mbp.getContentID() != null) {
            builder.addAttribute(new QName("content-id", null, null), "cid:" + mbp.getContentID().replaceAll("^<|>$", ""));
        }
        mimeParamsToAttributes(builder, part.getContentType());
        handleBinaryContent(part, builder);
        builder.endElement();
    } else {
        // Should never happen
        builder.startElement(new QName("other", MailModule.NAMESPACE_URI, MailModule.PREFIX), null);
        mimeParamsToAttributes(builder, part.getContentType());
        builder.addAttribute(new QName("disposition", null, null), part.getDisposition());
        builder.characters(part.getContent().toString());
        builder.endElement();
    }
}
Also used : ElementImpl(org.exist.dom.memtree.ElementImpl) QName(org.exist.dom.QName) StreamSource(javax.xml.transform.stream.StreamSource) DocumentBuilderReceiver(org.exist.dom.memtree.DocumentBuilderReceiver) MimeBodyPart(jakarta.mail.internet.MimeBodyPart) DocumentImpl(org.exist.dom.memtree.DocumentImpl)

Example 4 with ElementImpl

use of org.exist.dom.memtree.ElementImpl in project exist by eXist-db.

the class Execute method createReport.

private ElementImpl createReport(int exitValue, List<String> output, List<String> cmdArgs) {
    context.pushDocumentContext();
    try {
        MemTreeBuilder builder = context.getDocumentBuilder();
        AttributesImpl attribs = new AttributesImpl();
        attribs.addAttribute("", "exitCode", "exitCode", "CDATA", Integer.toString(exitValue));
        builder.startDocument();
        int nodeNr = builder.startElement(RESULT_QNAME, attribs);
        // print command line
        StringBuilder cmdLine = new StringBuilder();
        for (String param : cmdArgs) {
            cmdLine.append(param).append(' ');
        }
        builder.startElement(COMMAND_LINE_QNAME, null);
        builder.characters(cmdLine.toString());
        builder.endElement();
        // print received output to <stdout>
        builder.startElement(STDOUT_QNAME, null);
        for (String line : output) {
            builder.startElement(LINE_QNAME, null);
            builder.characters(line);
            builder.endElement();
        }
        builder.endElement();
        builder.endElement();
        return (ElementImpl) builder.getDocument().getNode(nodeNr);
    } finally {
        context.popDocumentContext();
    }
}
Also used : AttributesImpl(org.xml.sax.helpers.AttributesImpl) ElementImpl(org.exist.dom.memtree.ElementImpl) MemTreeBuilder(org.exist.dom.memtree.MemTreeBuilder)

Example 5 with ElementImpl

use of org.exist.dom.memtree.ElementImpl in project exist by eXist-db.

the class SerializeAttrMatchesTest method expandAttr.

@Test
public void expandAttr() throws CollectionConfigurationException, LockException, IOException, SAXException, PermissionDeniedException, EXistException, XPathException {
    configureAndStore(COLLECTION_CONFIG, XML, "test1.xml");
    // query and expand
    final String query = "for $hit in collection(\"" + TestConstants.TEST_COLLECTION_URI.toString() + "\")//w[ft:query(@lemma, <query><regex>књиг.*</regex></query>)]\n" + "return util:expand($hit, \"highlight-matches=both\")";
    final BrokerPool pool = existEmbeddedServer.getBrokerPool();
    try (final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().getSystemSubject()))) {
        final XQuery xquery = pool.getXQueryService();
        final Sequence seq = xquery.execute(broker, query, null);
        assertEquals(1, seq.getItemCount());
        final Item item = seq.itemAt(0);
        assertTrue(item instanceof ElementImpl);
        assertEquals("lemma", ((ElementImpl) item).getAttribute("exist:matches"));
    }
}
Also used : Item(org.exist.xquery.value.Item) DBBroker(org.exist.storage.DBBroker) ElementImpl(org.exist.dom.memtree.ElementImpl) XQuery(org.exist.xquery.XQuery) Sequence(org.exist.xquery.value.Sequence) BrokerPool(org.exist.storage.BrokerPool)

Aggregations

ElementImpl (org.exist.dom.memtree.ElementImpl)16 BrokerPool (org.exist.storage.BrokerPool)7 DBBroker (org.exist.storage.DBBroker)7 Sequence (org.exist.xquery.value.Sequence)7 QName (org.exist.dom.QName)6 XQuery (org.exist.xquery.XQuery)6 NodeList (org.w3c.dom.NodeList)6 MemTreeBuilder (org.exist.dom.memtree.MemTreeBuilder)5 Item (org.exist.xquery.value.Item)5 Test (org.junit.Test)5 Element (org.w3c.dom.Element)5 Txn (org.exist.storage.txn.Txn)4 XQueryContext (org.exist.xquery.XQueryContext)3 Properties (java.util.Properties)2 XMLStreamException (javax.xml.stream.XMLStreamException)2 Collection (org.exist.collections.Collection)2 PermissionDeniedException (org.exist.security.PermissionDeniedException)2 XmldbURI (org.exist.xmldb.XmldbURI)2 Node (org.w3c.dom.Node)2 InputSource (org.xml.sax.InputSource)2