use of org.exist.xquery.value.SequenceIterator in project exist by eXist-db.
the class IPRangeRealm method authenticate.
@Override
public Subject authenticate(final String ipAddress, final Object credentials) throws AuthenticationException {
// Elevaste to system privileges
try (final DBBroker broker = getSecurityManager().database().get(Optional.of(getSecurityManager().getSystemSubject()))) {
// Convert IP address
final long ipToTest = ipToLong(InetAddress.getByName(ipAddress));
// Get xquery service
final XQuery queryService = broker.getBrokerPool().getXQueryService();
if (queryService == null) {
LOG.error("IPRange broker unable to retrieve XQueryService");
return null;
}
// Construct XQuery
final String query = "collection('/db/system/security/iprange/accounts')/account/" + "iprange[" + ipToTest + " ge number(start) and " + ipToTest + " le number(end)]/../name";
final XQueryContext context = new XQueryContext(broker.getBrokerPool());
final CompiledXQuery compiled = queryService.compile(context, query);
final Properties outputProperties = new Properties();
// Execute xQuery
final Sequence result = queryService.execute(broker, compiled, null, outputProperties);
final SequenceIterator i = result.iterate();
// Get FIRST username when present
final String username = i.hasNext() ? i.nextItem().getStringValue() : "";
if (i.hasNext()) {
LOG.warn("IP address {} matched multiple ipranges. Using first result only.", ipAddress);
}
if (!username.isEmpty()) {
final Account account = getSecurityManager().getAccount(username);
if (account != null) {
LOG.info("IPRangeRealm trying {}", account.getName());
return new SubjectAccreditedImpl((AbstractAccount) account, ipAddress);
} else {
LOG.info("IPRangeRealm couldn't resolve account for {}", username);
}
} else {
LOG.info("IPRangeRealm xquery found no matches");
}
return null;
} catch (final EXistException | UnknownHostException | XPathException | PermissionDeniedException e) {
throw new AuthenticationException(AuthenticationException.UNNOWN_EXCEPTION, e.getMessage());
}
}
use of org.exist.xquery.value.SequenceIterator in project exist by eXist-db.
the class Modification method deepCopy.
protected Sequence deepCopy(Sequence inSeq) throws XPathException {
context.pushDocumentContext();
final MemTreeBuilder builder = context.getDocumentBuilder();
final DocumentBuilderReceiver receiver = new DocumentBuilderReceiver(builder);
final Serializer serializer = context.getBroker().borrowSerializer();
serializer.setReceiver(receiver);
try {
final Sequence out = new ValueSequence();
for (final SequenceIterator i = inSeq.iterate(); i.hasNext(); ) {
Item item = i.nextItem();
if (item.getType() == Type.DOCUMENT) {
if (((NodeValue) item).getImplementationType() == NodeValue.PERSISTENT_NODE) {
final NodeHandle root = (NodeHandle) ((NodeProxy) item).getOwnerDocument().getDocumentElement();
item = new NodeProxy(root);
} else {
item = (Item) ((Document) item).getDocumentElement();
}
}
if (Type.subTypeOf(item.getType(), Type.NODE)) {
if (((NodeValue) item).getImplementationType() == NodeValue.PERSISTENT_NODE) {
final int last = builder.getDocument().getLastNode();
final NodeProxy p = (NodeProxy) item;
serializer.toReceiver(p, false, false);
if (p.getNodeType() == Node.ATTRIBUTE_NODE) {
item = builder.getDocument().getLastAttr();
} else {
item = builder.getDocument().getNode(last + 1);
}
} else {
((org.exist.dom.memtree.NodeImpl) item).deepCopy();
}
}
out.add(item);
}
return out;
} catch (final SAXException | DOMException e) {
throw new XPathException(this, e.getMessage(), e);
} finally {
context.getBroker().returnSerializer(serializer);
context.popDocumentContext();
}
}
use of org.exist.xquery.value.SequenceIterator in project exist by eXist-db.
the class Update 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 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 Update 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 update 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()) {
context.pushInScopeNamespaces();
// start a transaction
try (final Txn transaction = getTransaction()) {
final NotificationService notifier = context.getBroker().getBrokerPool().getNotificationService();
final StoredNode[] ql = selectAndLock(transaction, inSeq);
for (final StoredNode node : ql) {
final DocumentImpl doc = node.getOwnerDocument();
if (!doc.getPermissions().validate(context.getSubject(), Permission.WRITE)) {
throw new XPathException(this, "User '" + context.getSubject().getName() + "' does not have permission to write to the document '" + doc.getDocumentURI() + "'!");
}
// update the document
switch(node.getNodeType()) {
case Node.ELEMENT_NODE:
final NodeListImpl content = new NodeListImpl();
for (final SequenceIterator j = contentSeq.iterate(); j.hasNext(); ) {
final Item next = j.nextItem();
if (Type.subTypeOf(next.getType(), Type.NODE)) {
content.add(((NodeValue) next).getNode());
} else {
final TextImpl text = new TextImpl(next.getStringValue());
content.add(text);
}
}
((ElementImpl) node).update(transaction, content);
break;
case Node.TEXT_NODE:
final ElementImpl textParent = (ElementImpl) node.getParentNode();
final TextImpl text = new TextImpl(contentSeq.getStringValue());
text.setOwnerDocument(doc);
textParent.updateChild(transaction, node, text);
break;
case Node.ATTRIBUTE_NODE:
final ElementImpl attrParent = (ElementImpl) ((Attr) node).getOwnerElement();
if (attrParent == null) {
LOG.warn("parent node not found for {}", node.getNodeId());
break;
}
final AttrImpl attr = (AttrImpl) node;
final AttrImpl attribute = new AttrImpl(attr.getQName(), contentSeq.getStringValue(), context.getBroker().getBrokerPool().getSymbols());
attribute.setOwnerDocument(doc);
attrParent.updateChild(transaction, node, attribute);
break;
default:
throw new XPathException(this, "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 | 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.SequenceIterator in project exist by eXist-db.
the class AttributeConstructor method evalEnclosedExpr.
private void evalEnclosedExpr(Sequence seq, StringBuilder buf) throws XPathException {
Item item;
AtomicValue atomic;
for (final SequenceIterator i = Atomize.atomize(seq).iterate(); i.hasNext(); ) {
item = i.nextItem();
buf.append(item.getStringValue());
if (i.hasNext()) {
buf.append(' ');
}
}
}
use of org.exist.xquery.value.SequenceIterator in project exist by eXist-db.
the class DynamicPIConstructor 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();
}
try {
final MemTreeBuilder builder = context.getDocumentBuilder();
context.proceed(this, builder);
final Sequence nameSeq = name.eval(contextSequence, contextItem);
// TODO : get rid of getLength()
if (!nameSeq.hasOne()) {
throw new XPathException(this, ErrorCodes.XPTY0004, "The name expression should evaluate to a single value");
}
final Item nameItem = nameSeq.itemAt(0);
if (!(nameItem.getType() == Type.STRING || nameItem.getType() == Type.NCNAME || nameItem.getType() == Type.UNTYPED_ATOMIC)) {
throw new XPathException(this, ErrorCodes.XPTY0004, "The name expression should evaluate to a " + Type.getTypeName(Type.STRING) + " or a " + Type.getTypeName(Type.NCNAME) + " or a " + Type.getTypeName(Type.UNTYPED_ATOMIC) + ". Got: " + Type.getTypeName(nameItem.getType()));
}
if (!XMLNames.isNCName(nameSeq.getStringValue())) {
throw new XPathException(this, ErrorCodes.XQDY0041, nameSeq.getStringValue() + "' is not a valid processing instruction name", nameSeq);
}
if (nameSeq.getStringValue().equalsIgnoreCase("XML")) {
throw new XPathException(this, ErrorCodes.XQDY0064, nameSeq.getStringValue() + "' is not a valid processing instruction name", nameSeq);
}
String contentString;
final Sequence contentSeq = content.eval(contextSequence, contextItem);
if (contentSeq.isEmpty()) {
contentString = "";
} else {
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.getStringValue());
}
while (buf.length() > 0 && Character.isWhitespace(buf.charAt(0))) buf.deleteCharAt(0);
contentString = buf.toString();
}
if (contentString.contains("?>")) {
throw new XPathException(this, ErrorCodes.XQDY0026, contentString + "' is not a valid processing intruction content", contentSeq);
}
final int nodeNo = builder.processingInstruction(nameSeq.getStringValue(), contentString);
final Sequence result = ((DocumentImpl) builder.getDocument()).getNode(nodeNo);
if (context.getProfiler().isEnabled()) {
context.getProfiler().end(this, "", result);
}
return result;
} finally {
if (newDocumentContext) {
context.popDocumentContext();
}
}
}
Aggregations