/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.jorphan.collections;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* Useful for finding all nodes in the tree that represent objects of a
* particular type. For instance, if your tree contains all strings, and a few
* StringBuilder objects, you can use the SearchByClass traverser to find all
* the StringBuilder objects in your tree.
* <p>
* Usage is simple. Given a {@link HashTree} object "tree", and a SearchByClass
* object:
*
* <pre>
* HashTree tree = new HashTree();
* // ... tree gets filled with objects
* SearchByClass searcher = new SearchByClass(StringBuilder.class);
* tree.traverse(searcher);
* Iterator iter = searcher.getSearchResults().iterator();
* while (iter.hasNext()) {
* StringBuilder foundNode = (StringBuilder) iter.next();
* HashTree subTreeOfFoundNode = searcher.getSubTree(foundNode);
* // .... do something with node and subTree...
* }
* </pre>
*
* @see HashTree
* @see HashTreeTraverser
*
* @param <T>
* Class that should be searched for
*/
public class SearchByClass<T> implements HashTreeTraverser {
private final List<T> objectsOfClass = new LinkedList<>();
private final Map<Object, ListedHashTree> subTrees = new HashMap<>();
private final Class<T> searchClass;
/**
* Creates an instance of SearchByClass, and sets the Class to be searched
* for.
*
* @param searchClass
* class to be searched for
*/
public SearchByClass(Class<T> searchClass) {
this.searchClass = searchClass;
}
/**
* After traversing the HashTree, call this method to get a collection of
* the nodes that were found.
*
* @return Collection All found nodes of the requested type
*/
public Collection<T> getSearchResults() { // TODO specify collection type without breaking callers
return objectsOfClass;
}
/**
* Given a specific found node, this method will return the sub tree of that
* node.
*
* @param root
* the node for which the sub tree is requested
* @return HashTree
*/
public HashTree getSubTree(Object root) {
return subTrees.get(root);
}
/** {@inheritDoc} */
@SuppressWarnings("unchecked")
@Override
public void addNode(Object node, HashTree subTree) {
if (searchClass.isAssignableFrom(node.getClass())) {
objectsOfClass.add((T) node);
ListedHashTree tree = new ListedHashTree(node);
tree.set(node, subTree);
subTrees.put(node, tree);
}
}
/** {@inheritDoc} */
@Override
public void subtractNode() {
}
/** {@inheritDoc} */
@Override
public void processPath() {
}
}