Search in sources :

Example 81 with Item

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

the class DynamicTextConstructor method eval.

/* (non-Javadoc)
     * @see org.exist.xquery.Expression#eval(org.exist.xquery.value.Sequence, org.exist.xquery.value.Item)
     */
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 (newDocumentContext) {
        context.pushDocumentContext();
    }
    Sequence result;
    try {
        final Sequence contentSeq = content.eval(contextSequence, contextItem);
        if (contentSeq.isEmpty()) {
            result = Sequence.EMPTY_SEQUENCE;
        } else {
            final MemTreeBuilder builder = context.getDocumentBuilder();
            context.proceed(this, builder);
            final StringBuilder buf = new StringBuilder();
            for (final SequenceIterator i = Atomize.atomize(contentSeq).iterate(); i.hasNext(); ) {
                context.proceed(this, builder);
                final Item next = i.nextItem();
                if (buf.length() > 0) {
                    buf.append(' ');
                }
                buf.append(next.toString());
            }
            // such a text node will be deleted or merged with another text node.
            if (!newDocumentContext && buf.length() == 0) {
                result = Sequence.EMPTY_SEQUENCE;
            } else {
                final int nodeNr = builder.characters(buf);
                result = builder.getDocument().getNode(nodeNr);
            }
        }
    } finally {
        if (newDocumentContext) {
            context.popDocumentContext();
        }
    }
    if (context.getProfiler().isEnabled()) {
        context.getProfiler().end(this, "", result);
    }
    return result;
}
Also used : Item(org.exist.xquery.value.Item) MemTreeBuilder(org.exist.dom.memtree.MemTreeBuilder) SequenceIterator(org.exist.xquery.value.SequenceIterator) Sequence(org.exist.xquery.value.Sequence)

Example 82 with Item

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

the class XMLDBStore method evalWithCollection.

