package com.onaro.util.jfc.grouping; import org.apache.commons.lang3.StringUtils; import com.onaro.sanscreen.client.view.tabular.value.NumberValue; /** * Average the values in a specific column for the rows in a group and all its descendants. */ public class AverageNumberSummarizer implements Summarizer { /** * The column to put the average in. */ private int column; /** * Defined the format-name used by {@link NumberValue} to format the number. */ private String format; /** * If true, don't show anything if a child row has a blank value */ protected boolean showIfAnyBlanks; /** * Initialize a summarizer for the given column. * @param column the column to put the average in */ public AverageNumberSummarizer(int column) { this(column, NumberValue.FORMAT_DEFAULT); } /** * Initialize a summarizer for the given column. Assumes default of showIfAnyBlanks = true. * @param column the column to put the average in * @param format Format to be used; blank/null results in NumberValue.FORMAT_DEFAULT being used */ public AverageNumberSummarizer(int column, String format) { this(column, format, true); } /** * Initialize a summarizer for the given column. * @param column the column to put the average in * @param format Format to be used; blank/null results in NumberValue.FORMAT_DEFAULT being used * @param showIfAnyBlanks if true, include null node values in the count divisor; otherwise return a null if any child node values are null */ public AverageNumberSummarizer(int column, String format, boolean showIfAnyBlanks) { this.column = column; this.format = StringUtils.isBlank(format) ? NumberValue.FORMAT_DEFAULT : format; this.showIfAnyBlanks = showIfAnyBlanks; } /** * Average the values of the column set for this summarizer in all the rows of the * given node and all its descendants. * @param node the node */ public void updateSummary(Node node) { double sum = 0; String unitsText = null; boolean hasBlankChildValue = false; for (int i = 0; i < node.getChildCount(); ++i) { Node child = node.getChild(i); Object value = child.getValueAt(column); if (value instanceof Number) { sum += ((Number)value).doubleValue(); } else if (value instanceof NumberValue) { NumberValue numberValue = ((NumberValue) value); sum += numberValue.getNumber(); if (unitsText==null) unitsText = numberValue.getUnitsText(); } else if(value == null) { hasBlankChildValue = true; } } // Show the value if we are showing even if there are blank values or we don't have blanks if(showIfAnyBlanks || !hasBlankChildValue) { double average = sum / node.getChildCount(); node.setValueAt(column, new NumberValue(average, unitsText, null, format)); } else { node.setValueAt(column, null); } } }