/*******************************************************************************
* Copyright (c) 2014 BREDEX GmbH.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* BREDEX GmbH - initial API and implementation and/or initial documentation
*******************************************************************************/
package org.eclipse.jubula.rc.javafx.tester.util;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jubula.rc.common.adaptable.AdapterFactoryRegistry;
import org.eclipse.jubula.rc.common.tester.adapter.interfaces.IComponent;
import org.eclipse.jubula.rc.common.tester.adapter.interfaces.ITextComponent;
import javafx.scene.Node;
import javafx.scene.Parent;
/**
* Utility class for finding instances of a certain type in the hierarchy below
* a given node
*
* @author BREDEX GmbH
* @created 25.03.2014
*/
public class NodeTraverseHelper {
/**
* Constructor
*/
private NodeTraverseHelper() {
//private
}
/**
* Finds instances of a certain type in the hierarchy below a given node
*
* @param <T> the type
* @param parent the parent
* @param type the type
* @param r the result
* @return the result
*/
private static <T> List<T> findInstancesOf(Parent parent,
Class<T> type, List<T> r) {
List<T> result = r;
for (Node object : parent.getChildrenUnmodifiable()) {
if (type.isAssignableFrom(object.getClass())) {
result.add((T) object);
}
if (object instanceof Parent) {
result = findInstancesOf((Parent) object, type, result);
}
}
return result;
}
/**
* Gives instances of a certain type in the hierarchy below a given node
*
* @param <T> the type
* @param parent the parent
* @param type the type
* @return returns all instances of the given type which are below the
* parent in the hierarchy
*/
public static <T> List<T> getInstancesOf(Parent parent,
Class<T> type) {
return findInstancesOf(parent, type, new ArrayList<T>());
}
/**
* Checks if the given node is under the given parent in the scene graph
*
* @param node the possible child node
* @param parent the parent
* @return true if the given node is related to the given parent, false if
* not
*/
public static boolean isChildOf(Node node, Parent parent) {
boolean result = false;
for (Node n : parent.getChildrenUnmodifiable()) {
if (!result) {
if (n == node) {
return true;
}
if (n instanceof Parent) {
result = isChildOf(node, (Parent) n);
}
}
}
return result;
}
/**
* Checks if a given Node is Visible by checking if all parent nodes are visible
* @param node the node
* @return true if visible, false otherwise
*/
public static boolean isVisible(Node node) {
if (node == null) {
return false;
}
Node tmp = node;
while (tmp != null) {
if (!tmp.isVisible()) {
return false;
}
tmp = tmp.getParent();
}
return true;
}
/**
* Find and collect strings under the given parent. This is done by looking
* for a ITextComponent Adapter for each child and then call getText. <br>
* <b>1. Commandment:</b> <br> Thou shall not call this method from a child for its parent.
*
* This would lead to an endless recursion and doom mankind to an endless
* struggle with debugging.
*
* @param parent
* the parent
* @return List containing the strings
*/
public static List<String> findStrings(Parent parent) {
ArrayList<String> renderedStrings = new ArrayList<>();
List<Node> children = new ArrayList<>();
for (Node n : new ArrayList<Node>(parent.getChildrenUnmodifiable())) {
// Only add children which are part of a rendered scene and when
// bounds calculation is possible
if (n.localToScreen(n.getBoundsInLocal()) != null) {
children.add(n);
}
}
children.sort(new NodePositionComparator());
for (Node n : children) {
IComponent adapter = (IComponent) AdapterFactoryRegistry
.getInstance().getAdapter(IComponent.class, n);
if (adapter != null && adapter instanceof ITextComponent) {
String text = ((ITextComponent) adapter).getText();
if (text != null) {
renderedStrings.add(text);
} else if (text == null && n instanceof Parent) {
renderedStrings.addAll(findStrings((Parent) n));
}
} else if (n instanceof Parent) {
renderedStrings.addAll(findStrings((Parent) n));
}
}
return renderedStrings;
}
}