public void traverse()

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);
	}