blob: 76d4eca7975c8aef21238bf187cda45d87e54e98 [file] [log] [blame]
package net.sf.taverna.biocatalogue.model.search;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import javax.swing.tree.TreePath;
import net.sf.taverna.biocatalogue.model.Util;
import net.sf.taverna.biocatalogue.ui.filtertree.FilterTreeNode;
import net.sf.taverna.biocatalogue.ui.tristatetree.JTriStateTree;
/**
* This class provides functionality to deal with service filtering settings.
* Particularly used to save the current state of the filtering tree as a
* favourite filter.
*
* Instances of this class hold all necessary information to restore the
* filtering state at a later point.
*
* @author Sergejs Aleksejevs
*/
public class ServiceFilteringSettings implements Comparable<ServiceFilteringSettings>, Serializable
{
private static final long serialVersionUID = -5706169924295062628L;
private String filterName;
private int filteringCriteriaNumber;
private List<TreePath> filterTreeRootsOfCheckedPaths;
/**
* Stores current filtering selection in the provided JTriStateTree
* instance into the instance of this class.
*
* @param filterTree The JTriStateTree instance to get the current selection from.
*/
public ServiceFilteringSettings(JTriStateTree filterTree)
{
this(null, filterTree);
}
/**
* Stores current filtering selection in the provided JTriStateTree
* instance into the instance of this class.
*
* @param filterName The name to associate with this filter.
* @param filterTree The JTriStateTree instance to get the current selection from.
*/
@SuppressWarnings("unchecked")
public ServiceFilteringSettings(String filterName, JTriStateTree filterTree)
{
this.filterName = filterName;
this.filteringCriteriaNumber = filterTree.getLeavesOfCheckedPaths().size();
// a deep copy of the data from the filter tree is created, so that the data stored in this instance
// is fully independent of the filter tree itself; therefore local copy of this data may be modified
// as needed and will not affect the main filter (and vice versa)
this.filterTreeRootsOfCheckedPaths = (List<TreePath>)Util.deepCopy(filterTree.getRootsOfCheckedPaths());
}
/**
* Analyses the filter tree and produces part of the request URL containing settings regarding filters.
*/
@SuppressWarnings("unchecked")
public Map<String,String[]> getFilteringURLParameters()
{
// analyse filter tree to get checked elements
Map<String,HashSet<String>> selections = new HashMap<String,HashSet<String>>();
// cycle through the deepest selected nodes;
// NB! the CheckboxTree acts in a way that if A contains B,C --
// 1) if only B is checked, tp.getLastPathComponent() will be B;
// 2) if both B,C are checked, tp.getLastPathComponent() will be A;
for (TreePath selectedRootNodePath : getFilterTreeRootsOfCheckedPaths()) {
FilterTreeNode selectedNode = (FilterTreeNode)selectedRootNodePath.getLastPathComponent();
// identify affected nodes
HashSet<FilterTreeNode> affectedNodes = new HashSet<FilterTreeNode>();
if (selectedNode.isFilterCategory()) {
// case as in example 2) -- need to "extract" nodes that are one level deeper
for (Enumeration children = selectedNode.children(); children.hasMoreElements(); ) {
affectedNodes.add((FilterTreeNode)children.nextElement());
}
}
else {
// case as in example 1)
affectedNodes.add(selectedNode);
}
// walk through the identified collection of nodes and build the data structure with URL values
for (FilterTreeNode node : affectedNodes) {
if (selections.containsKey(node.getType())) {
selections.get(node.getType()).add(node.getUrlValue());
}
else {
HashSet<String> newSet = new HashSet<String>();
newSet.add(node.getUrlValue());
selections.put(node.getType(), newSet);
}
}
}
// now use the constructed set of data to build the map of filtering URL parameters
Map<String,String[]> filterUrlParameters = new HashMap<String,String[]>();
for(String key : selections.keySet())
{
List<String> categoryValues = new ArrayList<String>();
for (String value : selections.get(key)) {
categoryValues.add(value);
}
filterUrlParameters.put(key, categoryValues.toArray(new String[0]));
}
return (filterUrlParameters);
}
// *** Getters ***
public String getFilterName() {
return (this.filterName == null || filterName.length() == 0 ? "untitled filter" : this.filterName);
}
public List<TreePath> getFilterTreeRootsOfCheckedPaths() {
return filterTreeRootsOfCheckedPaths;
}
/**
* @return Number of filtering criteria within the current filter.
*/
public int getNumberOfFilteringCriteria() {
return filteringCriteriaNumber;
}
// *** End of getters ***
public boolean equals(Object other)
{
if (other instanceof ServiceFilteringSettings)
{
ServiceFilteringSettings o = (ServiceFilteringSettings)other;
return (this.filterName.equals(o.filterName) &&
this.filterTreeRootsOfCheckedPaths.equals(o.filterTreeRootsOfCheckedPaths));
}
else {
return false;
}
}
public int compareTo(ServiceFilteringSettings other)
{
int iOrdering = this.filterName.compareTo(other.filterName);
if (iOrdering == 0) {
iOrdering = this.getNumberOfFilteringCriteria() - other.getNumberOfFilteringCriteria();
}
// inverse order, as the traversal of lists in the favourite filters panel is
// done this way round
return (-1 * iOrdering);
}
public String toString() {
return ("Filter: '" + getFilterName() + "' [" + detailsAsString() + "]");
}
public String detailsAsString() {
return (getNumberOfFilteringCriteria() + " filtering criteria");
}
}