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: * ItemHideFunction.java
027: * ------------
028: * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
029: */package org.jfree.report.function;
030:
031: import org.jfree.report.Element;
032: import org.jfree.report.event.PageEventListener;
033: import org.jfree.report.event.ReportEvent;
034: import org.jfree.util.ObjectUtilities;
035:
036: /**
037: * The ItemHideFunction hides equal values in a group. Only the first changed value is printed. This function uses the
038: * property <code>element</code> to define the name of the element in the ItemBand that should be made visible or
039: * invisible by this function. The property <code>field</code> defines the field in the datasource or the expression
040: * which should be used to determine the visibility.
041: *
042: * @author Thomas Morgner
043: */
044: public class ItemHideFunction extends AbstractFunction implements
045: PageEventListener {
046: /**
047: * The last object. This is part of the internal state and therefore not serialized.
048: */
049: private transient Object lastObject;
050:
051: /**
052: * The 'visible' flag. This is part of the internal state and therefore not serialized.
053: */
054: private transient boolean visible;
055:
056: /**
057: * The 'first-in-group' flag. This is part of the internal state and therefore not serialized.
058: */
059: private transient boolean firstInGroup;
060:
061: /**
062: * A flag indicating whether a group start resets the visiblity of the element.
063: */
064: private boolean ignoreGroupBreaks;
065: /**
066: * A flag indicating whether a page start resets the visiblity of the element.
067: */
068: private boolean ignorePageBreaks;
069:
070: /**
071: * The name of the element that should be hidden.
072: */
073: private String element;
074: /**
075: * The data-row column that should be checked for changed values.
076: */
077: private String field;
078:
079: /**
080: * Constructs an unnamed function. <P> Make sure to set the function name before it is used, or function
081: * initialisation will fail.
082: */
083: public ItemHideFunction() {
084: }
085:
086: /**
087: * Constructs a named function. <P> The field must be defined before using the function.
088: *
089: * @param name The function name.
090: */
091: public ItemHideFunction(final String name) {
092: this ();
093: setName(name);
094: }
095:
096: /**
097: * Returns whether a group start resets the visiblity of the element.
098: *
099: * @return false, if group breaks reset the visiblity, true otherwise.
100: */
101: public boolean isIgnoreGroupBreaks() {
102: return ignoreGroupBreaks;
103: }
104:
105: /**
106: * Defines whether a group start resets the visiblity of the element.
107: *
108: * @param ignoreGroupBreaks false, if group breaks reset the visiblity, true otherwise.
109: */
110: public void setIgnoreGroupBreaks(final boolean ignoreGroupBreaks) {
111: this .ignoreGroupBreaks = ignoreGroupBreaks;
112: }
113:
114: /**
115: * Returns whether a page start resets the visiblity of the element.
116: *
117: * @return false, if page breaks reset the visiblity, true otherwise.
118: */
119: public boolean isIgnorePageBreaks() {
120: return ignorePageBreaks;
121: }
122:
123: /**
124: * Returns whether a page start resets the visiblity of the element.
125: *
126: * @param ignorePageBreaks false, if page breaks reset the visiblity, true otherwise.
127: */
128: public void setIgnorePageBreaks(final boolean ignorePageBreaks) {
129: this .ignorePageBreaks = ignorePageBreaks;
130: }
131:
132: /**
133: * Returns the name of the element in the item band that should be set visible/invisible.
134: *
135: * @return The element name.
136: */
137: public String getElement() {
138: return element;
139: }
140:
141: /**
142: * Sets the name of the element in the item band that should be set visible/invisible.
143: *
144: * @param name the element name (must not be null).
145: */
146: public void setElement(final String name) {
147: this .element = name;
148: }
149:
150: /**
151: * Returns the field used by the function. The field name corresponds to a column name in the report's data-row.
152: *
153: * @return The field name.
154: */
155: public String getField() {
156: return field;
157: }
158:
159: /**
160: * Sets the field name for the function. The field name corresponds to a column name in the report's data-row.
161: *
162: * @param field the field name.
163: */
164: public void setField(final String field) {
165: this .field = field;
166: }
167:
168: /**
169: * Receives notification that a row of data is being processed. Reads the data from the field defined for this
170: * function and hides the field if the value is equal to the last value and the this is not the first row of the item
171: * group.
172: *
173: * @param event Information about the event.
174: */
175: public void itemsAdvanced(final ReportEvent event) {
176: final Object fieldValue = event.getDataRow().get(getField());
177:
178: // is visible when last and current object are not equal
179: // first element in group is always visible
180: if (firstInGroup == true) {
181: visible = true;
182: firstInGroup = false;
183: } else {
184: visible = (ObjectUtilities.equal(lastObject, fieldValue) == false);
185: }
186: lastObject = fieldValue;
187: final Element[] elements = FunctionUtilities.findAllElements(
188: event.getReport().getItemBand(), getElement());
189: for (int i = 0; i < elements.length; i++) {
190: final Element e = elements[i];
191: e.setVisible(visible);
192: }
193: }
194:
195: /**
196: * Resets the state of the function when a new ItemGroup has started.
197: *
198: * @param event the report event.
199: */
200: public void itemsStarted(final ReportEvent event) {
201: if (ignoreGroupBreaks == false) {
202: lastObject = null;
203: firstInGroup = true;
204: }
205: }
206:
207: /**
208: * Returns the function value, in this case the visibility of the defined element.
209: *
210: * @return The function value.
211: */
212: public Object getValue() {
213: if (visible) {
214: return Boolean.TRUE;
215: }
216: return Boolean.FALSE;
217: }
218:
219: /**
220: * Receives notification that a page is completed.
221: *
222: * @param event The event.
223: */
224: public void pageFinished(final ReportEvent event) {
225: }
226:
227: /**
228: * Receives notification that a new page is being started.
229: *
230: * @param event The event.
231: */
232: public void pageStarted(final ReportEvent event) {
233: if (ignorePageBreaks) {
234: return;
235: }
236:
237: final Object fieldValue = event.getDataRow().get(getField());
238:
239: // is visible when last and current object are not equal
240: // first element in group is always visible
241: // after a page start, reset the function ...
242: visible = true;
243: firstInGroup = true;
244: lastObject = fieldValue;
245: final Element[] elements = FunctionUtilities.findAllElements(
246: event.getReport().getItemBand(), getElement());
247: for (int i = 0; i < elements.length; i++) {
248: final Element e = elements[i];
249: e.setVisible(visible);
250: }
251: }
252:
253: /**
254: * Return a completly separated copy of this function. The copy does no longer share any changeable objects with the
255: * original function.
256: *
257: * @return a copy of this function.
258: */
259: public Expression getInstance() {
260: final ItemHideFunction ih = (ItemHideFunction) super
261: .getInstance();
262: ih.lastObject = null;
263: return ih;
264: }
265:
266: /**
267: * Receives notification that the report has started.
268: *
269: * @param event the event.
270: */
271: public void reportInitialized(final ReportEvent event) {
272: lastObject = null;
273: firstInGroup = true;
274: }
275: }
|