TreePath nodeIndexPath = new TreePath(nodeIndex, parentNodeIndexPath);
boolean nodeExpanded = isNodeExpanded(nodeKeyPath);
if (nodeExpanded && !preloadingState.isPreloaded(nodePath)) {
preloadingState.addPreloadedTreePath(nodePath);
}
NodeInfoForRow nodeInfo = new NodeInfoForRow(nodePath, nodeKeyPath, nodeIndexPath, level, nodeExpanded, thisLevelInitiallyVisible);
boolean preloadChildren = nodeHasChildren && (
preloadingState.isPreloaded(nodePath) || (preloadedNodes != null && preloadedNodes.getPreloadChildren(nodeKeyPath))
);
TempNodeParams thisNodeParams = new TempNodeParams(nodeData, nodeInfo, nodeExpanded, preloadChildren);
boolean[] flagsArray = new boolean[activeFilters.size()];
boolean rowAccepted = TableDataModel.filterRow(activeFilters, thisNodeParams, flagsArray);
thisNodeParams.setRowAccepted(rowAccepted);
thisNodeParams.setFilteringFlags(flagsArray);
boolean lookForFilteredSubrows =
activeFilters.size() > 0 &&
!rowAccepted && /* when some filters are active we shouldn't extract invisible nodes if parent node satisfies filtering criteria */
!treeStructure.isEnteringInfiniteRecursion() /* avoid searching the endlessly-recurring hierarchies */;
if (isRowValuesForFilteringNeeded() || lookForFilteredSubrows || preloadChildren) {
treeStructure.goToChildLevel();
List<NodeInfoForRow> subtreeNodeInfosForRendering = new ArrayList<NodeInfoForRow>();
List<NodeInfoForRow> subtreeNodeInfosAllFiltered = new ArrayList<NodeInfoForRow>();
List<NodeInfoForRow> subtreeNodeInfos_unfiltered = new ArrayList<NodeInfoForRow>();
int filteredChildCount = collectTreeNodeDatas(
treeStructure, activeFilters, subtreeNodeInfosForRendering, subtreeNodeInfosAllFiltered, subtreeNodeInfos_unfiltered,
level + 1, sortLevel, nodePath, nodeKeyPath, nodeIndexPath, thisLevelInitiallyVisible && nodeExpanded);
nodeInfo.setNodeHasChildren(filteredChildCount > 0);
nodeInfo.setChildrenPreloaded(preloadChildren);
nodeInfo.setChildNodeCount(filteredChildCount);
thisNodeParams.setSubtreeNodeInfosForRendering(subtreeNodeInfosForRendering);
thisNodeParams.setSubtreeNodeInfosAllFiltered(subtreeNodeInfosAllFiltered);
thisNodeParams.setSubtreeNodeInfos_unfiltered(subtreeNodeInfos_unfiltered);
treeStructure.goToParentLevel();
} else {
nodeInfo.setNodeHasChildren(nodeHasChildren);
nodeInfo.setChildrenPreloaded(false);
nodeInfo.setChildNodeCount(0);
}
thisLevelNodeParams.add(thisNodeParams);
}
if (sortLevel == -1 || level == sortLevel)
sortNodes(thisLevelNodeParams, level);
List<boolean[]> thisLevelNodeFilteringFlags = new ArrayList<boolean[]>();
List<TempNodeParams> filteredNodeParams = new ArrayList<TempNodeParams>();
for (TempNodeParams rowObj : thisLevelNodeParams) {
thisLevelNodeFilteringFlags.add(rowObj.getFilteringFlags());
if (rowObj.isRowAccepted())
filteredNodeParams.add(rowObj);
}
for (TempNodeParams nodeParams : filteredNodeParams) {
NodeInfoForRow nodeInfoForRow = nodeParams.getNodeInfoForRow();
nodeInfoForRow.setAcceptedByFilters(true);
}
int passedChildCount = 0;
for (int i = 0; i < thisLevelNodeParams.size(); i++) {
TempNodeParams nodeParams = thisLevelNodeParams.get(i);
boolean[] nodeFilteringFlags = thisLevelNodeFilteringFlags.get(i);
NodeInfoForRow nodeInfoForRow = nodeParams.getNodeInfoForRow();
nodeInfoForRow.setNodeFilteringFlags(nodeFilteringFlags);
List<NodeInfoForRow> subtreeNodeInfos_unfiltered = nodeParams.getSubtreeNodeInfos_unfiltered();
nodeInfos_unfiltered.add(nodeInfoForRow);
if (subtreeNodeInfos_unfiltered != null)
nodeInfos_unfiltered.addAll(subtreeNodeInfos_unfiltered);
List<NodeInfoForRow> subtreeNodeInfosForRendering = nodeParams.getSubtreeNodeInfosForRendering();
List<NodeInfoForRow> subtreeNodeInfosAllFiltered = nodeParams.getSubtreeNodeInfosAllFiltered();
if (nodeInfoForRow.isAcceptedByFilters() || (subtreeNodeInfosAllFiltered != null && subtreeNodeInfosAllFiltered.size() > 0)) {
nodeInfosForRendering.add(nodeInfoForRow);
if (nodeInfosAllFiltered != null)
nodeInfosAllFiltered.add(nodeInfoForRow);
passedChildCount++;
boolean preloadChildrenToClient = nodeParams.getPreloadChildrenToClient();