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;
}
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;
}
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);
}
}
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;
}
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);
}
}
Aggregations