use of org.exist.xquery.value.Item in project exist by eXist-db.
the class Shared method getStreamSource.
public static StreamSource getStreamSource(Item item, XQueryContext context) throws XPathException, IOException {
final StreamSource streamSource = new StreamSource();
if (item.getType() == Type.JAVA_OBJECT) {
LOG.debug("Streaming Java object");
final Object obj = ((JavaObjectValue) item).getObject();
if (!(obj instanceof File)) {
throw new XPathException("Passed java object should be a File");
}
final File inputFile = (File) obj;
final InputStream is = new FileInputStream(inputFile);
streamSource.setInputStream(is);
streamSource.setSystemId(inputFile.toURI().toURL().toString());
} else if (item.getType() == Type.ANY_URI) {
LOG.debug("Streaming xs:anyURI");
// anyURI provided
String url = item.getStringValue();
// Fix URL
if (url.startsWith("/")) {
url = "xmldb:exist://" + url;
}
final InputStream is = new URL(url).openStream();
streamSource.setInputStream(is);
streamSource.setSystemId(url);
} else if (item.getType() == Type.ELEMENT || item.getType() == Type.DOCUMENT) {
LOG.debug("Streaming element or document node");
if (item instanceof NodeProxy) {
final NodeProxy np = (NodeProxy) item;
final String url = "xmldb:exist://" + np.getOwnerDocument().getBaseURI();
LOG.debug("Document detected, adding URL {}", url);
streamSource.setSystemId(url);
}
// Node provided
final DBBroker broker = context.getBroker();
final ConsumerE<ConsumerE<Serializer, IOException>, IOException> withSerializerFn = fn -> {
final Serializer serializer = broker.borrowSerializer();
try {
fn.accept(serializer);
} finally {
broker.returnSerializer(serializer);
}
};
final NodeValue node = (NodeValue) item;
final InputStream is = new NodeInputStream(context.getBroker().getBrokerPool(), withSerializerFn, node);
streamSource.setInputStream(is);
} else if (item.getType() == Type.BASE64_BINARY || item.getType() == Type.HEX_BINARY) {
LOG.debug("Streaming base64 binary");
final BinaryValue binary = (BinaryValue) item;
final byte[] data = binary.toJavaObject(byte[].class);
final InputStream is = new UnsynchronizedByteArrayInputStream(data);
streamSource.setInputStream(is);
if (item instanceof Base64BinaryDocument) {
final Base64BinaryDocument b64doc = (Base64BinaryDocument) item;
final String url = "xmldb:exist://" + b64doc.getUrl();
LOG.debug("Base64BinaryDocument detected, adding URL {}", url);
streamSource.setSystemId(url);
}
} else {
LOG.error("Wrong item type {}", Type.getTypeName(item.getType()));
throw new XPathException("wrong item type " + Type.getTypeName(item.getType()));
}
return streamSource;
}
use of org.exist.xquery.value.Item 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.Item in project exist by eXist-db.
the class EXistSequence method next.
@Override
public Sequence next() throws ToolsException {
try {
final Item item = sequenceIterator.nextItem();
final org.exist.xquery.value.Sequence singleton = (org.exist.xquery.value.Sequence) item;
return new EXistSequence(singleton, context);
} catch (final XPathException xpe) {
throw new ToolsException(xpe.getMessage(), xpe);
}
}
Aggregations