Search in sources :

Example 86 with StringValue

use of org.exist.xquery.value.StringValue 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 87 with StringValue

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

the class XMLDBLoadFromPattern method evalWithCollection.

@Override
protected Sequence evalWithCollection(Collection collection, Sequence[] args, Sequence contextSequence) throws XPathException {
    final Path baseDir = Paths.get(args[1].getStringValue()).normalize();
    logger.debug("Loading files from directory: {}", baseDir.toAbsolutePath().toString());
    final Sequence patternsSeq = args[2];
    final int patternsLen = patternsSeq.getItemCount();
    final String[] includes = new String[patternsLen];
    for (int i = 0; i < patternsLen; i++) {
        includes[i] = patternsSeq.itemAt(0).getStringValue();
    }
    // determine resource type - xml or binary?
    MimeType mimeTypeFromArgs = null;
    if (getSignature().getArgumentCount() > 3 && args[3].hasOne()) {
        final String mimeTypeParam = args[3].getStringValue();
        mimeTypeFromArgs = MimeTable.getInstance().getContentType(mimeTypeParam);
        if (mimeTypeFromArgs == null) {
            throw new XPathException(this, "Unknown mime type specified: " + mimeTypeParam);
        }
    }
    // keep the directory structure?
    boolean keepDirStructure = false;
    if (getSignature().getArgumentCount() >= 5) {
        keepDirStructure = args[4].effectiveBooleanValue();
    }
    final String[] excludes;
    if (getSignature().getArgumentCount() == 6) {
        final Sequence excludesSeq = args[5];
        final int excludesLen = excludesSeq.getItemCount();
        excludes = new String[excludesLen];
        for (int i = 0; i < excludesLen; i++) {
            excludes[i] = excludesSeq.itemAt(i).getStringValue();
        }
    } else {
        excludes = null;
    }
    final ValueSequence stored = new ValueSequence();
    // scan for files
    final DirectoryScanner directoryScanner = new DirectoryScanner();
    directoryScanner.setIncludes(includes);
    directoryScanner.setExcludes(excludes);
    directoryScanner.setBasedir(baseDir.toFile());
    directoryScanner.setCaseSensitive(true);
    directoryScanner.scan();
    Collection col = collection;
    String relDir;
    String prevDir = null;
    // store according to each pattern
    for (final String includedFile : directoryScanner.getIncludedFiles()) {
        final Path file = baseDir.resolve(includedFile);
        try {
            if (logger.isDebugEnabled()) {
                logger.debug(file.toAbsolutePath().toString());
            }
            String relPath = file.toString().substring(baseDir.toString().length());
            final int p = relPath.lastIndexOf(java.io.File.separatorChar);
            if (p >= 0) {
                relDir = relPath.substring(0, p);
                relDir = relDir.replace(java.io.File.separatorChar, '/');
            } else {
                relDir = relPath;
            }
            if (keepDirStructure && (prevDir == null || (!relDir.equals(prevDir)))) {
                col = createCollectionPath(collection, relDir);
                prevDir = relDir;
            }
            MimeType mimeType = mimeTypeFromArgs;
            if (mimeType == null) {
                mimeType = MimeTable.getInstance().getContentTypeFor(FileUtils.fileName(file));
                if (mimeType == null) {
                    mimeType = MimeType.BINARY_TYPE;
                }
            }
            // TODO  : these probably need to be encoded and checked for right mime type
            final Resource resource = col.createResource(FileUtils.fileName(file), mimeType.getXMLDBType());
            resource.setContent(file.toFile());
            ((EXistResource) resource).setMimeType(mimeType.getName());
            col.storeResource(resource);
            // TODO : use dedicated function in XmldbURI
            stored.add(new StringValue(col.getName() + "/" + resource.getId()));
        } catch (final XMLDBException e) {
            logger.error("Could not store file {}: {}", file.toAbsolutePath(), e.getMessage());
        }
    }
    return stored;
}
Also used : Path(java.nio.file.Path) XPathException(org.exist.xquery.XPathException) EXistResource(org.exist.xmldb.EXistResource) Resource(org.xmldb.api.base.Resource) XMLDBException(org.xmldb.api.base.XMLDBException) ValueSequence(org.exist.xquery.value.ValueSequence) Sequence(org.exist.xquery.value.Sequence) MimeType(org.exist.util.MimeType) EXistResource(org.exist.xmldb.EXistResource) DirectoryScanner(org.apache.tools.ant.DirectoryScanner) ValueSequence(org.exist.xquery.value.ValueSequence) Collection(org.xmldb.api.base.Collection) StringValue(org.exist.xquery.value.StringValue)

Example 88 with StringValue

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

the class RegexUtil method translateRegexp.

/**
 * Translates the Regular Expression from XPath3 syntax to Java regex
 * syntax.
 *
 * @param context the context expression - used for error reporting
 * @param pattern a String containing a regular expression in the syntax of XPath Functions and Operators 3.0.
 * @param ignoreWhitespace true if whitespace is to be ignored ('x' flag)
 * @param caseBlind true if case is to be ignored ('i' flag)
 *
 * @return The Java Regular Expression
 *
 * @throws XPathException if the XQuery Regular Expression is invalid.
 */
