package com.onaro.util.jfc.grouping; import java.util.HashSet; import java.util.Set; import org.apache.commons.lang3.StringUtils; /** * Count the rows in a group and all its descendants making sure that they are unique. */ public class CountUniqueSummarizer implements Summarizer { /** * The column to put the count of rows in. */ private final int column; /** * Column value used to determine uniqueness */ private final int identifierColumn; /** * Initialize a counter for the given column. * @param column the column to put the number of rows in * @param identifierColumn the unique identifier column for the given row */ public CountUniqueSummarizer(int column, int identifierColumn) { this.column = column; this.identifierColumn = identifierColumn; } /** * Count the number of rows in the node and all its descendants. * @param node the node */ public void updateSummary(Node node) { Object value = null; Set valueSet = new HashSet(); for (int i = 0; i < node.getChildCount(); ++i) { Node child = node.getChild(i); value = child.getValueAt(column); if ((value instanceof CountValue)) { valueSet.addAll(((CountValue)value).valuesSet); } else { Object identifier = child.getValueAt(identifierColumn); valueSet.add(identifier); } } if (!valueSet.isEmpty()) { if (valueSet.size() == 1) { node.setValueAt(column, new CountValue(valueSet, value)); } else { node.setValueAt(column, new CountValue(valueSet)); } } } /** * Allows to distinguish values generated by the summarizer from the values that it * is counting. */ private static class CountValue implements Comparable { private final Set valuesSet; private final String display; public CountValue(Set valuesSet) { this.valuesSet = valuesSet; this.display = new StringBuilder().append('(').append(valuesSet.size()).append(')').toString(); } public CountValue(Set valuesSet, Object singleValue) { this.valuesSet = valuesSet; this.display = (singleValue == null) ? StringUtils.EMPTY : singleValue.toString(); } public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof CountValue)) return false; final CountValue countValue = (CountValue) o; if (display != null ? !display.equals(countValue.display) : countValue.display != null) return false; return true; } public int hashCode() { return (display != null ? display.hashCode() : 0); } public String toString() { return display; } public int compareTo(CountValue o) { if (o == null) return 1; return display.compareTo(o.toString()); } } }