package com.onaro.util.jfc.grouping; import java.util.Comparator; import java.util.HashSet; import java.util.Set; import java.util.regex.Pattern; import org.apache.commons.lang3.StringUtils; import com.onaro.commons.util.SwingCollectionPrinter; /** * A summarizer that display a list of column values of descendant nodes. */ public class CollectSummarizer implements Summarizer { /** * The column from which the value is copied and to which it is copied. */ private final int column; private final String delimiter; private final Pattern splitPattern; /** * Prints a list of the values, using the given delimiter */ private SwingCollectionPrinter valuesPrinter; /** * Initialize the collector for the given column. * @param column the column to collect its values * @param delimiter used to separate the values in the string presentation of the summary */ public CollectSummarizer(int column, String delimiter) { this.column = column; this.delimiter = StringUtils.isNotBlank(delimiter) ? delimiter : ", "; //$NON-NLS-1$ this.splitPattern = Pattern.compile(this.delimiter); valuesPrinter = new SwingCollectionPrinter(this.delimiter, new Comparator() { public int compare(String o1, String o2) { return o1.compareToIgnoreCase(o2); } }); } /** * Collect the values of descendant nodes into a set in the given node. * @param node the node */ public void updateSummary(Node node) { int childCount = node.getChildCount(); if (childCount > 0) { CollectedValues values = new CollectedValues(); for (int child = 0 ; child < childCount; ++child) { Object childValue = node.getChild(child).getValueAt(column); if (childValue instanceof CollectedValues) { values.addAll((CollectedValues)childValue); } else if(childValue != null && !childValue.toString().isEmpty()){ String childValueStr = childValue.toString(); // Quick check for the delimiter if (childValueStr.contains(delimiter)) { //if the string has more than one value, add the values one by one for (String string : splitPattern.split(childValueStr)) { if (string.length() > 0) { values.add(string); } } } else { values.add(childValueStr); } } } node.setValueAt(column, values); } } /** * An ordered set of values with a specialized string presentation. */ private class CollectedValues implements Comparable { /** * Keeps the values. */ private Set values = new HashSet(); /** * The string presentation, initialized lazily when needed and destroyed * whenever the value changes. */ private String cachedListString; /** * Add all the values in the collection of values of a descendant node. * @param c the collected values of a descendant node * @return true if this set changed as a result of the call */ public boolean addAll(CollectedValues c) { cachedListString = null; return values.addAll(c.values); } /** * Adds a value to this collection. * @param o the value to add * @return true if this set did not already contain the specified element */ public boolean add(String o) { cachedListString = null; return values.add(o); } /** * Gets the string presentation of the values using the {@link valuesPrinter} * delimited list of values. The value is kept for next calls as long as the * set of values didn't change. * @return a list text of the values */ public String toString() { if (cachedListString == null) { cachedListString = valuesPrinter.toString(values); } return cachedListString; } public int compareTo(CollectedValues o) { return toString().compareToIgnoreCase(o.toString()); } } }