* @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.ReadNextBlockOfChildrenRequest)
*/
@Override
public void process( ReadNextBlockOfChildrenRequest request ) {
logger.trace(request.toString());
Location actualLocation = null;
final Location previousSibling = request.startingAfter();
final int count = request.count();
try {
// Find the workspace ...
WorkspaceEntity workspace = getExistingWorkspace(request.inWorkspace(), request);
if (workspace == null) return;
Long workspaceId = workspace.getId();
assert workspaceId != null;
ActualLocation actualSibling = getActualLocation(workspaceId, previousSibling);
actualLocation = actualSibling.location;
if (!actualLocation.getPath().isRoot()) {
// First look in the cache for the children of the parent ...
Path parentPath = actualSibling.location.getPath().getParent();
assert parentPath != null;
LinkedList<Location> cachedChildren = cache.getAllChildren(workspaceId, parentPath);
if (cachedChildren != null) {
// The cache has all of the children for the node.
// First find the location of the previous sibling ...
boolean accumulate = false;
int counter = 0;
for (Location child : cachedChildren) {
if (accumulate) {
// We're accumulating children ...
request.addChild(child);
++counter;
if (counter <= count) continue;
break;
}
// Haven't found the previous sibling yet ...
if (child.isSame(previousSibling)) {
accumulate = true;
}
}
} else {
// The children were not found in the cache, so we have to search the database.
// We don't know the UUID of the parent, so find the previous sibling and
// then get the starting index and the parent UUID ...
ChildEntity previousChild = actualSibling.childEntity;
if (previousChild == null) {
Query query = entities.createNamedQuery("ChildEntity.findByChildUuid");
query.setParameter("workspaceId", workspaceId);
query.setParameter("childUuidString", actualSibling.uuid);
previousChild = (ChildEntity)query.getSingleResult();
}
int startingIndex = previousChild.getIndexInParent() + 1;
String parentUuid = previousChild.getId().getParentUuidString();
// Now search the database for the children ...
Query query = entities.createNamedQuery("ChildEntity.findRangeUnderParent");
query.setParameter("workspaceId", workspaceId);
query.setParameter("parentUuidString", parentUuid);
query.setParameter("firstIndex", startingIndex);
query.setParameter("afterIndex", startingIndex + request.count());
@SuppressWarnings( "unchecked" )
List<ChildEntity> children = query.getResultList();
LinkedList<Location> allChildren = null;
if (startingIndex == 1 && children.size() < request.count()) {
// The previous child was the first sibling, and we got fewer children than
// the max count. This means we know all of the children, so accumulate the locations
// so they can be cached ...
allChildren = new LinkedList<Location>();
allChildren.add(actualSibling.location);
}
for (ChildEntity child : children) {
String namespaceUri = child.getChildNamespace().getUri();
String localName = child.getChildName();
Name childName = nameFactory.create(namespaceUri, localName);
int sns = child.getSameNameSiblingIndex();
Path childPath = pathFactory.create(parentPath, childName, sns);
String childUuidString = child.getId().getChildUuidString();
Location childLocation = Location.create(childPath, UUID.fromString(childUuidString));
request.addChild(childLocation);
if (allChildren != null) {
// We're going to cache the results, so add this child ...
allChildren.add(childLocation);
}