throw new XPathException("Invalid argument to fn:doc function: empty string is not allowed here.");
throw new XPathException(getASTNode(), "Invalid argument to fn:doc function: empty string is not allowed here.");
	public Sequence eval(Sequence contextSequence, Item contextItem)		throws XPathException {		Sequence arg =			getArgument(0).eval(contextSequence, contextItem);		if(arg.getLength() == 0)			return Sequence.EMPTY_SEQUENCE;		String path = arg.itemAt(0).getStringValue();		if (path.length() == 0)			throw new XPathException("Invalid argument to fn:doc function: empty string is not allowed here.");		if (path.charAt(0) != '/')			path = context.getBaseURI() + '/' + path;		Lock dlock = null;		if(path.equals(cachedPath) && cachedNode != null) {		    dlock = cachedNode.getDocument().getUpdateLock();		    try {		        // wait for pending updates		        dlock.acquire(Lock.READ_LOCK);		        return cachedNode;		    } catch (LockException e) {		        throw new XPathException(getASTNode(), "Failed to acquire lock on document " + path);            } finally {		        dlock.release(Lock.READ_LOCK);		    }		}				try {		    DocumentImpl doc = (DocumentImpl) context.getBroker().getDocument(path);		    if(doc == null)		        return Sequence.EMPTY_SEQUENCE;		    if(!doc.getPermissions().validate(context.getUser(), Permission.READ))			    throw new XPathException(getASTNode(), "Insufficient privileges to read resource " + path);		    // wait for currently pending updates		    dlock = doc.getUpdateLock();		    dlock.acquire(Lock.READ_LOCK);			cachedPath = path;			cachedNode = new NodeProxy(doc, -1, Node.DOCUMENT_NODE);			return cachedNode;		} catch (PermissionDeniedException e) {			throw new XPathException(				"Permission denied: unable to load document " + path);		} catch (LockException e) {		    throw new XPathException(getASTNode(), "Failed to acquire read lock on document " + path);        } finally {		    if(dlock != null) dlock.release(Lock.READ_LOCK);		}	}