boolean loadIfRequired )
throws PathNotFoundException, AccessControlException {
Node<Payload, PropertyPayload> node = startingPoint;
if (!relativePath.isRoot()) {
// Find the absolute path, which ensures that the relative path is well-formed ...
Path absolutePath = relativePath.resolveAgainst(startingPoint.getPath());
// Verify that the user has the appropriate privileges to read these nodes...
authorizer.checkPermissions(absolutePath, Action.READ);
// Walk down the path ...
Iterator<Path.Segment> iter = relativePath.iterator();
while (iter.hasNext()) {
Path.Segment segment = iter.next();
try {
if (segment.isSelfReference()) continue;
if (segment.isParentReference()) {
node = node.getParent();
assert node != null; // since the relative path is well-formed
continue;
}
if (node.isLoaded()) {
// The child is the next node we need to process ...
node = node.getChild(segment);
} else {
if (!loadIfRequired) return null;
// The node has not yet been loaded into the cache, so read this node
// from the store as well as all nodes along the path to the node we're really
// interested in. We'll do this in a batch, so first create this batch ...
Graph.Batch batch = store.batch();
// Figure out which nodes along the path need to be loaded from the store ...
Path firstPath = node.getPath();
batch.read(firstPath);
// Now add the path to the child (which is no longer on the iterator) ...
Path nextPath = pathFactory.create(firstPath, segment);
if (!iter.hasNext() && loadDepth > 1) {
batch.readSubgraphOfDepth(loadDepth).at(nextPath);
} else {
batch.read(nextPath);
}
// Now add any remaining paths that are still on the iterator ...
while (iter.hasNext()) {
nextPath = pathFactory.create(nextPath, iter.next());
if (!iter.hasNext() && loadDepth > 1) {
batch.readSubgraphOfDepth(loadDepth).at(nextPath);
} else {
batch.read(nextPath);
}
}
// Load all of the nodes (we should be reading at least 2 nodes) ...
Results batchResults = batch.execute();
// Add the children and properties in the lowest cached node ...
Path previousPath = null;
Node<Payload, PropertyPayload> topNode = node;
Node<Payload, PropertyPayload> previousNode = node;
for (org.jboss.dna.graph.Node persistentNode : batchResults) {
Location location = persistentNode.getLocation();
Path path = location.getPath();
if (path.isRoot()) {
previousNode = root;
root.location = location;
} else {
if (path.getParent().equals(previousPath)) {
previousNode = previousNode.getChild(path.getLastSegment());
} else {
Path subgraphPath = path.relativeTo(topNode.getPath());
previousNode = findNodeRelativeTo(topNode, subgraphPath);
}
// Set the node that we're looking for ...
if (path.getLastSegment().equals(relativePath.getLastSegment()) && path.equals(absolutePath)) {
node = previousNode;