sourceConnection.execute(context, request);
if (request.hasError()) continue;
DateTime expTime = request.getCachePolicy() == null ? expirationTime : getCurrentTimeInUtc().plus(request.getCachePolicy().getTimeToLive(),
TimeUnit.MILLISECONDS);
// Convert the locations of the children (relative to the source) to be relative to this node
Contribution contribution = Contribution.create(source,
request.getActualLocationOfNode(),
expTime,
request.getProperties(),
request.getChildren());
contributions.add(contribution);
}
}
// Otherwise, we can do it by path and projections ...
Path path = location.getPath();
for (Projection projection : this.sourceProjections) {
final String source = projection.getSourceName();
if (sourceNames != null && !sourceNames.contains(source)) continue;
final RepositoryConnection sourceConnection = getConnection(projection);
if (sourceConnection == null) continue; // No source exists by this name
// Get the cached information ...
CachePolicy cachePolicy = sourceConnection.getDefaultCachePolicy();
if (cachePolicy == null) cachePolicy = this.defaultCachePolicy;
DateTime expirationTime = null;
if (cachePolicy != null) {
expirationTime = getCurrentTimeInUtc().plus(cachePolicy.getTimeToLive(), TimeUnit.MILLISECONDS);
}
// Get the paths-in-source where we should fetch node contributions ...
Set<Path> pathsInSource = projection.getPathsInSource(path, pathFactory);
if (pathsInSource.isEmpty()) {
// The source has no contributions, but see whether the project exists BELOW this path.
// We do this by getting the top-level repository paths of the projection, and then
// use those to figure out the children of the nodes.
Contribution contribution = null;
List<Path> topLevelPaths = projection.getTopLevelPathsInRepository(pathFactory);
Location input = new Location(path);
switch (topLevelPaths.size()) {
case 0:
break;
case 1: {
Path topLevelPath = topLevelPaths.iterator().next();
if (path.isAncestorOf(topLevelPath)) {
Location child = new Location(topLevelPath);
contribution = Contribution.createPlaceholder(source, input, expirationTime, child);
}
break;
}
default: {
// We assume that the top-level paths do not overlap ...
List<Location> children = new ArrayList<Location>(topLevelPaths.size());
for (Path topLevelPath : topLevelPaths) {
if (path.isAncestorOf(topLevelPath)) {
children.add(new Location(topLevelPath));
}
}
if (children.size() > 0) {
contribution = Contribution.createPlaceholder(source, input, expirationTime, children);
}
}
}
if (contribution == null) contribution = Contribution.create(source, expirationTime);
contributions.add(contribution);
} else {
// There is at least one (real) contribution ...
// Get the contributions ...
final int numPaths = pathsInSource.size();
if (numPaths == 1) {
Path pathInSource = pathsInSource.iterator().next();
ReadNodeRequest fromSource = new ReadNodeRequest(new Location(pathInSource));
sourceConnection.execute(getExecutionContext(), fromSource);
if (!fromSource.hasError()) {
Collection<Property> properties = fromSource.getProperties();
List<Location> children = fromSource.getChildren();
DateTime expTime = fromSource.getCachePolicy() == null ? expirationTime : getCurrentTimeInUtc().plus(fromSource.getCachePolicy().getTimeToLive(),
TimeUnit.MILLISECONDS);
Location actualLocation = fromSource.getActualLocationOfNode();
Contribution contribution = Contribution.create(source, actualLocation, expTime, properties, children);
contributions.add(contribution);
}
} else {
List<ReadNodeRequest> fromSourceCommands = new ArrayList<ReadNodeRequest>(numPaths);
for (Path pathInSource : pathsInSource) {
fromSourceCommands.add(new ReadNodeRequest(new Location(pathInSource)));
}
Request request = CompositeRequest.with(fromSourceCommands);
sourceConnection.execute(context, request);
for (ReadNodeRequest fromSource : fromSourceCommands) {
if (fromSource.hasError()) continue;
DateTime expTime = fromSource.getCachePolicy() == null ? expirationTime : getCurrentTimeInUtc().plus(fromSource.getCachePolicy().getTimeToLive(),
TimeUnit.MILLISECONDS);
List<Location> children = fromSource.getChildren();
Contribution contribution = Contribution.create(source,
fromSource.getActualLocationOfNode(),
expTime,
fromSource.getProperties(),
children);
contributions.add(contribution);