001: /**
002: * ===========================================
003: * JFreeReport : a free Java reporting library
004: * ===========================================
005: *
006: * Project Info: http://reporting.pentaho.org/
007: *
008: * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
009: *
010: * This library is free software; you can redistribute it and/or modify it under the terms
011: * of the GNU Lesser General Public License as published by the Free Software Foundation;
012: * either version 2.1 of the License, or (at your option) any later version.
013: *
014: * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
015: * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
016: * See the GNU Lesser General Public License for more details.
017: *
018: * You should have received a copy of the GNU Lesser General Public License along with this
019: * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
020: * Boston, MA 02111-1307, USA.
021: *
022: * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
023: * in the United States and other countries.]
024: *
025: * ------------
026: * CountDistinctFunction.java
027: * ------------
028: * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
029: */package org.jfree.report.function;
030:
031: import java.io.IOException;
032: import java.io.ObjectInputStream;
033: import java.util.HashSet;
034:
035: import org.jfree.report.event.ReportEvent;
036:
037: /**
038: * Counts the distinct occurences of an certain value of an column. This functionality is
039: * similiar to the SQL distinct() function.
040: *
041: * @author Thomas Morgner
042: */
043: public class CountDistinctFunction extends AbstractFunction {
044: /**
045: * The collected values for the current group.
046: */
047: private transient HashSet values;
048: /**
049: * The name of the group on which to reset the count. This can be set to null to compute the count for the whole
050: * report.
051: */
052: private String group;
053: /**
054: * The field for which the number of distinct values are counted.
055: */
056: private String field;
057:
058: /**
059: * DefaultConstructor.
060: */
061: public CountDistinctFunction() {
062: values = new HashSet();
063: }
064:
065: /**
066: * Returns the group name.
067: *
068: * @return The group name.
069: */
070: public String getGroup() {
071: return group;
072: }
073:
074: /**
075: * Sets the group name. <P> If a group is defined, the running total is reset to zero at
076: * the start of every instance of this group.
077: *
078: * @param name the group name (null permitted).
079: */
080: public void setGroup(final String name) {
081: this .group = name;
082: }
083:
084: /**
085: * Returns the field used by the function. The field name corresponds to a column name in the report's data-row.
086: *
087: * @return The field name.
088: */
089: public String getField() {
090: return field;
091: }
092:
093: /**
094: * Sets the field name for the function. The field name corresponds to a column name in the report's data-row.
095: *
096: * @param field the field name.
097: */
098: public void setField(final String field) {
099: this .field = field;
100: }
101:
102: /**
103: * Receives notification that report generation initializes the current run. <P> The
104: * event carries a ReportState.Started state. Use this to initialize the report.
105: *
106: * @param event The event.
107: */
108: public void reportInitialized(final ReportEvent event) {
109: if (FunctionUtilities.isDefinedPrepareRunLevel(this , event) == false) {
110: return;
111: }
112: values.clear();
113: }
114:
115: /**
116: * Receives notification that a group has started.
117: *
118: * @param event the event.
119: */
120: public void groupStarted(final ReportEvent event) {
121: if (getField() == null) {
122: return;
123: }
124:
125: if (FunctionUtilities.isDefinedPrepareRunLevel(this , event) == false) {
126: return;
127: }
128: if (FunctionUtilities.isDefinedGroup(getGroup(), event) == false) {
129: return;
130: }
131:
132: values.clear();
133: }
134:
135: /**
136: * Receives notification that a row of data is being processed.
137: *
138: * @param event the event.
139: */
140: public void itemsAdvanced(final ReportEvent event) {
141: if (getField() == null) {
142: return;
143: }
144: if (FunctionUtilities.isDefinedPrepareRunLevel(this , event) == false) {
145: return;
146: }
147:
148: final Object o = event.getDataRow().get(getField());
149: values.add(o);
150: }
151:
152: /**
153: * Return the number of distint values for the given column.
154: *
155: * @return the value of the function.
156: */
157: public Object getValue() {
158: return new Integer(values.size());
159: }
160:
161: /**
162: * Helper method for serialization.
163: *
164: * @param in the input stream from where to read the serialized object.
165: * @throws IOException when reading the stream fails.
166: * @throws ClassNotFoundException if a class definition for a serialized object could
167: * not be found.
168: */
169: private void readObject(final ObjectInputStream in)
170: throws IOException, ClassNotFoundException {
171: in.defaultReadObject();
172: values = new HashSet();
173: }
174: }
|