in taverna-workflowmodel-api/src/main/java/org/apache/taverna/visit/HierarchyTraverser.java [167:281]
public void traverse(Object o, List ancestry, Set<VisitReport> reports,
boolean includeTimeConsuming) {
/*
* For each visitor that is able to do visits for the set of VisitKind
* specified for the HierarchyTraverser
*/
for (Visitor v : visitors)
/*
* If time consuming visits are allowed or the visitor is not time
* consuming, and the visitor can visit the specified object
*/
if ((includeTimeConsuming || !v.isTimeConsuming()) && v.canVisit(o)) {
// Make the visitor visit the object
VisitReport report = null;
try {
report = v.visit(o, ancestry);
} catch (NullPointerException|ClassCastException e) {
logger.error("Visit threw exception", e);
}
if (report == null)
continue;
patchCheckTime(report, currentTimeMillis());
/*
* If the current object is an Activity then change the report
* so that its subject is the Processor containing the Activity
*/
if (o instanceof Activity) {
Processor p = (Processor) findAncestor(ancestry,
Processor.class);
if (p != null)
patchSubject(report, p);
}
/*
* Note in the VisitReport if it was caused by a time-consuming
* visitor
*/
if (v.isTimeConsuming() && (report != null))
patchTimeConsuming(report);
/*
* Add the VisitReport and its sub-reports, if any, to the set
* of VisitReports
*/
addReport(reports, report);
}
/*
* If the object is a nested dataflow activity then traverse the
* dataflow that is nested. Take the reports about the sub-dataflow and,
* if there are problems with it, create a DataflowCollation report
* about the nested dataflow activity (or to be more precise the
* Procesor containing it.)
*/
if (o instanceof NestedDataflow) {
NestedDataflow nestedDataflow = (NestedDataflow) o;
Dataflow subFlow = nestedDataflow.getNestedDataflow();
Set<VisitReport> subReports = new HashSet<>();
traverse(subFlow, new ArrayList<Object>(), subReports,
includeTimeConsuming);
Processor p = (Processor) findAncestor(ancestry, Processor.class);
if (p != null) {
Status worstStatus = getWorstStatus(subReports);
if (!worstStatus.equals(Status.OK)) {
VisitReport report = new VisitReport(
DataflowCollation.getInstance(),
p,
(worstStatus.equals(Status.WARNING) ? "Warnings in nested workflow"
: "Errors in nested workflow"),
DataflowCollation.NESTED_ISSUES, worstStatus,
subReports);
report.setProperty("dataflowIdentifier",
subFlow.getIdentifier());
report.setWasTimeConsuming(includeTimeConsuming);
reports.add(report);
}
}
}
// Now move on to traversing the descendents
/*
* For every child-getting method for this object, try to get the
* children and add them into a set.
*/
Set<String> methodNames = getMethods(o);
Set<Object> children = new HashSet<>();
for (Method m : o.getClass().getMethods())
if (methodNames.contains(m.getName())) {
Object methodResult = null;
try {
methodResult = m.invoke(o);
} catch (IllegalArgumentException | IllegalAccessException
| InvocationTargetException e) {
logger.error(e);
}
/*
* If the method did not produce a singleton but instead a List
* or similar then add the members of the list.
*/
children.addAll(getLeafs(methodResult));
}
/*
* For every child of the current object, traverse that object and get
* reports about it and its descendents.
*/
ArrayList<Object> newAncestry = new ArrayList<>();
newAncestry.add(o);
newAncestry.addAll(ancestry);
for (Object c : children)
traverse(c, newAncestry, reports, includeTimeConsuming);
}