@Override
public void process( ReadNodeRequest request ) {
Path federatedPath = request.at().getPath();
Map<Name, Property> properties = request.getPropertiesByName();
Map<Name, Integer> childSnsIndexes = new HashMap<Name, Integer>();
ProjectedRequest projectedRequest = federatedRequest.getFirstProjectedRequest();
assert projectedRequest != null;
request.setCachePolicy(getDefaultCachePolicy());
Location actualLocation = request.at();
int numMerged = 0;
while (projectedRequest != null) {
Request sourceRequest = projectedRequest.getRequest();
if (sourceRequest.hasError()) {
projectedRequest = projectedRequest.next();
continue;
}
if (sourceRequest.isCancelled()) {
request.cancel();
return;
}
Projection projection = projectedRequest.getProjection();
if (sourceRequest instanceof VerifyNodeExistsRequest) {
// We needed to verify the existance of a child node ...
VerifyNodeExistsRequest verify = (VerifyNodeExistsRequest)sourceRequest;
Location childInSource = verify.getActualLocationOfNode();
Location childInRepos = getChildLocationWithCorrectSnsIndex(childInSource,
federatedPath,
childSnsIndexes,
projection);
request.addChild(childInRepos);
if (federatedPath == null) federatedPath = childInRepos.getPath().getParent();
} else {
ReadNodeRequest readFromSource = (ReadNodeRequest)sourceRequest;
Location sourceLocation = readFromSource.getActualLocationOfNode();
if (sourceLocation.hasIdProperties()) {
// Accumulate the identification properties ...
for (Property propertyInSource : sourceLocation.getIdProperties()) {
Name name = propertyInSource.getName();
Property existing = actualLocation.getIdProperty(name);
if (existing != null) {
// Merge the property values ...
propertyInSource = merge(existing, propertyInSource, propertyFactory, true);
}
actualLocation = actualLocation.with(propertyInSource);
}
}
// Make sure we have an actual location ...
actualLocation = determineActualLocation(actualLocation, sourceLocation, projection);
if (federatedPath == null) federatedPath = actualLocation.getPath();
// Add all the children from the source ...
for (Location childInSource : readFromSource.getChildren()) {
request.addChild(getChildLocationWithCorrectSnsIndex(childInSource,
federatedPath,
childSnsIndexes,
projection));
}
// Add all the properties ...
for (Property propertyInSource : readFromSource.getProperties()) {
Name name = propertyInSource.getName();
Property existing = properties.get(name);
if (existing != null) {
// Merge the property values ...
propertyInSource = merge(existing, propertyInSource, propertyFactory, true);
}
properties.put(name, propertyInSource);
}
setCacheableInfo(request, readFromSource.getCachePolicy());
}
projectedRequest = projectedRequest.next();
++numMerged;
}
if (numMerged == 0) {
// No source requests had results ...
setPathNotFound(request, request.at(), federatedRequest.getFirstProjectedRequest());