* @see org.exist.xquery.Expression#eval(org.exist.dom.DocumentSet, org.exist.xquery.value.Sequence, org.exist.xquery.value.Item)
*/
public Sequence eval(Sequence contextSequence, Item contextItem)
throws XPathException {
DocumentSet docs = null;
Sequence result = null;
// check if the loaded documents should remain locked
final boolean lockOnLoad = context.lockDocumentsOnLoad();
boolean cacheIsValid = false;
if (getArgumentCount() == 0) {
// TODO: disabled cache for now as it may cause concurrency issues
// better use compile-time inspection and maybe a pragma to mark those
// sections in the query that can be safely cached
// if(cached != null) {
// result = cached;
// docs = cachedDocs;
// } else {
MutableDocumentSet mdocs = new DefaultDocumentSet();
try {
context.getBroker().getAllXMLResources(mdocs);
} catch(final PermissionDeniedException pde) {
LOG.error(pde.getMessage(), pde);
throw new XPathException(this, pde);
}
docs = mdocs;
// }
} else {
List<String> args = getParameterValues(contextSequence, contextItem);
if(cachedArgs != null)
{cacheIsValid = compareArguments(cachedArgs, args);}
if(cacheIsValid) {
result = cached;
docs = cachedDocs;
} else {
MutableDocumentSet mdocs = new DefaultDocumentSet();
for(int i = 0; i < args.size(); i++) {
try {
final String next = (String)args.get(i);
XmldbURI nextUri = new AnyURIValue(next).toXmldbURI();
if(nextUri.getCollectionPath().length() == 0) {
throw new XPathException(this, "Invalid argument to " + XMLDBModule.PREFIX + ":document() function: empty string is not allowed here.");
}
if(nextUri.numSegments()==1) {
nextUri = context.getBaseURI().toXmldbURI().resolveCollectionPath(nextUri);
}
final DocumentImpl doc = context.getBroker().getResource(nextUri, Permission.READ);
if(doc == null) {
if (context.isRaiseErrorOnFailedRetrieval()) {
throw new XPathException(this, ErrorCodes.FODC0002, "can not access '" + nextUri + "'");
}
}else {
mdocs.add(doc);
}
} catch (final XPathException e) { //From AnyURIValue constructor
e.setLocation(line, column);
logger.error("From AnyURIValue constructor:", e);
throw e;
} catch (final PermissionDeniedException e) {
logger.error("Permission denied", e);
throw new XPathException(this, "Permission denied: unable to load document " + (String) args.get(i));
}
}
docs = mdocs;
cachedArgs = args;
}
}
try {
if(!cacheIsValid)
// wait for pending updates
{docs.lock(context.getBroker(), lockOnLoad, true);}
// wait for pending updates
if(result == null) {
result = new ExtArrayNodeSet(docs.getDocumentCount(), 1);
DocumentImpl doc;
for (final Iterator<DocumentImpl> i = docs.getDocumentIterator(); i.hasNext();) {
doc = i.next();
result.add(new NodeProxy(doc)); //, -1, Node.DOCUMENT_NODE));
if(lockOnLoad) {
context.addLockedDocument(doc);
}
}
}
} catch (final LockException e) {
logger.error("Could not acquire lock on document set", e);
throw new XPathException(this, "Could not acquire lock on document set.");
} finally {
if(!(cacheIsValid || lockOnLoad))
// release all locks
{docs.unlock(lockOnLoad);}
}
cached = result;
cachedDocs = docs;
registerUpdateListener();