0001: /**
0002: * ===========================================
0003: * JFreeReport : a free Java reporting library
0004: * ===========================================
0005: *
0006: * Project Info: http://reporting.pentaho.org/
0007: *
0008: * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
0009: *
0010: * This library is free software; you can redistribute it and/or modify it under the terms
0011: * of the GNU Lesser General Public License as published by the Free Software Foundation;
0012: * either version 2.1 of the License, or (at your option) any later version.
0013: *
0014: * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
0015: * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
0016: * See the GNU Lesser General Public License for more details.
0017: *
0018: * You should have received a copy of the GNU Lesser General Public License along with this
0019: * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
0020: * Boston, MA 02111-1307, USA.
0021: *
0022: * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
0023: * in the United States and other countries.]
0024: *
0025: * ------------
0026: * ExpressionDataRow.java
0027: * ------------
0028: * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
0029: */package org.jfree.report.states.datarow;
0030:
0031: import java.util.ArrayList;
0032: import javax.swing.table.TableModel;
0033:
0034: import org.jfree.report.DataRow;
0035: import org.jfree.report.ReportProcessingException;
0036: import org.jfree.report.ResourceBundleFactory;
0037: import org.jfree.report.event.PageEventListener;
0038: import org.jfree.report.event.PrepareEventListener;
0039: import org.jfree.report.event.ReportEvent;
0040: import org.jfree.report.function.Expression;
0041: import org.jfree.report.function.ExpressionRuntime;
0042: import org.jfree.report.function.Function;
0043: import org.jfree.report.function.ProcessingContext;
0044: import org.jfree.report.util.IntList;
0045: import org.jfree.report.util.IntegerCache;
0046: import org.jfree.report.util.LevelList;
0047: import org.jfree.util.Configuration;
0048: import org.jfree.util.Log;
0049:
0050: /**
0051: * Creation-Date: Dec 13, 2006, 3:17:20 PM
0052: *
0053: * @author Thomas Morgner
0054: */
0055: public final class ExpressionDataRow {
0056: private static final Integer[] EMPTY_INTEGERARRAY = new Integer[0];
0057: private static final Expression[] EMPTY_EXPRESSIONS = new Expression[0];
0058:
0059: private static class DataRowRuntime implements ExpressionRuntime {
0060: private ExpressionDataRow expressionDataRow;
0061:
0062: protected DataRowRuntime(final ExpressionDataRow dataRow) {
0063: this .expressionDataRow = dataRow;
0064: }
0065:
0066: public DataRow getDataRow() {
0067: return expressionDataRow.getMasterRow().getGlobalView();
0068: }
0069:
0070: public Configuration getConfiguration() {
0071: return getProcessingContext().getConfiguration();
0072: }
0073:
0074: public ResourceBundleFactory getResourceBundleFactory() {
0075: return getProcessingContext().getResourceBundleFactory();
0076: }
0077:
0078: /**
0079: * Access to the tablemodel was granted using report properties, now direct.
0080: */
0081: public TableModel getData() {
0082: return expressionDataRow.getMasterRow().getReportDataRow()
0083: .getReportData();
0084: }
0085:
0086: /**
0087: * Where are we in the current processing.
0088: */
0089: public int getCurrentRow() {
0090: return expressionDataRow.getMasterRow().getReportDataRow()
0091: .getCursor();
0092: }
0093:
0094: /**
0095: * The output descriptor is a simple string collections consisting of the following components:
0096: * exportclass/type/subtype
0097: * <p/>
0098: * For example, the PDF export would be: pageable/pdf The StreamHTML export would return table/html/stream
0099: *
0100: * @return the export descriptor.
0101: */
0102: public String getExportDescriptor() {
0103: return getProcessingContext().getExportDescriptor();
0104: }
0105:
0106: public ProcessingContext getProcessingContext() {
0107: return expressionDataRow.getProcessingContext();
0108: }
0109: }
0110:
0111: private static class LevelStorage {
0112: private int levelNumber;
0113: private int[] activeExpressions;
0114: private int[] functions;
0115: private int[] pageEventListeners;
0116: private int[] prepareEventListeners;
0117: private int[] expressions;
0118:
0119: protected LevelStorage(final int levelNumber,
0120: final int[] expressions, final int[] activeExpressions,
0121: final int[] functions, final int[] pageEventListeners,
0122: final int[] prepareEventListeners) {
0123: this .levelNumber = levelNumber;
0124: this .activeExpressions = activeExpressions;
0125: this .functions = functions;
0126: this .pageEventListeners = pageEventListeners;
0127: this .prepareEventListeners = prepareEventListeners;
0128: this .expressions = expressions;
0129: }
0130:
0131: public int getLevelNumber() {
0132: return levelNumber;
0133: }
0134:
0135: public int[] getFunctions() {
0136: return functions;
0137: }
0138:
0139: /**
0140: * @return Returns the activeExpressions.
0141: */
0142: public int[] getActiveExpressions() {
0143: return activeExpressions;
0144: }
0145:
0146: /**
0147: * @return Returns the expressions.
0148: */
0149: public int[] getExpressions() {
0150: return expressions;
0151: }
0152:
0153: /**
0154: * @return Returns the pageEventListeners.
0155: */
0156: public int[] getPageEventListeners() {
0157: return pageEventListeners;
0158: }
0159:
0160: /**
0161: * @return Returns the prepareEventListeners.
0162: */
0163: public int[] getPrepareEventListeners() {
0164: return prepareEventListeners;
0165: }
0166: }
0167:
0168: //private HashMap nameCache;
0169: private GlobalMasterRow masterRow;
0170: private ProcessingContext processingContext;
0171: private int length;
0172: private Expression[] expressions;
0173: private LevelStorage[] levelData;
0174: private MasterDataRowChangeEvent chEvent;
0175: private DataRowRuntime runtime;
0176: private ArrayList errorList;
0177: private static final Exception[] EMPTY_EXCEPTIONS = new Exception[0];
0178: private boolean prepareEventListener;
0179:
0180: public ExpressionDataRow(final GlobalMasterRow masterRow,
0181: final ProcessingContext processingContext) {
0182: this .processingContext = processingContext;
0183: this .masterRow = masterRow;
0184: this .expressions = EMPTY_EXPRESSIONS;
0185: this .chEvent = new MasterDataRowChangeEvent(
0186: MasterDataRowChangeEvent.COLUMN_UPDATED, "", "");
0187: this .runtime = new DataRowRuntime(this );
0188: this .revalidate();
0189: }
0190:
0191: private ExpressionDataRow(final GlobalMasterRow masterRow,
0192: final ExpressionDataRow previousRow,
0193: final boolean updateGlobalView)
0194: throws CloneNotSupportedException {
0195: this .chEvent = new MasterDataRowChangeEvent(
0196: MasterDataRowChangeEvent.COLUMN_UPDATED, "", "");
0197: this .processingContext = previousRow.processingContext;
0198: this .masterRow = masterRow;
0199: this .expressions = new Expression[previousRow.expressions.length];
0200: this .length = previousRow.length;
0201: this .levelData = previousRow.levelData;
0202: this .runtime = new DataRowRuntime(this );
0203:
0204: for (int i = 0; i < length; i++) {
0205: final Expression expression = previousRow.expressions[i];
0206: if (expression == null) {
0207: Log.debug("Error: Expression is null...");
0208: throw new IllegalStateException();
0209: }
0210:
0211: if (expression instanceof Function) {
0212: expressions[i] = (Expression) expression.clone();
0213: } else {
0214: expressions[i] = expression;
0215: }
0216:
0217: if (updateGlobalView == false) {
0218: continue;
0219: }
0220:
0221: final String name = expression.getName();
0222: chEvent.setColumnName(name);
0223: Object value;
0224:
0225: final ExpressionRuntime oldRuntime = expression
0226: .getRuntime();
0227: try {
0228: expression.setRuntime(runtime);
0229: if (runtime.getProcessingContext().getProcessingLevel() <= expression
0230: .getDependencyLevel()) {
0231: value = expression.getValue();
0232: } else {
0233: value = null;
0234: }
0235: } catch (Exception e) {
0236: if (Log.isDebugEnabled()) {
0237: Log.warn("Failed to evaluate expression '" + name
0238: + '\'', e);
0239: } else {
0240: Log.warn("Failed to evaluate expression '" + name
0241: + '\'');
0242: }
0243: value = null;
0244: } finally {
0245: expression.setRuntime(oldRuntime);
0246: }
0247: chEvent.setColumnValue(value);
0248: masterRow.dataRowChanged(chEvent);
0249: }
0250: }
0251:
0252: /**
0253: * This adds the expression to the data-row and queries the expression for the first time.
0254: *
0255: * @param expressionSlot
0256: * @param preserveState
0257: * @throws ReportProcessingException
0258: */
0259: private void pushExpression(final Expression expressionSlot,
0260: final boolean preserveState)
0261: throws ReportProcessingException {
0262: if (expressionSlot == null) {
0263: throw new NullPointerException();
0264: }
0265:
0266: ensureCapacity(length + 1);
0267:
0268: if (preserveState == false) {
0269: this .expressions[length] = expressionSlot.getInstance();
0270: } else {
0271: try {
0272: this .expressions[length] = (Expression) expressionSlot
0273: .clone();
0274: } catch (CloneNotSupportedException e) {
0275: throw new ReportProcessingException(
0276: "Failed to clone the expression.");
0277: }
0278: }
0279:
0280: final String name = expressionSlot.getName();
0281: length += 1;
0282:
0283: // A manual advance to initialize the function.
0284: if (name != null) {
0285: final MasterDataRowChangeEvent chEvent = new MasterDataRowChangeEvent(
0286: MasterDataRowChangeEvent.COLUMN_ADDED, name, null);
0287: masterRow.dataRowChanged(chEvent);
0288: }
0289: }
0290:
0291: public synchronized void pushExpressions(
0292: final Expression[] expressionSlots,
0293: final boolean preserveState)
0294: throws ReportProcessingException {
0295: if (expressionSlots == null) {
0296: throw new NullPointerException();
0297: }
0298:
0299: ensureCapacity(length + expressionSlots.length);
0300: for (int i = 0; i < expressionSlots.length; i++) {
0301: final Expression expression = expressionSlots[i];
0302: if (expression == null) {
0303: continue;
0304: }
0305: pushExpression(expression, preserveState);
0306: }
0307:
0308: revalidate();
0309: }
0310:
0311: public synchronized void popExpressions(final int counter) {
0312: for (int i = 0; i < counter; i++) {
0313: popExpression();
0314: }
0315:
0316: revalidate();
0317: }
0318:
0319: private void popExpression() {
0320: if (length == 0) {
0321: return;
0322: }
0323: final Expression removedExpression = this .expressions[length - 1];
0324: final String originalName = removedExpression.getName();
0325: removedExpression.setRuntime(null);
0326:
0327: this .expressions[length - 1] = null;
0328: this .length -= 1;
0329: if (originalName != null) {
0330: if (removedExpression.isPreserve() == false) {
0331: final MasterDataRowChangeEvent chEvent = new MasterDataRowChangeEvent(
0332: MasterDataRowChangeEvent.COLUMN_REMOVED,
0333: originalName, null);
0334: masterRow.dataRowChanged(chEvent);
0335: }
0336: }
0337: }
0338:
0339: private void ensureCapacity(final int requestedSize) {
0340: final int capacity = this .expressions.length;
0341: if (capacity > requestedSize) {
0342: return;
0343: }
0344: final int newSize = Math.max(capacity * 2, requestedSize + 10);
0345:
0346: final Expression[] newExpressions = new Expression[newSize];
0347: System.arraycopy(expressions, 0, newExpressions, 0, length);
0348:
0349: this .expressions = newExpressions;
0350: }
0351:
0352: private void revalidate() {
0353: // recompute the level storage ..
0354: final LevelList levelList = new LevelList();
0355: for (int i = 0; i < length; i++) {
0356: final Expression expression = expressions[i];
0357:
0358: // The list maps the current position to the level ..
0359: levelList.add(IntegerCache.getInteger(i), expression
0360: .getDependencyLevel());
0361: }
0362:
0363: final Integer[] levels = levelList.getLevelsDescendingArray();
0364: this .levelData = new LevelStorage[levels.length];
0365: final int expressionsCount = levelList.size();
0366:
0367: final int capacity = Math.min(20, expressionsCount);
0368: final IntList expressionPositions = new IntList(capacity);
0369: final IntList activeExpressions = new IntList(capacity);
0370: final IntList functions = new IntList(capacity);
0371: final IntList pageEventListeners = new IntList(capacity);
0372: final IntList prepareEventListeners = new IntList(capacity);
0373: boolean prepareEventListener = false;
0374:
0375: for (int i = 0; i < levels.length; i++) {
0376: final int currentLevel = levels[i].intValue();
0377: final Integer[] data = (Integer[]) levelList
0378: .getElementArrayForLevel(currentLevel,
0379: EMPTY_INTEGERARRAY);
0380: for (int x = 0; x < data.length; x++) {
0381: final Integer position = data[x];
0382: final Expression ex = this .expressions[position
0383: .intValue()];
0384: final int globalPosition = position.intValue();
0385:
0386: expressionPositions.add(globalPosition);
0387: activeExpressions.add(globalPosition);
0388: if (ex instanceof Function == false) {
0389: continue;
0390: }
0391:
0392: functions.add(globalPosition);
0393: if (ex instanceof PageEventListener) {
0394: pageEventListeners.add(globalPosition);
0395: } else if (ex instanceof PrepareEventListener) {
0396: prepareEventListener = true;
0397: prepareEventListeners.add(globalPosition);
0398: }
0399: }
0400:
0401: levelData[i] = new LevelStorage(currentLevel,
0402: expressionPositions.toArray(), activeExpressions
0403: .toArray(), functions.toArray(),
0404: pageEventListeners.toArray(), prepareEventListeners
0405: .toArray());
0406:
0407: expressionPositions.clear();
0408: activeExpressions.clear();
0409: functions.clear();
0410: pageEventListeners.clear();
0411: prepareEventListeners.clear();
0412:
0413: this .prepareEventListener = prepareEventListener;
0414: }
0415: }
0416:
0417: public int[] getLevels() {
0418: final int[] retval = new int[levelData.length];
0419: for (int i = 0; i < levelData.length; i++) {
0420: final LevelStorage storage = levelData[i];
0421: retval[i] = storage.getLevelNumber();
0422: }
0423: return retval;
0424: }
0425:
0426: /**
0427: * Returns the number of columns, expressions and functions and marked ReportProperties in the report.
0428: *
0429: * @return the item count.
0430: */
0431: public int getColumnCount() {
0432: return length;
0433: }
0434:
0435: public void fireReportEvent(final ReportEvent event) {
0436: if (event.isPrepareEvent()) {
0437: firePrepareEvent(event);
0438: } else if ((event.getType() & ReportEvent.PAGE_STARTED) == ReportEvent.PAGE_STARTED) {
0439: firePageStartedEvent(event);
0440: } else if ((event.getType() & ReportEvent.PAGE_FINISHED) == ReportEvent.PAGE_FINISHED) {
0441: firePageFinishedEvent(event);
0442: } else if ((event.getType() & ReportEvent.ITEMS_ADVANCED) == ReportEvent.ITEMS_ADVANCED) {
0443: fireItemsAdvancedEvent(event);
0444: } else if ((event.getType() & ReportEvent.ITEMS_FINISHED) == ReportEvent.ITEMS_FINISHED) {
0445: fireItemsFinishedEvent(event);
0446: } else if ((event.getType() & ReportEvent.ITEMS_STARTED) == ReportEvent.ITEMS_STARTED) {
0447: fireItemsStartedEvent(event);
0448: } else if ((event.getType() & ReportEvent.GROUP_FINISHED) == ReportEvent.GROUP_FINISHED) {
0449: fireGroupFinishedEvent(event);
0450: } else if ((event.getType() & ReportEvent.GROUP_STARTED) == ReportEvent.GROUP_STARTED) {
0451: fireGroupStartedEvent(event);
0452: } else if ((event.getType() & ReportEvent.REPORT_INITIALIZED) == ReportEvent.REPORT_INITIALIZED) {
0453: fireReportInitializedEvent(event);
0454: } else if ((event.getType() & ReportEvent.REPORT_DONE) == ReportEvent.REPORT_DONE) {
0455: fireReportDoneEvent(event);
0456: } else if ((event.getType() & ReportEvent.REPORT_FINISHED) == ReportEvent.REPORT_FINISHED) {
0457: fireReportFinishedEvent(event);
0458: } else if ((event.getType() & ReportEvent.REPORT_STARTED) == ReportEvent.REPORT_STARTED) {
0459: fireReportStartedEvent(event);
0460: } else {
0461: throw new IllegalArgumentException();
0462: }
0463:
0464: reactivateExpressions(event.isDeepTraversing());
0465: }
0466:
0467: private void reactivateExpressions(final boolean deepTraversing) {
0468: final int activeLevel = processingContext.getProcessingLevel();
0469: for (int levelIdx = 0; levelIdx < levelData.length; levelIdx++) {
0470: final int level = levelData[levelIdx].getLevelNumber();
0471: if (level < activeLevel) {
0472: break;
0473: }
0474:
0475: final int[] listeners = levelData[levelIdx]
0476: .getActiveExpressions();
0477: for (int l = 0; l < listeners.length; l++) {
0478: final Expression expression = expressions[listeners[l]];
0479: if (deepTraversing
0480: && expression.isDeepTraversing() == false) {
0481: continue;
0482: }
0483:
0484: expression.setRuntime(runtime);
0485: final String name = expression.getName();
0486: if (name != null) {
0487: chEvent.setColumnName(name);
0488: try {
0489: final Object value;
0490: if (runtime.getProcessingContext()
0491: .getProcessingLevel() <= expression
0492: .getDependencyLevel()) {
0493: value = expression.getValue();
0494: } else {
0495: value = null;
0496: }
0497: chEvent.setColumnValue(value);
0498: } catch (Exception e) {
0499: chEvent.setColumnValue(null);
0500: Log.info("Evaluation of expression '" + name
0501: + "'failed.", e);
0502: }
0503: masterRow.dataRowChanged(chEvent);
0504: }
0505: expression.setRuntime(null);
0506: }
0507: }
0508: }
0509:
0510: private void fireItemsAdvancedEvent(final ReportEvent event) {
0511: final boolean deepTraversing = event.isDeepTraversing();
0512: final int activeLevel = processingContext.getProcessingLevel();
0513: for (int levelIdx = 0; levelIdx < levelData.length; levelIdx++) {
0514: final int level = levelData[levelIdx].getLevelNumber();
0515: if (level < activeLevel) {
0516: break;
0517: }
0518:
0519: final int[] listeners = levelData[levelIdx].getFunctions();
0520: for (int l = 0; l < listeners.length; l++) {
0521: final Expression expression = expressions[listeners[l]];
0522: if (deepTraversing
0523: && expression.isDeepTraversing() == false) {
0524: continue;
0525: }
0526:
0527: final ExpressionRuntime oldRuntime = expression
0528: .getRuntime();
0529: expression.setRuntime(runtime);
0530: final Function e = (Function) expression;
0531: try {
0532: e.itemsAdvanced(event);
0533: final String name = expression.getName();
0534: if (name != null) {
0535: chEvent.setColumnName(name);
0536: chEvent.setColumnValue(expression.getValue());
0537: masterRow.dataRowChanged(chEvent);
0538: }
0539: } catch (Exception ex) {
0540: if (Log.isDebugEnabled()) {
0541: Log.error("Failed to fire prepare event", ex);
0542: } else {
0543: Log
0544: .error("Failed to fire prepare event: "
0545: + ex);
0546: }
0547: addError(ex);
0548: }
0549:
0550: expression.setRuntime(oldRuntime);
0551: }
0552: }
0553: }
0554:
0555: private void fireItemsStartedEvent(final ReportEvent event) {
0556: final boolean deepTraversing = event.isDeepTraversing();
0557: final int activeLevel = processingContext.getProcessingLevel();
0558: for (int levelIdx = 0; levelIdx < levelData.length; levelIdx++) {
0559: final int level = levelData[levelIdx].getLevelNumber();
0560: if (level < activeLevel) {
0561: break;
0562: }
0563:
0564: final int[] listeners = levelData[levelIdx].getFunctions();
0565: for (int l = 0; l < listeners.length; l++) {
0566: final Expression expression = expressions[listeners[l]];
0567: if (deepTraversing
0568: && expression.isDeepTraversing() == false) {
0569: continue;
0570: }
0571:
0572: final ExpressionRuntime oldRuntime = expression
0573: .getRuntime();
0574: expression.setRuntime(runtime);
0575: final Function e = (Function) expression;
0576: try {
0577: e.itemsStarted(event);
0578: final String name = expression.getName();
0579: if (name != null) {
0580: chEvent.setColumnName(name);
0581: chEvent.setColumnValue(expression.getValue());
0582: masterRow.dataRowChanged(chEvent);
0583: }
0584: } catch (Exception ex) {
0585: if (Log.isDebugEnabled()) {
0586: Log.error("Failed to fire prepare event", ex);
0587: } else {
0588: Log
0589: .error("Failed to fire prepare event: "
0590: + ex);
0591: }
0592: addError(ex);
0593: }
0594:
0595: expression.setRuntime(oldRuntime);
0596: }
0597: }
0598: }
0599:
0600: private void fireItemsFinishedEvent(final ReportEvent event) {
0601: final boolean deepTraversing = event.isDeepTraversing();
0602: final int activeLevel = processingContext.getProcessingLevel();
0603: for (int levelIdx = 0; levelIdx < levelData.length; levelIdx++) {
0604: final int level = levelData[levelIdx].getLevelNumber();
0605: if (level < activeLevel) {
0606: break;
0607: }
0608:
0609: final int[] listeners = levelData[levelIdx].getFunctions();
0610: for (int l = 0; l < listeners.length; l++) {
0611: final Expression expression = expressions[listeners[l]];
0612: if (deepTraversing
0613: && expression.isDeepTraversing() == false) {
0614: continue;
0615: }
0616:
0617: final ExpressionRuntime oldRuntime = expression
0618: .getRuntime();
0619: expression.setRuntime(runtime);
0620: final Function e = (Function) expression;
0621: try {
0622: e.itemsFinished(event);
0623: final String name = expression.getName();
0624: if (name != null) {
0625: chEvent.setColumnName(name);
0626: chEvent.setColumnValue(expression.getValue());
0627: masterRow.dataRowChanged(chEvent);
0628: }
0629: } catch (Exception ex) {
0630: if (Log.isDebugEnabled()) {
0631: Log.error("Failed to fire prepare event", ex);
0632: } else {
0633: Log
0634: .error("Failed to fire prepare event: "
0635: + ex);
0636: }
0637: addError(ex);
0638: }
0639:
0640: expression.setRuntime(oldRuntime);
0641: }
0642: }
0643: }
0644:
0645: private void fireGroupStartedEvent(final ReportEvent event) {
0646: final boolean deepTraversing = event.isDeepTraversing();
0647: final int activeLevel = processingContext.getProcessingLevel();
0648: for (int levelIdx = 0; levelIdx < levelData.length; levelIdx++) {
0649: final int level = levelData[levelIdx].getLevelNumber();
0650: if (level < activeLevel) {
0651: break;
0652: }
0653:
0654: final int[] listeners = levelData[levelIdx].getFunctions();
0655: for (int l = 0; l < listeners.length; l++) {
0656: final Expression expression = expressions[listeners[l]];
0657: if (deepTraversing
0658: && expression.isDeepTraversing() == false) {
0659: continue;
0660: }
0661:
0662: final ExpressionRuntime oldRuntime = expression
0663: .getRuntime();
0664: expression.setRuntime(runtime);
0665: final Function e = (Function) expression;
0666: try {
0667: e.groupStarted(event);
0668: final String name = expression.getName();
0669: if (name != null) {
0670: chEvent.setColumnName(name);
0671: chEvent.setColumnValue(expression.getValue());
0672: masterRow.dataRowChanged(chEvent);
0673: }
0674: } catch (Exception ex) {
0675: if (Log.isDebugEnabled()) {
0676: Log.error("Failed to fire group-started event",
0677: ex);
0678: } else {
0679: Log
0680: .error("Failed to fire group-started event: "
0681: + ex);
0682: }
0683: addError(ex);
0684: }
0685:
0686: expression.setRuntime(oldRuntime);
0687: }
0688: }
0689: }
0690:
0691: private void fireGroupFinishedEvent(final ReportEvent event) {
0692: final boolean deepTraversing = event.isDeepTraversing();
0693: final int activeLevel = processingContext.getProcessingLevel();
0694: for (int levelIdx = 0; levelIdx < levelData.length; levelIdx++) {
0695: final int level = levelData[levelIdx].getLevelNumber();
0696: if (level < activeLevel) {
0697: break;
0698: }
0699:
0700: final int[] listeners = levelData[levelIdx].getFunctions();
0701: for (int l = 0; l < listeners.length; l++) {
0702: final Expression expression = expressions[listeners[l]];
0703: if (deepTraversing
0704: && expression.isDeepTraversing() == false) {
0705: continue;
0706: }
0707:
0708: final ExpressionRuntime oldRuntime = expression
0709: .getRuntime();
0710: expression.setRuntime(runtime);
0711: final Function e = (Function) expression;
0712: try {
0713: e.groupFinished(event);
0714: final String name = expression.getName();
0715: if (name != null) {
0716: chEvent.setColumnName(name);
0717: chEvent.setColumnValue(expression.getValue());
0718: masterRow.dataRowChanged(chEvent);
0719: }
0720: } catch (Exception ex) {
0721: if (Log.isDebugEnabled()) {
0722: Log.error(
0723: "Failed to fire group-finished event",
0724: ex);
0725: } else {
0726: Log
0727: .error("Failed to fire group-finished event: "
0728: + ex);
0729: }
0730: addError(ex);
0731: }
0732:
0733: expression.setRuntime(oldRuntime);
0734: }
0735: }
0736: }
0737:
0738: private void fireReportStartedEvent(final ReportEvent event) {
0739: final boolean deepTraversing = event.isDeepTraversing();
0740: final int activeLevel = processingContext.getProcessingLevel();
0741: for (int levelIdx = 0; levelIdx < levelData.length; levelIdx++) {
0742: final int level = levelData[levelIdx].getLevelNumber();
0743: if (level < activeLevel) {
0744: break;
0745: }
0746:
0747: final int[] listeners = levelData[levelIdx].getFunctions();
0748: for (int l = 0; l < listeners.length; l++) {
0749: final Expression expression = expressions[listeners[l]];
0750: if (deepTraversing
0751: && expression.isDeepTraversing() == false) {
0752: continue;
0753: }
0754:
0755: final ExpressionRuntime oldRuntime = expression
0756: .getRuntime();
0757: expression.setRuntime(runtime);
0758: final Function e = (Function) expression;
0759: try {
0760: e.reportStarted(event);
0761: final String name = expression.getName();
0762: if (name != null) {
0763: chEvent.setColumnName(name);
0764: chEvent.setColumnValue(expression.getValue());
0765: masterRow.dataRowChanged(chEvent);
0766: }
0767: } catch (Exception ex) {
0768: if (Log.isDebugEnabled()) {
0769: Log.error(
0770: "Failed to fire report-started event",
0771: ex);
0772: } else {
0773: Log
0774: .error("Failed to fire report-started event: "
0775: + ex);
0776: }
0777: addError(ex);
0778: }
0779:
0780: expression.setRuntime(oldRuntime);
0781: }
0782: }
0783: }
0784:
0785: private void fireReportDoneEvent(final ReportEvent event) {
0786: final boolean deepTraversing = event.isDeepTraversing();
0787: final int activeLevel = processingContext.getProcessingLevel();
0788: for (int levelIdx = 0; levelIdx < levelData.length; levelIdx++) {
0789: final int level = levelData[levelIdx].getLevelNumber();
0790: if (level < activeLevel) {
0791: break;
0792: }
0793:
0794: final int[] listeners = levelData[levelIdx].getFunctions();
0795: for (int l = 0; l < listeners.length; l++) {
0796: final Expression expression = expressions[listeners[l]];
0797: if (deepTraversing
0798: && expression.isDeepTraversing() == false) {
0799: continue;
0800: }
0801:
0802: final ExpressionRuntime oldRuntime = expression
0803: .getRuntime();
0804: expression.setRuntime(runtime);
0805: final Function e = (Function) expression;
0806: try {
0807: e.reportDone(event);
0808: final String name = expression.getName();
0809: if (name != null) {
0810: chEvent.setColumnName(name);
0811: chEvent.setColumnValue(expression.getValue());
0812: masterRow.dataRowChanged(chEvent);
0813: }
0814: } catch (Exception ex) {
0815: if (Log.isDebugEnabled()) {
0816: Log.error("Failed to fire report-done event",
0817: ex);
0818: } else {
0819: Log.error("Failed to fire report-done event: "
0820: + ex);
0821: }
0822: addError(ex);
0823: }
0824:
0825: expression.setRuntime(oldRuntime);
0826: }
0827: }
0828: }
0829:
0830: private void fireReportFinishedEvent(final ReportEvent event) {
0831: final boolean deepTraversing = event.isDeepTraversing();
0832: final int activeLevel = processingContext.getProcessingLevel();
0833: for (int levelIdx = 0; levelIdx < levelData.length; levelIdx++) {
0834: final int level = levelData[levelIdx].getLevelNumber();
0835: if (level < activeLevel) {
0836: break;
0837: }
0838:
0839: final int[] listeners = levelData[levelIdx].getFunctions();
0840: for (int l = 0; l < listeners.length; l++) {
0841: final Expression expression = expressions[listeners[l]];
0842: if (deepTraversing
0843: && expression.isDeepTraversing() == false) {
0844: continue;
0845: }
0846:
0847: final ExpressionRuntime oldRuntime = expression
0848: .getRuntime();
0849: expression.setRuntime(runtime);
0850: final Function e = (Function) expression;
0851: try {
0852: e.reportFinished(event);
0853: final String name = expression.getName();
0854: if (name != null) {
0855: chEvent.setColumnName(name);
0856: chEvent.setColumnValue(expression.getValue());
0857: masterRow.dataRowChanged(chEvent);
0858: }
0859: } catch (Exception ex) {
0860: if (Log.isDebugEnabled()) {
0861: Log.error(
0862: "Failed to fire report-finished event",
0863: ex);
0864: } else {
0865: Log
0866: .error("Failed to fire report-finished event: "
0867: + ex);
0868: }
0869: addError(ex);
0870: }
0871:
0872: expression.setRuntime(oldRuntime);
0873: }
0874: }
0875: }
0876:
0877: private void fireReportInitializedEvent(final ReportEvent event) {
0878: final boolean deepTraversing = event.isDeepTraversing();
0879: final int activeLevel = processingContext.getProcessingLevel();
0880: for (int levelIdx = 0; levelIdx < levelData.length; levelIdx++) {
0881: final int level = levelData[levelIdx].getLevelNumber();
0882: if (level < activeLevel) {
0883: break;
0884: }
0885:
0886: final int[] listeners = levelData[levelIdx].getFunctions();
0887: for (int l = 0; l < listeners.length; l++) {
0888: final Expression expression = expressions[listeners[l]];
0889: if (deepTraversing
0890: && expression.isDeepTraversing() == false) {
0891: continue;
0892: }
0893:
0894: final ExpressionRuntime oldRuntime = expression
0895: .getRuntime();
0896: expression.setRuntime(runtime);
0897: final Function e = (Function) expression;
0898: try {
0899: e.reportInitialized(event);
0900: final String name = expression.getName();
0901: if (name != null) {
0902: chEvent.setColumnName(name);
0903: chEvent.setColumnValue(expression.getValue());
0904: masterRow.dataRowChanged(chEvent);
0905: }
0906:
0907: } catch (Exception ex) {
0908: if (Log.isDebugEnabled()) {
0909: Log
0910: .error(
0911: "Failed to fire report-initialized event",
0912: ex);
0913: } else {
0914: Log
0915: .error("Failed to fire report-initialized event: "
0916: + ex);
0917: }
0918: addError(ex);
0919: }
0920:
0921: expression.setRuntime(oldRuntime);
0922: }
0923: }
0924: }
0925:
0926: private void firePageStartedEvent(final ReportEvent event) {
0927: final boolean deepTraversing = event.isDeepTraversing();
0928: final int activeLevel = processingContext.getProcessingLevel();
0929: for (int levelIdx = 0; levelIdx < levelData.length; levelIdx++) {
0930: final int level = levelData[levelIdx].getLevelNumber();
0931: if (level < activeLevel) {
0932: break;
0933: }
0934:
0935: final int[] listeners = levelData[levelIdx]
0936: .getPageEventListeners();
0937: for (int l = 0; l < listeners.length; l++) {
0938: final Expression expression = expressions[listeners[l]];
0939: if (deepTraversing
0940: && expression.isDeepTraversing() == false) {
0941: continue;
0942: }
0943:
0944: final ExpressionRuntime oldRuntime = expression
0945: .getRuntime();
0946: expression.setRuntime(runtime);
0947: final PageEventListener e = (PageEventListener) expression;
0948: try {
0949: e.pageStarted(event);
0950: final String name = expression.getName();
0951: if (name != null) {
0952: chEvent.setColumnName(name);
0953: chEvent.setColumnValue(expression.getValue());
0954: masterRow.dataRowChanged(chEvent);
0955: }
0956:
0957: } catch (Exception ex) {
0958: if (Log.isDebugEnabled()) {
0959: Log.error("Failed to fire page-started event",
0960: ex);
0961: } else {
0962: Log.error("Failed to fire page-started event: "
0963: + ex);
0964: }
0965: addError(ex);
0966: }
0967:
0968: expression.setRuntime(oldRuntime);
0969: }
0970: }
0971: }
0972:
0973: private void firePageFinishedEvent(final ReportEvent event) {
0974: final boolean deepTraversing = event.isDeepTraversing();
0975: final int activeLevel = processingContext.getProcessingLevel();
0976: for (int levelIdx = 0; levelIdx < levelData.length; levelIdx++) {
0977: final int level = levelData[levelIdx].getLevelNumber();
0978: if (level < activeLevel) {
0979: break;
0980: }
0981:
0982: final int[] listeners = levelData[levelIdx]
0983: .getPageEventListeners();
0984: for (int l = 0; l < listeners.length; l++) {
0985: final Expression expression = expressions[listeners[l]];
0986: if (deepTraversing
0987: && expression.isDeepTraversing() == false) {
0988: continue;
0989: }
0990:
0991: final ExpressionRuntime oldRuntime = expression
0992: .getRuntime();
0993: expression.setRuntime(runtime);
0994: final PageEventListener e = (PageEventListener) expression;
0995: try {
0996: e.pageFinished(event);
0997: final String name = expression.getName();
0998: if (name != null) {
0999: chEvent.setColumnName(name);
1000: chEvent.setColumnValue(expression.getValue());
1001: masterRow.dataRowChanged(chEvent);
1002: }
1003:
1004: } catch (Exception ex) {
1005: if (Log.isDebugEnabled()) {
1006: Log.error("Failed to fire page-finished event",
1007: ex);
1008: } else {
1009: Log
1010: .error("Failed to fire page-finished event: "
1011: + ex);
1012: }
1013: addError(ex);
1014: }
1015:
1016: expression.setRuntime(oldRuntime);
1017: }
1018: }
1019: }
1020:
1021: private void firePrepareEvent(final ReportEvent event) {
1022: final boolean deepTraversing = event.isDeepTraversing();
1023: final int activeLevel = processingContext.getProcessingLevel();
1024: for (int levelIdx = 0; levelIdx < levelData.length; levelIdx++) {
1025: final int level = levelData[levelIdx].getLevelNumber();
1026: if (level < activeLevel) {
1027: break;
1028: }
1029:
1030: final int[] listeners = levelData[levelIdx]
1031: .getPrepareEventListeners();
1032: for (int l = 0; l < listeners.length; l++) {
1033: final Expression expression = expressions[listeners[l]];
1034: if (deepTraversing
1035: && expression.isDeepTraversing() == false) {
1036: continue;
1037: }
1038:
1039: final ExpressionRuntime oldRuntime = expression
1040: .getRuntime();
1041: expression.setRuntime(runtime);
1042: final PrepareEventListener e = (PrepareEventListener) expression;
1043: try {
1044: e.prepareEvent(event);
1045: } catch (Exception ex) {
1046: if (Log.isDebugEnabled()) {
1047: Log.error("Failed to fire prepare event", ex);
1048: } else {
1049: Log
1050: .error("Failed to fire prepare event: "
1051: + ex);
1052: }
1053: addError(ex);
1054: }
1055: expression.setRuntime(oldRuntime);
1056: }
1057: }
1058: }
1059:
1060: public ExpressionDataRow derive(final GlobalMasterRow masterRow,
1061: final boolean update) {
1062: try {
1063: return new ExpressionDataRow(masterRow, this , update);
1064: } catch (CloneNotSupportedException e) {
1065: throw new IllegalStateException(
1066: "Cannot clone? Cannot survive!");
1067: }
1068: }
1069:
1070: public boolean isErrorOccured() {
1071: if (errorList == null) {
1072: return false;
1073: }
1074: return errorList.isEmpty() == false;
1075: }
1076:
1077: public void clearErrors() {
1078: if (errorList == null) {
1079: return;
1080: }
1081: this .errorList.clear();
1082: }
1083:
1084: public Exception[] getErrors() {
1085: if (errorList == null) {
1086: return EMPTY_EXCEPTIONS;
1087: }
1088: return (Exception[]) errorList.toArray(new Exception[errorList
1089: .size()]);
1090: }
1091:
1092: private void addError(final Exception e) {
1093: if (errorList == null) {
1094: errorList = new ArrayList();
1095: }
1096: errorList.add(e);
1097: }
1098:
1099: public boolean isValid() {
1100: return levelData != null;
1101: }
1102:
1103: public Expression[] getExpressions() {
1104: return (Expression[]) expressions.clone();
1105: }
1106:
1107: public boolean isPrepareEventListener() {
1108: return prepareEventListener;
1109: }
1110:
1111: /**
1112: * @noinspection ProtectedMemberInFinalClass
1113: */
1114: protected GlobalMasterRow getMasterRow() {
1115: return masterRow;
1116: }
1117:
1118: /**
1119: * @noinspection ProtectedMemberInFinalClass
1120: */
1121: protected ProcessingContext getProcessingContext() {
1122: return processingContext;
1123: }
1124:
1125: }
|