@Override
public Sequence evalWithCollection(Collection collection, Sequence[] args, Sequence contextSequence) throws XPathException {
    String docName = args[1].isEmpty() ? null : args[1].getStringValue();
    if (docName != null && docName.isEmpty()) {
        docName = null;
    } else if (docName != null) {
        docName = new AnyURIValue(docName).toXmldbURI().toString();
    }
    final Item item = args[2].itemAt(0);
    // determine the mime type
    final boolean storeAsBinary = isCalledAs(FS_STORE_BINARY_NAME);
    MimeType mimeType = null;
    if (getSignature().getArgumentCount() == 4) {
        final String strMimeType = args[3].getStringValue();
        mimeType = MimeTable.getInstance().getContentType(strMimeType);
    }
    if (mimeType == null && docName != null) {
        mimeType = MimeTable.getInstance().getContentTypeFor(docName);
    }
    if (mimeType == null) {
        mimeType = (storeAsBinary || !Type.subTypeOf(item.getType(), Type.NODE)) ? MimeType.BINARY_TYPE : MimeType.XML_TYPE;
    } else if (storeAsBinary) {
        mimeType = new MimeType(mimeType.getName(), MimeType.BINARY);
    }
    Resource resource;
    try {
        if (Type.subTypeOf(item.getType(), Type.JAVA_OBJECT)) {
            final Object obj = ((JavaObjectValue) item).getObject();
            if (obj instanceof java.io.File) {
                resource = loadFromFile(collection, ((java.io.File) obj).toPath(), docName, mimeType);
            } else if (obj instanceof java.nio.file.Path) {
                resource = loadFromFile(collection, (Path) obj, docName, mimeType);
            } else {
                LOGGER.error("Passed java object should be either a java.nio.file.Path or java.io.File");
                throw new XPathException(this, "Passed java object should be either a java.nio.file.Path or java.io.File");
            }
        } else if (Type.subTypeOf(item.getType(), Type.ANY_URI)) {
            try {
                final URI uri = new URI(item.getStringValue());
                resource = loadFromURI(collection, uri, docName, mimeType);
            } catch (final URISyntaxException e) {
                LOGGER.error("Invalid URI: {}", item.getStringValue());
                throw new XPathException(this, "Invalid URI: " + item.getStringValue(), e);
            }
        } else {
            if (mimeType.isXMLType()) {
                resource = collection.createResource(docName, "XMLResource");
            } else {
                resource = collection.createResource(docName, "BinaryResource");
            }
            if (Type.subTypeOf(item.getType(), Type.STRING)) {
                resource.setContent(item.getStringValue());
            } else if (item.getType() == Type.BASE64_BINARY) {
                resource.setContent(((BinaryValue) item).toJavaObject());
            } else if (Type.subTypeOf(item.getType(), Type.NODE)) {
                if (mimeType.isXMLType()) {
                    final ContentHandler handler = ((XMLResource) resource).setContentAsSAX();
                    handler.startDocument();
                    item.toSAX(context.getBroker(), handler, SERIALIZATION_PROPERTIES);
                    handler.endDocument();
                } else {
                    try (final StringWriter writer = new StringWriter()) {
                        final SAXSerializer serializer = new SAXSerializer();
                        serializer.setOutput(writer, null);
                        item.toSAX(context.getBroker(), serializer, SERIALIZATION_PROPERTIES);
                        resource.setContent(writer.toString());
                    } catch (final IOException e) {
                        LOGGER.error(e.getMessage(), e);
                    }
                }
            } else {
                LOGGER.error("Data should be either a node or a string");
                throw new XPathException(this, "Data should be either a node or a string");
            }
            ((EXistResource) resource).setMimeType(mimeType.getName());
            collection.storeResource(resource);
        }
    } catch (final XMLDBException e) {
        LOGGER.error(e.getMessage(), e);
        throw new XPathException(this, "XMLDB reported an exception while storing document: " + e.getMessage(), e);
    } catch (final SAXException e) {
        LOGGER.error(e.getMessage());
        throw new XPathException(this, "SAX reported an exception while storing document", e);
    }
    if (resource == null) {
        return Sequence.EMPTY_SEQUENCE;
    } else {
        try {
            // TODO : use dedicated function in XmldbURI
            return new StringValue(collection.getName() + "/" + resource.getId());
        } catch (final XMLDBException e) {
            LOGGER.error(e.getMessage());
            throw new XPathException(this, "XMLDB reported an exception while retrieving the " + "stored document", e);
        }
    }
}
Also used : XPathException(org.exist.xquery.XPathException) AnyURIValue(org.exist.xquery.value.AnyURIValue) BinaryResource(org.xmldb.api.modules.BinaryResource) XMLResource(org.xmldb.api.modules.XMLResource) EXistResource(org.exist.xmldb.EXistResource) Resource(org.xmldb.api.base.Resource) XMLDBException(org.xmldb.api.base.XMLDBException) URISyntaxException(java.net.URISyntaxException) IOException(java.io.IOException) URI(java.net.URI) MimeType(org.exist.util.MimeType) ContentHandler(org.xml.sax.ContentHandler) SAXException(org.xml.sax.SAXException) Item(org.exist.xquery.value.Item) StringWriter(java.io.StringWriter) JavaObjectValue(org.exist.xquery.value.JavaObjectValue) SAXSerializer(org.exist.util.serializer.SAXSerializer) StringValue(org.exist.xquery.value.StringValue) Path(java.nio.file.Path)

Example 83 with Item

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

the class Modification method selectAndLock.

/**
 * Acquire a lock on all documents processed by this modification.
 * We have to avoid that node positions change during the
 * operation.
 *
 * @param nodes sequence containing nodes from documents to lock
 * @param transaction current transaction
 * @return array of nodes for which lock was acquired
 *
 * @throws LockException in case locking failed
 * @throws TriggerException in case of error thrown by triggers
 * @throws XPathException in case of dynamic error
 */
