/*
* 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.function;
import java.util.Locale;
import org.pentaho.reporting.engine.classic.core.event.ReportEvent;
import org.pentaho.reporting.libraries.base.util.ObjectUtilities;
import org.pentaho.reporting.libraries.formatting.FastMessageFormat;
/**
* A report function that combines {@link PageFunction}and {@link PageTotalFunction}. Restrictions for both classes
* apply to this one also.
*
* @author Jörg Schaible
*/
public class PageOfPagesFunction extends PageFunction {
/**
* A internal function delegate that computes the total number of pages.
*/
private PageTotalFunction pageTotalFunction;
/**
* The message format pattern.
*/
private String format;
/**
* An internal cached value holding the last locale used by the function.
*/
private transient Locale lastLocale;
/**
* An internal cached value holding the last page seen by the function.
*/
private transient Integer lastPage;
/**
* An internal cached value holding the last total-pages seen by the function.
*/
private transient Integer lastTotalPage;
/**
* An internal cached value holding the message format object.
*/
private transient FastMessageFormat messageFormat;
/**
* An internal cached value holding the last message that has been computed.
*/
private transient String lastMessage;
/**
* Default Constructor.
*/
public PageOfPagesFunction() {
this.pageTotalFunction = new PageTotalFunction();
this.format = "{0} / {1}";
}
/**
* Constructs a named function.
*
* @param name
* the function name.
*/
public PageOfPagesFunction( final String name ) {
this();
setName( name );
}
/**
* Returns the format used to print the value. The default format is "{0} / {1}".
*
* @return the format string.
* @see java.text.MessageFormat
*/
public String getFormat() {
return format;
}
/**
* Set the format of the value. The format should follow the rules of {@link java.text.MessageFormat}. The first
* parameter is filled with the current page, the second with the total number of pages.
*
* @param format
* the format string.
*/
public void setFormat( final String format ) {
if ( format == null ) {
throw new NullPointerException( "Format must not be null." );
}
this.format = format;
this.messageFormat = null;
}
/**
* Forwards the report event to both the base class and the page-total function delegate.
*
* @param event
* the received report event.
*/
public void reportInitialized( final ReportEvent event ) {
super.reportInitialized( event );
pageTotalFunction.reportInitialized( event );
}
/**
* Forwards the report event to both the base class and the page-total function delegate.
*
* @param event
* the received report event.
*/
public void pageStarted( final ReportEvent event ) {
super.pageStarted( event );
pageTotalFunction.pageStarted( event );
}
/**
* Forwards the report event to both the base class and the page-total function delegate.
*
* @param event
* the received report event.
*/
public void pageFinished( final ReportEvent event ) {
super.pageFinished( event );
pageTotalFunction.pageFinished( event );
}
/**
* Forwards the report event to both the base class and the page-total function delegate.
*
* @param event
* the received report event.
*/
public void groupStarted( final ReportEvent event ) {
super.groupStarted( event );
pageTotalFunction.groupStarted( event );
}
public void groupFinished( final ReportEvent event ) {
super.groupFinished( event );
pageTotalFunction.groupFinished( event );
}
/**
* Receives notification that report generation has completed, the report footer was printed, no more output is done.
* This is a helper event to shut down the output service.
*
* @param event
* The event.
*/
public void reportDone( final ReportEvent event ) {
super.reportDone( event );
pageTotalFunction.reportDone( event );
}
/**
* Return the value of this {@link Function}. The method uses the format definition from the properties and adds the
* current page and the total number of pages as parameter.
*
* @return the formatted value with current page and total number of pages.
*/
public Object getValue() {
final Integer page = (Integer) super.getValue();
final Integer pages = (Integer) pageTotalFunction.getValue();
Locale locale = getResourceBundleFactory().getLocale();
if ( locale == null ) {
locale = Locale.getDefault();
}
if ( messageFormat == null || ObjectUtilities.equal( locale, lastLocale ) == false ) {
this.messageFormat = new FastMessageFormat( getFormat(), locale );
this.lastLocale = locale;
}
if ( lastMessage == null || ObjectUtilities.equal( page, this.lastPage ) == false
|| ObjectUtilities.equal( pages, this.lastTotalPage ) == false ) {
this.lastMessage = messageFormat.format( new Object[] { page, pages } );
this.lastPage = page;
this.lastTotalPage = pages;
}
return lastMessage;
}
/**
* Sets the name of the group that the function acts upon.
*
* @param group
* the group name.
*/
public void setGroup( final String group ) {
super.setGroup( group );
pageTotalFunction.setGroup( group );
}
/**
* Defines the page number where the counting starts.
*
* @param startPage
* the page number of the first page.
*/
public void setStartPage( final int startPage ) {
super.setStartPage( startPage );
pageTotalFunction.setStartPage( startPage );
}
/**
* Defines the defined dependency level. For page functions, this level can be as low as the pagination level.
*
* @param level
* the dependency level.
*/
public void setDependencyLevel( final int level ) {
super.setDependencyLevel( level );
pageTotalFunction.setDependencyLevel( level );
}
/**
* Returns the defined dependency level. For page functions, this level can be as low as the pagination level.
*
* @return the dependency level.
*/
public int getDependencyLevel() {
return pageTotalFunction.getDependencyLevel();
}
/**
* Return a completly separated copy of this function. The copy does no longer share any changeable objects with the
* original function.
*
* @return a copy of this function.
*/
public Expression getInstance() {
final PageOfPagesFunction function = (PageOfPagesFunction) super.getInstance();
function.pageTotalFunction = (PageTotalFunction) pageTotalFunction.getInstance();
return function;
}
/**
* Defines the ExpressionRune used in this expression. The ExpressionRuntime is set before the expression receives
* events or gets evaluated and is unset afterwards. Do not hold references on the runtime or you will create
* memory-leaks.
*
* @param runtime
* the runtime information for the expression
*/
public void setRuntime( final ExpressionRuntime runtime ) {
super.setRuntime( runtime );
pageTotalFunction.setRuntime( runtime );
}
/**
* Creates a copy of the function.
*
* @return the clone.
* @throws CloneNotSupportedException
* if an error occurs.
*/
public Object clone() throws CloneNotSupportedException {
final PageOfPagesFunction function = (PageOfPagesFunction) super.clone();
function.pageTotalFunction = (PageTotalFunction) pageTotalFunction.clone();
return function;
}
}