/*!
* 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;
}
}