/*!
* 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) 2002-2013 Pentaho Corporation.. All rights reserved.
*/
package org.pentaho.reporting.engine.classic.core.layout.process;
import org.pentaho.reporting.engine.classic.core.ElementAlignment;
import org.pentaho.reporting.engine.classic.core.InvalidReportStateException;
import org.pentaho.reporting.engine.classic.core.layout.model.LayoutNodeTypes;
import org.pentaho.reporting.engine.classic.core.layout.model.LogicalPageBox;
import org.pentaho.reporting.engine.classic.core.layout.model.PageGrid;
import org.pentaho.reporting.engine.classic.core.layout.model.RenderBox;
import org.pentaho.reporting.engine.classic.core.layout.model.RenderNode;
import org.pentaho.reporting.engine.classic.core.layout.model.table.TableCellRenderBox;
import org.pentaho.reporting.engine.classic.core.layout.model.table.TableRenderBox;
import org.pentaho.reporting.engine.classic.core.layout.model.table.columns.TableColumnModel;
import org.pentaho.reporting.engine.classic.core.layout.output.OutputProcessorFeature;
import org.pentaho.reporting.engine.classic.core.layout.output.OutputProcessorMetaData;
import org.pentaho.reporting.engine.classic.core.layout.process.alignment.CenterAlignmentProcessor;
import org.pentaho.reporting.engine.classic.core.layout.process.alignment.JustifyAlignmentProcessor;
import org.pentaho.reporting.engine.classic.core.layout.process.alignment.LeftAlignmentProcessor;
import org.pentaho.reporting.engine.classic.core.layout.process.alignment.RightAlignmentProcessor;
import org.pentaho.reporting.engine.classic.core.layout.process.alignment.TextAlignmentProcessor;
import org.pentaho.reporting.engine.classic.core.layout.process.util.MinorAxisNodeContext;
import org.pentaho.reporting.engine.classic.core.layout.process.util.MinorAxisTableContext;
import org.pentaho.reporting.engine.classic.core.util.geom.StrictGeomUtility;
public abstract class AbstractMinorAxisLayoutStep extends IterateVisualProcessStep {
public static final long OVERFLOW_DUMMY_WIDTH = StrictGeomUtility.toInternalValue( 20000 );
private OutputProcessorMetaData metaData;
private boolean strictLegacyMode;
private PageGrid pageGrid;
private TextAlignmentProcessor centerProcessor;
private TextAlignmentProcessor rightProcessor;
private TextAlignmentProcessor leftProcessor;
private TextAlignmentProcessor justifyProcessor;
private MinorAxisTableContext tableContext;
protected AbstractMinorAxisLayoutStep() {
}
public void initialize( final OutputProcessorMetaData metaData ) {
this.metaData = metaData;
this.strictLegacyMode = metaData.isFeatureSupported( OutputProcessorFeature.STRICT_COMPATIBILITY );
}
protected OutputProcessorMetaData getMetaData() {
return metaData;
}
protected boolean isStrictLegacyMode() {
return strictLegacyMode;
}
protected PageGrid getPageGrid() {
return pageGrid;
}
protected boolean checkCacheValid( final RenderNode node ) {
final RenderNode.CacheState cacheState = node.getCacheState();
if ( cacheState == RenderNode.CacheState.CLEAN ) {
return true;
}
return false;
}
public void compute( final LogicalPageBox root ) {
getEventWatch().start();
getSummaryWatch().start();
try {
pageGrid = root.getPageGrid();
startProcessing( root );
} finally {
pageGrid = null;
getEventWatch().stop();
getSummaryWatch().stop( true );
}
}
protected abstract MinorAxisNodeContext getNodeContext();
/**
* Reuse the processors ..
*
* @param alignment
* @return
*/
protected TextAlignmentProcessor create( final ElementAlignment alignment ) {
if ( ElementAlignment.CENTER.equals( alignment ) ) {
if ( centerProcessor == null ) {
centerProcessor = new CenterAlignmentProcessor();
}
return centerProcessor;
} else if ( ElementAlignment.RIGHT.equals( alignment ) ) {
if ( rightProcessor == null ) {
rightProcessor = new RightAlignmentProcessor();
}
return rightProcessor;
} else if ( ElementAlignment.JUSTIFY.equals( alignment ) ) {
if ( justifyProcessor == null ) {
justifyProcessor = new JustifyAlignmentProcessor();
}
return justifyProcessor;
}
if ( leftProcessor == null ) {
leftProcessor = new LeftAlignmentProcessor();
}
return leftProcessor;
}
protected void startTableContext( final RenderBox box ) {
if ( box.getNodeType() == LayoutNodeTypes.TYPE_BOX_TABLE ) {
if ( isStrictLegacyMode() ) {
throw new InvalidReportStateException( "A report with a legacy mode of pre-4.0 cannot handle table layouts. "
+ "Migrate your report to at least version 4.0." );
}
tableContext = new MinorAxisTableContext( (TableRenderBox) box, tableContext );
}
}
protected boolean finishTableContext( final RenderBox box ) {
if ( box.getNodeType() != LayoutNodeTypes.TYPE_BOX_TABLE ) {
return false;
}
final TableColumnModel columnModel = tableContext.getTable().getColumnModel();
if ( tableContext.isStructureValidated() == false ) {
columnModel.validateSizes( (TableRenderBox) box );
tableContext.setStructureValidated( true );
}
box.setCachedWidth( columnModel.getCachedSize() );
tableContext = tableContext.pop();
return true;
}
public MinorAxisTableContext getTableContext() {
return tableContext;
}
protected long computeCellWidth( final TableCellRenderBox tableCellRenderBox ) {
final MinorAxisTableContext tableContext = getTableContext();
final int columnIndex = tableCellRenderBox.getColumnIndex();
final TableColumnModel columnModel = tableContext.getColumnModel();
final int colSpan = tableCellRenderBox.getColSpan();
if ( colSpan <= 0 ) {
throw new InvalidReportStateException( "A cell cannot have a col-span of zero or less" );
}
long cellSizeFromModel = 0;
for ( int i = 0; i < colSpan; i++ ) {
cellSizeFromModel += columnModel.getEffectiveColumnSize( columnIndex + i );
cellSizeFromModel += columnModel.getBorderSpacing();
}
cellSizeFromModel -= columnModel.getBorderSpacing();
return cellSizeFromModel;
}
protected boolean startTableColLevelBox( final RenderBox box ) {
return false;
}
}