package com.onaro.util.jfc.grouping; /** * Count the rows in a group and all its descendants for which a given condition * is true. */ public class ConditionalCountSummarizer implements Summarizer { /** * The column to put the count of rows in. */ private int column; /** * The condition that tells if a row should be counted or not. */ private Condition condition; /** * Initialize a counter for the given column. * @param column the column to put the number of rows in * @param condition the condition that tells if a row should be counted or not */ public ConditionalCountSummarizer(int column, Condition condition) { this.column = column; this.condition = condition; } /** * Count the number of rows in the node and all its descendants. * @param node the node */ public void updateSummary(Node node) { int count = 0; for (int i = 0; i < node.getChildCount(); ++i) { Node child = node.getChild(i); if (child.getChildCount() == 0) { if (condition.count(child.getValueAt(column))) ++count; } else { Integer childCount = (Integer)child.getValueAt(column); count += childCount.intValue(); } } node.setValueAt(column, Integer.valueOf(count)); } /** * Defines how a row is evaluated. */ public interface Condition { /** * Tells if a row with this value should be counted or not. * @param value the value to test * @return true if a row with such value should be counted */ public boolean count(Object value); } /** * A condition that compares to a given value. */ public static class EqualsCondition implements Condition { /** * If a row has this value than this condition will tell to count it. */ private Object targetValue; /** * Initialize the condition for the given value. * @param targetValue if a row has this value than this condition will tell to count it */ public EqualsCondition(Object targetValue) { this.targetValue = targetValue; } public boolean count(Object value) { if (targetValue == null) { return value == null; } else { return targetValue.equals(value); } } } }