001: /*
002: * Copyright 2006 Pentaho Corporation. All rights reserved.
003: * This software was developed by Pentaho Corporation and is provided under the terms
004: * of the Mozilla Public License, Version 1.1, or any later version. You may not use
005: * this file except in compliance with the license. If you need a copy of the license,
006: * please go to http://www.mozilla.org/MPL/MPL-1.1.txt. The Original Code is the Pentaho
007: * BI Platform. The Initial Developer is Pentaho Corporation.
008: *
009: * Software distributed under the Mozilla Public License is distributed on an "AS IS"
010: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. Please refer to
011: * the license for the specific language governing your rights and limitations.
012: *
013: * Created 02.07.2007
014: * @author Ingo Klose
015: */
016: package org.pentaho.plugin.jfreereport.reportcharts;
017:
018: import java.util.ArrayList;
019: import java.util.Arrays;
020: import java.util.List;
021:
022: import org.apache.commons.logging.Log;
023: import org.apache.commons.logging.LogFactory;
024: import org.jfree.data.category.DefaultCategoryDataset;
025: import org.jfree.data.general.AbstractDataset;
026: import org.jfree.report.event.ReportEvent;
027: import org.jfree.report.function.Expression;
028: import org.jfree.report.function.FunctionUtilities;
029: import org.jfree.util.ObjectUtilities;
030: import org.pentaho.messages.Messages;
031:
032: public class PivotCategorySetCollectorFunction extends
033: CategorySetCollectorFunction {
034: private static final long serialVersionUID = -1661805548096343053L;
035:
036: private ArrayList categoryNames;
037: private String seriesColumnHeader;
038:
039: private static final Log myLogger = LogFactory
040: .getLog(PivotCategorySetCollectorFunction.class);
041:
042: public PivotCategorySetCollectorFunction() {
043: super ();
044: this .categoryNames = new ArrayList();
045: }
046:
047: /*
048: * ------- Standard accessors - we use indexed properties for the series config.
049: */
050:
051: public String getSeriesColumnHeader() {
052: return seriesColumnHeader;
053: }
054:
055: public void setSeriesColumnHeader(final String seriesColumnHeader) {
056: this .seriesColumnHeader = seriesColumnHeader;
057: }
058:
059: public void setCategoryName(final int index, final String field) {
060: if (categoryNames.size() == index) {
061: categoryNames.add(field);
062: } else {
063: categoryNames.set(index, field);
064: }
065: }
066:
067: public String getCategoryName(final int index) {
068: return (String) this .categoryNames.get(index);
069: }
070:
071: public int getCategoryNameCount() {
072: return this .categoryNames.size();
073: }
074:
075: public String[] getCategoryName() {
076: return (String[]) this .categoryNames
077: .toArray(new String[this .categoryNames.size()]);
078: }
079:
080: public void setCategoryName(final String[] fields) {
081: this .categoryNames.clear();
082: this .categoryNames.addAll(Arrays.asList(fields));
083: }
084:
085: /* ---------------------------------------------------------------- Now the function implementation ...
086: */
087:
088: public void itemsAdvanced(ReportEvent reportEvent) {
089: logger
090: .debug(Messages
091: .getString("CATEGORYSETCOLL.USER_DEBUG_ITEMS_ADVANCED")); //$NON-NLS-1$
092: if (FunctionUtilities.isDefinedPrepareRunLevel(this ,
093: reportEvent) == false) {
094: // we do not modify the created dataset if this is not the function
095: // computation run. (FunctionLevel '0')
096: return;
097: }
098: if (!isSummaryOnly()) {
099: buildDataset();
100: }
101: }
102:
103: public void groupFinished(ReportEvent reportEvent) {
104: logger
105: .debug(Messages
106: .getString("CATEGORYSETCOLL.USER_DEBUG_GROUPS_FINISHED")); //$NON-NLS-1$
107: if (FunctionUtilities.isDefinedPrepareRunLevel(this ,
108: reportEvent) == false) {
109: // we do not modify the created dataset if this is not the function
110: // computation run. (FunctionLevel '0')
111: return;
112: }
113:
114: if (isSummaryOnly()) {
115: if (FunctionUtilities.isDefinedGroup(getGroup(),
116: reportEvent)) {
117:
118: // we can be sure that everything has been computed here. So
119: // grab the values and add them to the dataset.
120:
121: buildDataset();
122: }
123: }
124: }
125:
126: protected void buildDataset() {
127:
128: DefaultCategoryDataset dataset = null;
129: if (getDatasourceValue() instanceof DefaultCategoryDataset) {
130: dataset = (DefaultCategoryDataset) getDatasourceValue();
131: }
132:
133: //get column Id for row header
134: int iRowHeaderColumn = getDataRow().findColumn(
135: seriesColumnHeader);
136:
137: //get value in column that identifies the rows
138: String currentRowHeader = getDataRow().get(seriesColumnHeader)
139: .toString();
140:
141: //Check if row is part of the graph series
142: for (int i = 0; i < getSeriesNameCount(); i++) {
143: String rowName = (String) getSeriesName(i);
144:
145: if (rowName.equals(currentRowHeader)) {
146:
147: //loop through all columns to get values
148: for (int j = 0; j < getCategoryNameCount(); j++) {
149:
150: String newRowHeader = (String) getCategoryName(j);
151: int iColumnIndex = getDataRow().findColumn(
152: (String) getCategoryName(j));
153:
154: //if not rowHeader Column
155: if (iColumnIndex != iRowHeaderColumn) {
156:
157: //get the data
158: Object valueObject = getDataRow().get(
159: iColumnIndex);
160:
161: Number value = (valueObject instanceof Number) ? (Number) valueObject
162: : null;
163: Object isThere = null;
164: try {
165: isThere = dataset.getValue(rowName,
166: newRowHeader);
167: } catch (Exception ignored) {
168: }
169: if (isThere != null) {
170: double val = (value != null) ? value
171: .doubleValue() : 0;
172: value = new Double(val
173: + ((Number) isThere).doubleValue());
174: dataset.setValue(value, rowName,
175: newRowHeader);
176: } else {
177: dataset.addValue(value, rowName,
178: newRowHeader);
179: }
180: }
181: }
182: }
183: }
184: }
185:
186: public AbstractDataset getNewDataset() {
187: return new DefaultCategoryDataset();
188: }
189:
190: /**
191: * Return a completly separated copy of this function. The copy no longer
192: * shares any changeable objects with the original function.
193: * Also from Thomas:
194: * Should retain data from the report definition, but clear calculated data.
195: *
196: * @return a copy of this function.
197: */
198: public Expression getInstance() {
199: PivotCategorySetCollectorFunction fn = (PivotCategorySetCollectorFunction) super
200: .getInstance();
201: try {
202: fn.categoryNames = (ArrayList) categoryNames.clone();
203: } catch (Exception ex) {
204: myLogger.error(ex);
205: throw new IllegalStateException(ex);
206: }
207: return fn;
208: }
209:
210: }
|