in taverna-reference-impl/src/main/java/org/apache/taverna/reference/impl/ReferenceSetAugmentorImpl.java [198:299]
public final Set<ExternalReferenceSPI> augmentReferenceSet(
ReferenceSet references,
Set<Class<ExternalReferenceSPI>> targetReferenceTypes,
ReferenceContext context) throws ReferenceSetAugmentationException {
synchronized (this) {
if (!cacheValid)
update();
}
// Synchronize on the reference set itself
synchronized (references) {
/*
* First check whether we actually need to modify the reference set
* at all - it's perfectly valid to call the augmentor when nothing
* actually needs to be done (ideally you wouldn't do this, but it's
* likely to happen)
*/
for (ExternalReferenceSPI er : references.getExternalReferences())
if (targetReferenceTypes.contains(er.getClass()))
return new HashSet<>();
// Need to perform augmentation if we reach this point
List<TranslationPath> candidatePaths = new ArrayList<>();
for (Class<ExternalReferenceSPI> target : targetReferenceTypes) {
ShortestPathSolver solver = solvers.get(target);
if (solver == null) {
solver = new ShortestPathSolver(target);
solvers.put(target, solver);
}
if (solver != null)
for (TranslationPath path : solver.getTranslationPaths()) {
for (ExternalReferenceSPI er : references
.getExternalReferences())
if (er.getClass().equals(path.getSourceType()))
candidatePaths.add(path);
for (TranslationPath dereferenceBasedPath : path
.getDereferenceBasedPaths(references))
candidatePaths.add(dereferenceBasedPath);
}
}
/*
* Now add candidate paths to represent a no-translator 'direct from
* byte stream source' path for each target type compatible
* reference builder
*/
for (ExternalReferenceBuilderSPI<?> builder : builders)
if (targetReferenceTypes.contains(builder.getReferenceType()))
/*
* The builder can construct one of the target types, add
* paths for all possible pairs of 'de-reference existing
* reference' and the builder
*/
for (ExternalReferenceSPI er : references
.getExternalReferences()) {
TranslationPath newPath = new TranslationPath();
newPath.setBuilders(builders);
newPath.setInitialBuilder(builder);
newPath.setSourceReference(er);
candidatePaths.add(newPath);
}
/*
* Got a list of candidate paths sorted by estimated overall path
* cost
*/
Collections.sort(candidatePaths);
if (log.isDebugEnabled()) {
log.debug("Found "
+ candidatePaths.size()
+ " contextual translation path(s) including builder based :");
int counter = 0;
for (TranslationPath path : candidatePaths)
log.debug(" " + (++counter) + ") " + path.toString());
}
if (candidatePaths.isEmpty()) {
log.warn("No candidate paths found for augmentation");
throw new ReferenceSetAugmentationException(
"No candidate translation paths were found");
}
log.debug("Performing augmentation :");
int counter = 0;
for (TranslationPath path : candidatePaths)
try {
counter++;
Set<ExternalReferenceSPI> newReferences = path
.doTranslation(references, context);
if (log.isDebugEnabled())
log.debug(" Success (" + counter + "), created "
+ printRefSet(newReferences));
return newReferences;
} catch (Exception ex) {
log.debug(" Failed (" + counter + ")");
log.trace(ex);
// Use next path...
}
log.warn(" No paths succeeded, augmentation failed");
throw new ReferenceSetAugmentationException(
"All paths threw exceptions, can't perform augmentation");
}
}