protected StoredNode[] selectAndLock(Txn transaction, Sequence nodes) throws LockException, XPathException, TriggerException {
    final java.util.concurrent.locks.Lock globalLock = context.getBroker().getBrokerPool().getGlobalUpdateLock();
    globalLock.lock();
    try {
        final DocumentSet lockedDocuments = nodes.getDocumentSet();
        // acquire a lock on all documents
        // we have to avoid that node positions change
        // during the modification
        lockedDocumentsLocks = lockedDocuments.lock(context.getBroker(), true);
        final StoredNode[] ql = new StoredNode[nodes.getItemCount()];
        for (int i = 0; i < ql.length; i++) {
            final Item item = nodes.itemAt(i);
            if (!Type.subTypeOf(item.getType(), Type.NODE)) {
                throw new XPathException(this, "XQuery update expressions can only be applied to nodes. Got: " + item.getStringValue());
            }
            final NodeValue nv = (NodeValue) item;
            if (nv.getImplementationType() == NodeValue.IN_MEMORY_NODE) {
                throw new XPathException(this, "XQuery update expressions can not be applied to in-memory nodes.");
            }
            final Node n = nv.getNode();
            if (n.getNodeType() == Node.DOCUMENT_NODE) {
                throw new XPathException(this, "Updating the document object is not allowed.");
            }
            ql[i] = (StoredNode) n;
            final DocumentImpl doc = ql[i].getOwnerDocument();
            // prepare Trigger
            prepareTrigger(transaction, doc);
        }
        return ql;
    } finally {
        globalLock.unlock();
    }
}
Also used : Item(org.exist.xquery.value.Item) NodeValue(org.exist.xquery.value.NodeValue) StoredNode(org.exist.dom.persistent.StoredNode) Node(org.w3c.dom.Node) DefaultDocumentSet(org.exist.dom.persistent.DefaultDocumentSet) DocumentSet(org.exist.dom.persistent.DocumentSet) MutableDocumentSet(org.exist.dom.persistent.MutableDocumentSet) DocumentImpl(org.exist.dom.persistent.DocumentImpl) StoredNode(org.exist.dom.persistent.StoredNode)

Example 84 with Item

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

the class Replace method eval.

