/*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* Copyright (c) 2001 - 2013 Object Refinery Ltd, Pentaho Corporation and Contributors.. All rights reserved.
*/
package org.pentaho.reporting.engine.classic.core.event;
import org.pentaho.reporting.engine.classic.core.DataRow;
import org.pentaho.reporting.engine.classic.core.ReportDefinition;
import org.pentaho.reporting.engine.classic.core.states.ReportState;
import java.util.EventObject;
/**
* Represents a report event.
* <p/>
* Includes information which {@link org.pentaho.reporting.engine.classic.core.states.ReportState} generated the event.
*
* @author Thomas Morgner
*/
public class ReportEvent extends EventObject {
/**
* The event type constant, that the report initialize event is invoked.
*/
public static final int REPORT_INITIALIZED = 0x01;
/**
* The event type constant, that the page start event is invoked.
*/
public static final int PAGE_STARTED = 0x02;
/**
* The event type constant, that the report start event is invoked.
*/
public static final int REPORT_STARTED = 0x04;
/**
* The event type constant, that a group start event is invoked.
*/
public static final int GROUP_STARTED = 0x08;
/**
* The event type constant, that the items started event is invoked.
*/
public static final int ITEMS_STARTED = 0x10;
/**
* The event type constant, that the items advanced event is invoked.
*/
public static final int ITEMS_ADVANCED = 0x20;
/**
* The event type constant, that the items finished event is invoked.
*/
public static final int ITEMS_FINISHED = 0x40;
/**
* The event type constant, that a group finished event is invoked.
*/
public static final int GROUP_FINISHED = 0x80;
/**
* The event type constant, that the report finished event is invoked.
*/
public static final int REPORT_FINISHED = 0x100;
/**
* The event type constant, that the report done event is invoked.
*/
public static final int REPORT_DONE = 0x200;
/**
* The event type constant, that the page finished event is invoked.
*/
public static final int PAGE_FINISHED = 0x400;
/**
* This event is fired when a summary row is going to be printed. This is a crosstab only event, and happens after the
* group-finished event. Crosstab-aware functions must now select the result for the given group.
*/
public static final int SUMMARY_ROW = 0x800;
public static final int SUMMARY_ROW_START = 0x1800;
public static final int SUMMARY_ROW_END = 0x2800;
/**
* This is a layout-helper event. It is only passed down to layouter functions. This event is fired before a
* group-finished event is fired and helps the layouter to close the group-body so that keep-together and widows can
* compute their state properly.
*/
public static final int GROUP_BODY_FINISHED = 0x8000;
private static final int RESERVED_BLOCK_1 = 0xC000;
/**
* Crosstab marker flag. This marks events that are part of a crosstab processing.
*/
public static final int CROSSTABBING = 0x10000;
public static final int CROSSTABBING_TABLE = 0x110000;
public static final int CROSSTABBING_OTHER = 0x210000;
public static final int CROSSTABBING_ROW = 0x410000;
public static final int CROSSTABBING_COL = 0x810000;
/**
* A flag that marks the given event as a deep-traversing event. This flag is an indicator, that the event did not
* originate in this report, so it propably came from a parent or child report.
*/
public static final int DEEP_TRAVERSING_EVENT = 0x4000000;
public static final int NO_PARENT_PASSING_EVENT = 0x8000000;
public static final int ARTIFICIAL_EVENT_CODE = 0x80000000;
/**
* The event type for this event.
*/
private int type;
/**
* The state that generated the event in the first place. For master reports this is the same as the event source, for
* master-reports receiving events from a sub-report, this is the subreport's report state.
*/
private ReportState originatingState;
/**
* Creates a new <code>ReportEvent</code>.
*
* @param state
* the current state of the processed report (<code>null</code> not permmitted).
* @param type
* the event type for this event object.
*/
public ReportEvent( final ReportState state, final int type ) {
super( state );
if ( state == null ) {
throw new NullPointerException( "ReportEvent(ReportState) : null not permitted." );
}
if ( type <= 0 ) {
throw new IllegalArgumentException( "This is not a valid EventType: " + type );
}
this.type = type;
this.originatingState = state;
}
/**
* Creates a new <code>ReportEvent</code>.
*
* @param state
* the current state of the processed report (<code>null</code> not permmitted).
* @param originatingState
* the original state that generated the event.
* @param type
* the event type for this event object.
*/
public ReportEvent( final ReportState state, final ReportState originatingState, final int type ) {
this( state, type );
if ( originatingState == null ) {
throw new NullPointerException( "Originating state can never be null." );
}
this.originatingState = originatingState;
}
/**
* Returns the event type. The type is made up of a combination of several flags.
*
* @return the event type.
*/
public int getType() {
return type;
}
/**
* Returns the <code>ReportState</code>, which is the source of the event.
*
* @return the state (never <code>null</code>).
*/
public ReportState getState() {
return (ReportState) getSource();
}
/**
* Returns the originating state. The originating state is the state, that generated the event in the first place. For
* master reports this is the same as the event source, for master-reports receiving events from a sub-report, this is
* the subreport's report state.
*
* @return the originating state.
*/
public ReportState getOriginatingState() {
return originatingState;
}
/**
* Returns the report that generated the event.
* <P>
* This is a convenience method that extracts the report from the report state.
*
* @return the report.
*/
public ReportDefinition getReport() {
return getState().getReport();
}
/**
* Returns the currently assigned dataRow for this event.
* <p/>
* The {@link DataRow} is used to access the fields of the
* {@link org.pentaho.reporting.engine.classic.core.filter .DataSource} and other functions and expressions within the
* current row of the report.
*
* @return the data row.
*/
public DataRow getDataRow() {
return getState().getDataRow();
}
/**
* Returns the current function level.
*
* @return the function level.
*/
public int getLevel() {
return getState().getLevel();
}
/**
* Checks whether the deep-traversing flag is set. An event is deep-traversing, if it did not originate in the current
* report.
*
* @return true, if this is a deep-traversing element, false otherwise.
*/
public boolean isDeepTraversing() {
return ( type & ReportEvent.DEEP_TRAVERSING_EVENT ) == ReportEvent.DEEP_TRAVERSING_EVENT;
}
/**
* @noinspection HardCodedStringLiteral
*/
public static String translateStateCode( final int code ) {
final StringBuffer b = new StringBuffer();
if ( ( code & REPORT_INITIALIZED ) == REPORT_INITIALIZED ) {
b.append( "Report-Init" );
} else if ( ( code & PAGE_STARTED ) == PAGE_STARTED ) {
b.append( "Page-Start" );
final int i = code & ~PAGE_STARTED;
if ( i != 0 ) {
b.append( "[" );
b.append( translateStateCode( i ) );
b.append( "]" );
}
}
if ( ( code & REPORT_STARTED ) == REPORT_STARTED ) {
b.append( "Report-Start" );
}
if ( ( code & GROUP_STARTED ) == GROUP_STARTED ) {
b.append( "Group-Start" );
}
if ( ( code & ITEMS_STARTED ) == ITEMS_STARTED ) {
b.append( "Items-Start" );
}
if ( ( code & ITEMS_ADVANCED ) == ITEMS_ADVANCED ) {
b.append( "Items-Advanced" );
}
if ( ( code & ITEMS_FINISHED ) == ITEMS_FINISHED ) {
b.append( "Items-Finished" );
}
if ( ( code & GROUP_BODY_FINISHED ) == GROUP_BODY_FINISHED ) {
b.append( "Group-Body-Finished" );
}
if ( ( code & GROUP_FINISHED ) == GROUP_FINISHED ) {
b.append( "Group-Finished" );
}
if ( ( code & REPORT_FINISHED ) == REPORT_FINISHED ) {
b.append( "Report-Finished" );
}
if ( ( code & REPORT_DONE ) == REPORT_DONE ) {
b.append( "Report-Done" );
}
if ( ( code & PAGE_FINISHED ) == PAGE_FINISHED ) {
b.append( "Page-Finished" );
}
if ( ( code & SUMMARY_ROW ) == SUMMARY_ROW ) {
b.append( "Summary Row" );
if ( ( code & SUMMARY_ROW_START ) == SUMMARY_ROW_START ) {
b.append( " [Start]" );
}
if ( ( code & SUMMARY_ROW_END ) == SUMMARY_ROW_END ) {
b.append( " [End]" );
}
}
if ( ( code & CROSSTABBING ) == CROSSTABBING ) {
b.append( " Crosstab" );
if ( ( code & CROSSTABBING_TABLE ) == CROSSTABBING_TABLE ) {
b.append( ":Table" );
}
if ( ( code & CROSSTABBING_OTHER ) == CROSSTABBING_OTHER ) {
b.append( ":Other" );
}
if ( ( code & CROSSTABBING_ROW ) == CROSSTABBING_ROW ) {
b.append( ":Row" );
}
if ( ( code & CROSSTABBING_COL ) == CROSSTABBING_COL ) {
b.append( ":Col" );
}
}
if ( ( code & ( DEEP_TRAVERSING_EVENT | NO_PARENT_PASSING_EVENT | ARTIFICIAL_EVENT_CODE ) ) != 0 ) {
b.append( " (" );
if ( ( code & DEEP_TRAVERSING_EVENT ) == DEEP_TRAVERSING_EVENT ) {
b.append( " DeepTraverse" );
}
if ( ( code & NO_PARENT_PASSING_EVENT ) == NO_PARENT_PASSING_EVENT ) {
b.append( " NoParent" );
}
if ( ( code & ARTIFICIAL_EVENT_CODE ) == ARTIFICIAL_EVENT_CODE ) {
b.append( " Artificial" );
}
b.append( " )" );
}
return b.toString();
}
}