001: /**
002: * ========================================
003: * JFreeReport : a free Java report library
004: * ========================================
005: *
006: * Project Info: http://reporting.pentaho.org/
007: *
008: * (C) Copyright 2000-2007, by Object Refinery Limited, 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: * $Id: GlobalMasterRow.java 3525 2007-10-16 11:43:48Z tmorgner $
027: * ------------
028: * (C) Copyright 2000-2005, by Object Refinery Limited.
029: * (C) Copyright 2005-2007, by Pentaho Corporation.
030: */package org.jfree.report.data;
031:
032: import org.jfree.report.DataRow;
033: import org.jfree.report.DataSourceException;
034: import org.jfree.report.flow.ReportContext;
035:
036: /**
037: * This data row holds all statefull information from the datasources of the
038: * report.
039: * <p/>
040: * When doing subreports, a datarow only has access to its own dataset and the
041: * columns from the next direct subreport, which have been marked as exported.
042: *
043: * @author Thomas Morgner
044: */
045: public final class GlobalMasterRow {
046: // private StaticDataRow previousRow;
047: private ReportDataRow reportDataRow;
048: private ParameterDataRow parameterDataRow;
049: private ExpressionDataRow expressionDataRow;
050: private GlobalMasterRow parentDataRow;
051: private GlobalView globalView;
052: private ImportedVariablesDataRow importedDataRow;
053:
054: private GlobalMasterRow() {
055: }
056:
057: public static GlobalMasterRow createReportRow(
058: final ReportContext reportContext) {
059: final GlobalMasterRow gmr = new GlobalMasterRow();
060: gmr.globalView = GlobalView.createView();
061: gmr.expressionDataRow = new ExpressionDataRow(gmr,
062: reportContext, 10);
063: return gmr;
064: }
065:
066: public static GlobalMasterRow createReportRow(
067: final GlobalMasterRow parentRow,
068: final ReportContext reportContext) {
069: final GlobalMasterRow gmr = createReportRow(reportContext);
070: gmr.parentDataRow = parentRow;
071: return gmr;
072: }
073:
074: public ExpressionDataRow getExpressionDataRow() {
075: return expressionDataRow;
076: }
077:
078: public ReportDataRow getReportDataRow() {
079: return reportDataRow;
080: }
081:
082: public void setReportDataRow(final ReportDataRow reportDataRow)
083: throws DataSourceException {
084: this .reportDataRow = reportDataRow;
085: updateGlobalView();
086: }
087:
088: public ParameterDataRow getParameterDataRow() {
089: return parameterDataRow;
090: }
091:
092: public void setParameterDataRow(
093: final ParameterDataRow parameterDataRow)
094: throws DataSourceException {
095: this .parameterDataRow = parameterDataRow;
096: updateGlobalView();
097: }
098:
099: public GlobalMasterRow getParentDataRow() {
100: return parentDataRow;
101: }
102:
103: public ImportedVariablesDataRow getImportedDataRow() {
104: return importedDataRow;
105: }
106:
107: public void setExportedDataRow(
108: final ImportedVariablesDataRow importedDataRow)
109: throws DataSourceException {
110: this .importedDataRow = importedDataRow;
111: updateImportedParameterView();
112: }
113:
114: /**
115: * Derives an instance of this datarow. That copy is completly disconnected
116: * from the original one and no change made to that copy affects the original
117: * datarow.
118: *
119: * @return the derived datarow.
120: */
121: public GlobalMasterRow derive() throws DataSourceException {
122: return derive(null);
123: }
124:
125: private GlobalMasterRow derive(final GlobalMasterRow subReportRow)
126: throws DataSourceException {
127: final GlobalMasterRow dataRow = new GlobalMasterRow();
128: dataRow.parameterDataRow = parameterDataRow;
129: dataRow.reportDataRow = reportDataRow;
130: dataRow.expressionDataRow = expressionDataRow.derive(dataRow);
131: dataRow.globalView = globalView.derive();
132: if (parentDataRow != null) {
133: dataRow.parentDataRow = parentDataRow.derive(subReportRow);
134: }
135: dataRow.importedDataRow = importedDataRow;
136: return dataRow;
137: }
138:
139: /**
140: * This advances the cursor by one row and updates the flags.
141: *
142: * @return
143: * @throws DataSourceException
144: */
145: public GlobalMasterRow advance() throws DataSourceException {
146: return advance(false, null);
147: }
148:
149: private GlobalMasterRow advance(final boolean deepTraversingOnly,
150: final GlobalMasterRow subReportRow)
151: throws DataSourceException {
152: final GlobalMasterRow dataRow = new GlobalMasterRow();
153: dataRow.globalView = globalView.advance();
154: dataRow.parameterDataRow = parameterDataRow;
155:
156: if (deepTraversingOnly == false && reportDataRow != null) {
157: dataRow.reportDataRow = reportDataRow.advance();
158: } else {
159: dataRow.reportDataRow = reportDataRow;
160: }
161: dataRow.updateGlobalView();
162: if (expressionDataRow != null) {
163: dataRow.expressionDataRow = expressionDataRow.advance(
164: dataRow, deepTraversingOnly);
165: }
166: if (parentDataRow != null) {
167: // the parent row should get a grip on our data as well - just for the
168: // deep traversing fun and so on ..
169: dataRow.parentDataRow = parentDataRow
170: .advance(true, dataRow);
171: }
172: if (importedDataRow != null) {
173: if (subReportRow == null) {
174: throw new NullPointerException();
175: }
176: dataRow.importedDataRow = importedDataRow
177: .advance(subReportRow);
178: dataRow.updateImportedParameterView();
179: }
180: return dataRow;
181: }
182:
183: private void updateImportedParameterView()
184: throws DataSourceException {
185: if (importedDataRow == null) {
186: return;
187: }
188:
189: final int parameterCount = importedDataRow.getColumnCount();
190: for (int i = 0; i < parameterCount; i++) {
191: final String columnName = importedDataRow.getColumnName(i);
192: if (columnName != null) {
193: final Object columnValue = importedDataRow.get(i);
194: globalView.putField(columnName, columnValue, true);
195: }
196: }
197: }
198:
199: /** This updates the global view. */
200: private void updateGlobalView() throws DataSourceException {
201: if (parameterDataRow != null) {
202: final int parameterCount = parameterDataRow
203: .getColumnCount();
204: for (int i = 0; i < parameterCount; i++) {
205: final String columnName = parameterDataRow
206: .getColumnName(i);
207: if (columnName != null) {
208: final Object columnValue = parameterDataRow.get(i);
209: globalView.putField(columnName, columnValue, true);
210: }
211: }
212: }
213: if (reportDataRow != null) {
214: final int dataColCount = reportDataRow.getColumnCount();
215: for (int i = 0; i < dataColCount; i++) {
216: final String columnName = reportDataRow
217: .getColumnName(i);
218: if (columnName != null) {
219: final Object columnValue = reportDataRow.get(i);
220: globalView.putField(columnName, columnValue, true);
221: }
222: }
223: }
224: }
225:
226: public boolean isAdvanceable() throws DataSourceException {
227: if (reportDataRow == null) {
228: return false;
229: }
230: return reportDataRow.isAdvanceable();
231: }
232:
233: public DataRow getGlobalView() {
234: return globalView;
235: }
236:
237: /**
238: * A call back method to communicate structural changes back to the master
239: * rows. (This is only called from the expression row, as all other datarows
240: * are static).
241: *
242: * @param chEvent
243: */
244: public void dataRowChanged(final MasterDataRowChangeEvent chEvent)
245: throws DataSourceException {
246: // rebuild the global view and tracks changes ..
247: final int type = chEvent.getType();
248: if (type == MasterDataRowChangeEvent.COLUMN_ADDED) {
249: globalView.putField(chEvent.getColumnName(), chEvent
250: .getColumnValue(), false);
251: } else if (type == MasterDataRowChangeEvent.COLUMN_UPDATED) {
252: globalView.putField(chEvent.getColumnName(), chEvent
253: .getColumnValue(), true);
254: } else if (type == MasterDataRowChangeEvent.COLUMN_REMOVED) {
255: globalView.removeColumn(chEvent.getColumnName());
256: }
257: }
258: }
|