public static String translateRegexp(final Expression context, final String pattern, final boolean ignoreWhitespace, final boolean caseBlind) throws XPathException {
    // convert pattern to Java regex syntax
    try {
        final int options = RegularExpression.XML11 | RegularExpression.XPATH30;
        int flagbits = 0;
        if (ignoreWhitespace) {
            flagbits |= Pattern.COMMENTS;
        }
        if (caseBlind) {
            flagbits |= Pattern.CASE_INSENSITIVE;
        }
        final List<RegexSyntaxException> warnings = new ArrayList<>();
        return JDK15RegexTranslator.translate(pattern, options, flagbits, warnings);
    } catch (final RegexSyntaxException e) {
        throw new XPathException(context, ErrorCodes.FORX0002, "Conversion from XPath F&O 3.0 regular expression syntax to Java regular expression syntax failed: " + e.getMessage(), new StringValue(pattern), e);
    }
}
Also used : XPathException(org.exist.xquery.XPathException) ArrayList(java.util.ArrayList) RegexSyntaxException(org.exist.thirdparty.net.sf.saxon.functions.regex.RegexSyntaxException) StringValue(org.exist.xquery.value.StringValue)

Example 89 with StringValue

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

the class Rename method eval.

@Override
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 contentSeq = value.eval(contextSequence);
    if (contentSeq.isEmpty()) {
        throw new XPathException(this, Messages.getMessage(Error.UPDATE_EMPTY_CONTENT));
    }
    final Sequence inSeq = select.eval(contextSequence);
    /* If we try and Rename 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 rename 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;
        }
    }
    if (!inSeq.isEmpty()) {
        QName newQName;
        final Item item = contentSeq.itemAt(0);
        if (item.getType() == Type.QNAME) {
            newQName = ((QNameValue) item).getQName();
        } else {
            try {
                newQName = QName.parse(context, item.getStringValue());
            } catch (final QName.IllegalQNameException iqe) {
                throw new XPathException(this, ErrorCodes.XPST0081, "No namespace defined for prefix " + item.getStringValue());
            }
        }
        // start a transaction
        try (final Txn transaction = getTransaction()) {
            final StoredNode[] ql = selectAndLock(transaction, inSeq);
            final NotificationService notifier = context.getBroker().getBrokerPool().getNotificationService();
            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() + "'!");
                }
                final NodeImpl parent = (NodeImpl) getParent(node);
                // update the document
                final NamedNode newNode;
                switch(node.getNodeType()) {
                    case Node.ELEMENT_NODE:
                        newNode = new ElementImpl((ElementImpl) node);
                        break;
                    case Node.ATTRIBUTE_NODE:
                        newNode = new AttrImpl((AttrImpl) node);
                        break;
                    default:
                        throw new XPathException(this, "unsupported node-type");
                }
                newNode.setNodeName(newQName, context.getBroker().getBrokerPool().getSymbols());
                parent.updateChild(transaction, node, newNode);
                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 PermissionDeniedException | EXistException | LockException | TriggerException e) {
            throw new XPathException(this, e.getMessage(), e);
        } finally {
            unlockDocuments();
        }
    }
    if (context.getProfiler().isEnabled()) {
        context.getProfiler().end(this, "", Sequence.EMPTY_SEQUENCE);
    }
    return Sequence.EMPTY_SEQUENCE;
}
Also used : QName(org.exist.dom.QName) NotificationService(org.exist.storage.NotificationService) ValueSequence(org.exist.xquery.value.ValueSequence) Sequence(org.exist.xquery.value.Sequence) Txn(org.exist.storage.txn.Txn) EXistException(org.exist.EXistException) Item(org.exist.xquery.value.Item) 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)

Example 90 with StringValue

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

the class XMLDBHasLock method evalWithCollection.

public Sequence evalWithCollection(Collection collection, Sequence[] args, Sequence contextSequence) throws XPathException {
    try {
        final UserManagementService ums = (UserManagementService) collection.getService("UserManagementService", "1.0");
        final Resource res = collection.getResource(new AnyURIValue(args[1].getStringValue()).toXmldbURI().toString());
        if (res != null) {
            final String lockUser = ums.hasUserLock(res);
            if (lockUser != null && isCalledAs("clear-lock")) {
                ums.unlockResource(res);
            }
            return lockUser == null ? Sequence.EMPTY_SEQUENCE : new StringValue(lockUser);
        } else {
            logger.error("Unable to locate resource {}", args[1].getStringValue());
            throw new XPathException(this, "Unable to locate resource " + args[1].getStringValue());
        }
    } catch (final XMLDBException e) {
        logger.error("Failed to retrieve user lock");
        throw new XPathException(this, "Failed to retrieve user lock", e);
    }
}
Also used : XPathException(org.exist.xquery.XPathException) AnyURIValue(org.exist.xquery.value.AnyURIValue) Resource(org.xmldb.api.base.Resource) XMLDBException(org.xmldb.api.base.XMLDBException) UserManagementService(org.exist.xmldb.UserManagementService) StringValue(org.exist.xquery.value.StringValue)

Aggregations

StringValue (org.exist.xquery.value.StringValue)96 Sequence (org.exist.xquery.value.Sequence)49 XPathException (org.exist.xquery.XPathException)40 ValueSequence (org.exist.xquery.value.ValueSequence)27 IOException (java.io.IOException)11 PermissionDeniedException (org.exist.security.PermissionDeniedException)10 Item (org.exist.xquery.value.Item)10 XQueryContext (org.exist.xquery.XQueryContext)8 Txn (org.exist.storage.txn.Txn)7 AnyURIValue (org.exist.xquery.value.AnyURIValue)7 QName (org.exist.dom.QName)6 LockException (org.exist.util.LockException)6 NodeValue (org.exist.xquery.value.NodeValue)6 Path (java.nio.file.Path)5 EXistException (org.exist.EXistException)5 TriggerException (org.exist.collections.triggers.TriggerException)5 DocumentImpl (org.exist.dom.persistent.DocumentImpl)5 StoredNode (org.exist.dom.persistent.StoredNode)5 NotificationService (org.exist.storage.NotificationService)5 MimeType (org.exist.util.MimeType)5