/* (non-Javadoc)
     * @see org.exist.xquery.AbstractExpression#eval(org.exist.xquery.value.Sequence, org.exist.xquery.value.Item)
     */
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();
    }
    final Sequence inSeq = select.eval(contextSequence);
    if (inSeq.isEmpty()) {
        return Sequence.EMPTY_SEQUENCE;
    }
    /* If we try and Replace a node at an invalid location,
         * trap the error in a context variable,
         * this is then accessible from xquery via. the context extension module - deliriumsky
         * TODO: This trapping could be expanded further - basically where XPathException is thrown from thiss class
         * TODO: Maybe we could provide more detailed messages in the trap, e.g. couldnt replace node `xyz` into `abc` becuase... this would be nicer for the end user of the xquery application
         */
    if (!Type.subTypeOf(inSeq.getItemType(), Type.NODE)) {
        // Indicate the failure to perform this update by adding it to the sequence in the context variable XQueryContext.XQUERY_CONTEXTVAR_XQUERY_UPDATE_ERROR
        ValueSequence prevUpdateErrors = null;
        final XPathException xpe = new XPathException(this, Messages.getMessage(Error.UPDATE_SELECT_TYPE));
        final Object ctxVarObj = context.getAttribute(XQueryContext.XQUERY_CONTEXTVAR_XQUERY_UPDATE_ERROR);
        if (ctxVarObj == null) {
            prevUpdateErrors = new ValueSequence();
        } else {
            prevUpdateErrors = (ValueSequence) XPathUtil.javaObjectToXPath(ctxVarObj, context);
        }
        prevUpdateErrors.add(new StringValue(xpe.getMessage()));
        context.setAttribute(XQueryContext.XQUERY_CONTEXTVAR_XQUERY_UPDATE_ERROR, prevUpdateErrors);
        if (!inSeq.isEmpty()) {
            // TODO: should we trap this instead of throwing an exception - deliriumsky?
            throw xpe;
        }
    }
    // END trap Replace failure
    Sequence contentSeq = value.eval(contextSequence);
    if (contentSeq.isEmpty()) {
        throw new XPathException(this, Messages.getMessage(Error.UPDATE_EMPTY_CONTENT));
    }
    context.pushInScopeNamespaces();
    contentSeq = deepCopy(contentSeq);
    // start a transaction
    try (final Txn transaction = getTransaction()) {
        final StoredNode[] ql = selectAndLock(transaction, inSeq);
        final NotificationService notifier = context.getBroker().getBrokerPool().getNotificationService();
        Item temp;
        TextImpl text;
        AttrImpl attribute;
        ElementImpl parent;
        for (final StoredNode node : ql) {
            final DocumentImpl doc = node.getOwnerDocument();
            if (!doc.getPermissions().validate(context.getSubject(), Permission.WRITE)) {
                throw new PermissionDeniedException("User '" + context.getSubject().getName() + "' does not have permission to write to the document '" + doc.getDocumentURI() + "'!");
            }
            // update the document
            parent = (ElementImpl) node.getParentStoredNode();
            if (parent == null) {
                throw new XPathException(this, "The root element of a document can not be replaced with 'update replace'. " + "Please consider removing the document or use 'update value' to just replace the children of the root.");
            }
            switch(node.getNodeType()) {
                case Node.ELEMENT_NODE:
                    temp = contentSeq.itemAt(0);
                    if (!Type.subTypeOf(temp.getType(), Type.NODE)) {
                        throw new XPathException(this, Messages.getMessage(Error.UPDATE_REPLACE_ELEM_TYPE, Type.getTypeName(temp.getType())));
                    }
                    parent.replaceChild(transaction, ((NodeValue) temp).getNode(), node);
                    break;
                case Node.TEXT_NODE:
                    text = new TextImpl(contentSeq.getStringValue());
                    text.setOwnerDocument(doc);
                    parent.updateChild(transaction, node, text);
                    break;
                case Node.ATTRIBUTE_NODE:
                    final AttrImpl attr = (AttrImpl) node;
                    attribute = new AttrImpl(attr.getQName(), contentSeq.getStringValue(), context.getBroker().getBrokerPool().getSymbols());
                    attribute.setOwnerDocument(doc);
                    parent.updateChild(transaction, node, attribute);
                    break;
                default:
                    throw new EXistException("unsupported node-type");
            }
            doc.setLastModified(System.currentTimeMillis());
            modifiedDocuments.add(doc);
            context.getBroker().storeXMLResource(transaction, doc);
            notifier.notifyUpdate(doc, UpdateListener.UPDATE);
        }
        finishTriggers(transaction);
        // commit the transaction
        transaction.commit();
    } catch (final LockException | PermissionDeniedException | EXistException | TriggerException e) {
        throw new XPathException(this, e.getMessage(), e);
    } finally {
        unlockDocuments();
        context.popInScopeNamespaces();
    }
    if (context.getProfiler().isEnabled()) {
        context.getProfiler().end(this, "", Sequence.EMPTY_SEQUENCE);
    }
    return Sequence.EMPTY_SEQUENCE;
}
Also used : XPathException(org.exist.xquery.XPathException) NotificationService(org.exist.storage.NotificationService) ValueSequence(org.exist.xquery.value.ValueSequence) Sequence(org.exist.xquery.value.Sequence) Txn(org.exist.storage.txn.Txn) AttrImpl(org.exist.dom.persistent.AttrImpl) EXistException(org.exist.EXistException) DocumentImpl(org.exist.dom.persistent.DocumentImpl) TextImpl(org.exist.dom.persistent.TextImpl) Item(org.exist.xquery.value.Item) ElementImpl(org.exist.dom.persistent.ElementImpl) LockException(org.exist.util.LockException) ValueSequence(org.exist.xquery.value.ValueSequence) PermissionDeniedException(org.exist.security.PermissionDeniedException) StringValue(org.exist.xquery.value.StringValue) TriggerException(org.exist.collections.triggers.TriggerException) StoredNode(org.exist.dom.persistent.StoredNode)

Example 85 with Item

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

the class Shared method getStreamSource.

/**
 *  Get stream source for specified resource, containing InputStream and
 * location. Used by @see Jaxv.
 * @param s The sequence
 * @param context xquery context
 * @return Streamsources
 * @throws XPathException An error occurred.
 * @throws IOException An I/O error occurred.
 */
public static StreamSource[] getStreamSource(Sequence s, XQueryContext context) throws XPathException, IOException {
    final ArrayList<StreamSource> sources = new ArrayList<>();
    final SequenceIterator i = s.iterate();
    while (i.hasNext()) {
        final Item next = i.nextItem();
        final StreamSource streamsource = getStreamSource(next, context);
        sources.add(streamsource);
    }
    StreamSource[] returnSources = new StreamSource[sources.size()];
    returnSources = sources.toArray(returnSources);
    return returnSources;
}
Also used : Item(org.exist.xquery.value.Item) ValidationReportItem(org.exist.validation.ValidationReportItem) SequenceIterator(org.exist.xquery.value.SequenceIterator) StreamSource(javax.xml.transform.stream.StreamSource) ArrayList(java.util.ArrayList)

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