/*
* 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.layout;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.pentaho.reporting.engine.classic.core.layout.model.BreakMarkerRenderBox;
import org.pentaho.reporting.engine.classic.core.layout.model.FinishedRenderNode;
import org.pentaho.reporting.engine.classic.core.layout.model.LogicalPageBox;
import org.pentaho.reporting.engine.classic.core.layout.model.ParagraphRenderBox;
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.RenderableComplexText;
import org.pentaho.reporting.engine.classic.core.layout.model.RenderableText;
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.TableRowRenderBox;
import org.pentaho.reporting.engine.classic.core.layout.model.table.TableSectionRenderBox;
import org.pentaho.reporting.engine.classic.core.style.BandStyleKeys;
import org.pentaho.reporting.engine.classic.core.style.TableLayout;
@SuppressWarnings( "HardCodedStringLiteral" )
public class ModelPrinter {
public static final ModelPrinter INSTANCE = new ModelPrinter();
private static final Log logger = LogFactory.getLog( ModelPrinter.class );
private static final boolean PRINT_LINEBOX_CONTENTS = false;
private static final boolean PRINT_TABLE_CELL_CONTENTS = true;
public ModelPrinter() {
}
public static RenderBox getRoot( final RenderNode node ) {
RenderBox parent = node.getParent();
RenderBox retval = node.getParent();
while ( parent != null ) {
retval = parent;
parent = parent.getParent();
}
return retval;
}
protected void print( final String s ) {
logger.debug( s );
}
@SuppressWarnings( "UnusedDeclaration" )
public void printParents( RenderNode box ) {
int level = 0;
while ( box != null ) {
if ( box instanceof RenderBox ) {
printBoxDetails( (RenderBox) box, level );
} else {
printNode( box, level );
}
level += 1;
box = box.getParent();
}
}
public void print( final RenderNode box ) {
if ( !isPrintingEnabled() ) {
return;
}
if ( box instanceof RenderBox ) {
printBox( (RenderBox) box, 0 );
} else {
printNode( box, 0 );
}
}
protected boolean isPrintingEnabled() {
return logger.isDebugEnabled();
}
public void print( final RenderBox box ) {
if ( !isPrintingEnabled() ) {
return;
}
printBox( box, 0 );
}
protected void printBox( final RenderBox box, final int level ) {
printBoxDetails( box, level );
final StringBuilder b = new StringBuilder();
for ( int i = 0; i < level; i++ ) {
b.append( " " );
}
print( b.toString() );
if ( box instanceof ParagraphRenderBox ) {
if ( PRINT_LINEBOX_CONTENTS ) {
final ParagraphRenderBox paraBox = (ParagraphRenderBox) box;
print( "---------------- START PARAGRAPH POOL CONTAINER -------------------------------------" );
printBox( paraBox.getPool(), level + 1 );
print( "---------------- FINISH PARAGRAPH POOL CONTAINER -------------------------------------" );
if ( paraBox.isComplexParagraph() ) {
print( "---------------- START PARAGRAPH LINEBOX CONTAINER -------------------------------------" );
printBox( paraBox.getLineboxContainer(), level + 1 );
print( "---------------- FINISH PARAGRAPH LINEBOX CONTAINER -------------------------------------" );
}
}
}
if ( isPrintPageHeader() && box instanceof LogicalPageBox ) {
final LogicalPageBox lbox = (LogicalPageBox) box;
printBox( lbox.getHeaderArea(), level + 1 );
printBox( lbox.getWatermarkArea(), level + 1 );
}
printChilds( box, level );
if ( isPrintPageFooter() && box instanceof LogicalPageBox ) {
final LogicalPageBox lbox = (LogicalPageBox) box;
printBox( lbox.getRepeatFooterArea(), level + 1 );
printBox( lbox.getFooterArea(), level + 1 );
}
}
protected boolean isPrintPageHeader() {
return true;
}
protected boolean isPrintPageFooter() {
return true;
}
private void printBoxDetails( final RenderBox box, final int level ) {
StringBuilder b = new StringBuilder();
for ( int i = 0; i < level; i++ ) {
b.append( " " );
}
b.append( box.getClass().getName() );
b.append( '[' );
b.append( box.getElementType().getClass().getName() );
// b.append(Integer.toHexString(System.identityHashCode(box)));
b.append( ';' );
b.append( box.getName() );
b.append( ']' );
b.append( "={stateKey=" );
b.append( box.getStateKey() );
b.append( ", pinned=" );
b.append( box.getPinned() );
b.append( '}' );
print( b.toString() );
b = new StringBuilder();
for ( int i = 0; i < level; i++ ) {
b.append( " " );
}
b.append( "- layout x=" );
b.append( box.getX() );
b.append( ", y=" );
b.append( box.getY() );
b.append( ", width=" );
b.append( box.getWidth() );
b.append( ", height=" );
b.append( box.getHeight() );
b.append( ", min-chunk-width=" );
b.append( box.getMinimumChunkWidth() );
b.append( ", x2=" );
b.append( box.getX() + box.getWidth() );
b.append( ", y2=" );
b.append( box.getY2() );
b.append( ", y2-overflow=" );
b.append( box.getY() + box.getOverflowAreaHeight() );
print( b.toString() );
b = new StringBuilder();
for ( int i = 0; i < level; i++ ) {
b.append( " " );
}
b.append( "- cached-layout cached-x=" );
b.append( box.getCachedX() );
b.append( ", cached-y=" );
b.append( box.getCachedY() );
b.append( ", cached-width=" );
b.append( box.getCachedWidth() );
b.append( ", cached-height=" );
b.append( box.getCachedHeight() );
b.append( ", content-area-x1=" );
b.append( box.getContentAreaX1() );
b.append( ", content-area-x2=" );
b.append( box.getContentAreaX2() );
print( b.toString() );
b = new StringBuilder();
for ( int i = 0; i < level; i++ ) {
b.append( " " );
}
b.append( "- widow-size=" );
b.append( box.getWidowConstraintSize() );
b.append( "- widow-size-with-keep-together=" );
b.append( box.getWidowConstraintSizeWithKeepTogether() );
b.append( ", orphan-size=" );
b.append( box.getOrphanConstraintSize() );
b.append( ", widows=" );
b.append( box.getStaticBoxLayoutProperties().getWidows() );
b.append( ", orphans=" );
b.append( box.getStaticBoxLayoutProperties().getOrphans() );
b.append( ", keep-together=" );
b.append( box.getStaticBoxLayoutProperties().isAvoidPagebreakInside() );
b.append( ", widow-orphan-opt-out=" );
b.append( box.getStaticBoxLayoutProperties().isWidowOrphanOptOut() );
b.append( ", widows-box=" );
b.append( box.isWidowBox() );
b.append( ", orphan-restrict-finish=" );
b.append( box.getRestrictFinishedClearOut() );
b.append( ", invalid-widow-orphan-node=" );
b.append( box.isInvalidWidowOrphanNode() );
print( b.toString() );
b = new StringBuilder();
for ( int i = 0; i < level; i++ ) {
b.append( " " );
}
b.append( "- boxDefinition=" );
b.append( box.getBoxDefinition() );
print( b.toString() );
b = new StringBuilder();
for ( int i = 0; i < level; i++ ) {
b.append( " " );
}
b.append( "- nodeLayoutProperties=" );
b.append( box.getNodeLayoutProperties() );
print( b.toString() );
b = new StringBuilder();
for ( int i = 0; i < level; i++ ) {
b.append( " " );
}
b.append( "- staticBoxLayoutProperties=" );
b.append( box.getStaticBoxLayoutProperties() );
print( b.toString() );
b = new StringBuilder();
for ( int i = 0; i < level; i++ ) {
b.append( " " );
}
print( b.toString() );
if ( box instanceof LogicalPageBox ) {
final LogicalPageBox pageBox = (LogicalPageBox) box;
b = new StringBuilder();
for ( int i = 0; i < level; i++ ) {
b.append( " " );
}
b.append( "- PageBox={PageOffset=" );
b.append( pageBox.getPageOffset() );
b.append( ", PageHeight=" );
b.append( pageBox.getPageHeight() );
b.append( ", PageEnd=" );
b.append( pageBox.getPageEnd() );
b.append( ", PageWidth=" );
b.append( pageBox.getPageWidth() );
b.append( '}' );
print( b.toString() );
b = new StringBuilder();
for ( int i = 0; i < level; i++ ) {
b.append( " " );
}
b.append( "- PageBreaks={" );
b.append( pageBox.getAllVerticalBreaks() );
b.append( '}' );
print( b.toString() );
}
if ( box instanceof TableRenderBox ) {
final TableRenderBox pageBox = (TableRenderBox) box;
b = new StringBuilder();
for ( int i = 0; i < level; i++ ) {
b.append( " " );
}
b.append( "- Layout: " );
Object styleProperty = pageBox.getStyleSheet().getStyleProperty( BandStyleKeys.TABLE_LAYOUT );
if ( TableLayout.auto.equals( styleProperty ) ) {
b.append( TableLayout.auto );
} else {
b.append( TableLayout.fixed );
}
print( b.toString() );
}
if ( box instanceof TableSectionRenderBox ) {
final TableSectionRenderBox pageBox = (TableSectionRenderBox) box;
b = new StringBuilder();
for ( int i = 0; i < level; i++ ) {
b.append( " " );
}
b.append( "- Role: " );
b.append( pageBox.getDisplayRole() );
print( b.toString() );
}
if ( box instanceof TableRowRenderBox ) {
final TableRowRenderBox pageBox = (TableRowRenderBox) box;
b = new StringBuilder();
for ( int i = 0; i < level; i++ ) {
b.append( " " );
}
b.append( "- Row: " );
b.append( pageBox.getRowIndex() );
print( b.toString() );
}
if ( box instanceof TableCellRenderBox ) {
final TableCellRenderBox pageBox = (TableCellRenderBox) box;
b = new StringBuilder();
for ( int i = 0; i < level; i++ ) {
b.append( " " );
}
b.append( "- Column-Index=" );
b.append( pageBox.getColumnIndex() );
b.append( ", ColSpan=" );
b.append( pageBox.getColSpan() );
b.append( ", RowSpan=" );
b.append( pageBox.getRowSpan() );
print( b.toString() );
}
if ( box instanceof BreakMarkerRenderBox ) {
final BreakMarkerRenderBox pageBox = (BreakMarkerRenderBox) box;
b = new StringBuilder();
for ( int i = 0; i < level; i++ ) {
b.append( " " );
}
b.append( "- InstanceID=" );
b.append( pageBox.getInstanceId() );
b.append( ", validity-range=" );
b.append( pageBox.getValidityRange() );
print( b.toString() );
}
if ( box.isOpen() ) {
b = new StringBuilder();
for ( int i = 0; i < level; i++ ) {
b.append( " " );
}
b.append( "- WARNING: THIS BOX IS STILL OPEN" );
print( b.toString() );
}
if ( box.isFinishedTable() || box.isFinishedPaginate() ) {
b = new StringBuilder();
for ( int i = 0; i < level; i++ ) {
b.append( " " );
}
b.append( "- INFO: THIS BOX IS FINISHED: " );
if ( box.isFinishedTable() ) {
b.append( "- TABLE " );
}
if ( box.isFinishedPaginate() ) {
b.append( "- PAGE " );
}
print( b.toString() );
}
if ( box.isCommited() ) {
b = new StringBuilder();
for ( int i = 0; i < level; i++ ) {
b.append( " " );
}
b.append( "- INFO: THIS BOX IS COMMITED" );
print( b.toString() );
}
}
private void printChilds( final RenderBox box, final int level ) {
if ( PRINT_TABLE_CELL_CONTENTS == false && box instanceof TableCellRenderBox ) {
return;
}
RenderNode childs = box.getFirstChild();
while ( childs != null ) {
if ( childs instanceof RenderBox ) {
printBox( (RenderBox) childs, level + 1 );
} else {
printNode( childs, level + 1 );
}
childs = childs.getNext();
}
}
private void printNode( final RenderNode node, final int level ) {
StringBuilder b = new StringBuilder();
for ( int i = 0; i < level; i++ ) {
b.append( " " );
}
b.append( node.getClass().getName() );
b.append( '[' );
// b.append(Integer.toHexString(System.identityHashCode(node)));
b.append( ']' );
print( b.toString() );
b = new StringBuilder();
for ( int i = 0; i < level; i++ ) {
b.append( " " );
}
b.append( "- layout x=" );
b.append( node.getX() );
b.append( ", y=" );
b.append( node.getY() );
b.append( ", width=" );
b.append( node.getWidth() );
b.append( ", height=" );
b.append( node.getHeight() );
b.append( ", min-chunk-width=" );
b.append( node.getMinimumChunkWidth() );
b.append( ", x2=" );
b.append( node.getX() + node.getWidth() );
b.append( ", y2=" );
b.append( node.getY() + node.getHeight() );
print( b.toString() );
b = new StringBuilder();
for ( int i = 0; i < level; i++ ) {
b.append( " " );
}
b.append( "- cached-layout cached-x=" );
b.append( node.getCachedX() );
b.append( ", cached-y=" );
b.append( node.getCachedY() );
b.append( ", cached-width=" );
b.append( node.getCachedWidth() );
b.append( ", cached-height=" );
b.append( node.getCachedHeight() );
print( b.toString() );
if ( node instanceof FinishedRenderNode ) {
b = new StringBuilder();
for ( int i = 0; i < level; i++ ) {
b.append( " " );
}
final FinishedRenderNode fn = (FinishedRenderNode) node;
b.append( "layouted-y=" );
b.append( fn.getLayoutedY() );
b.append( ", layouted-width=" );
b.append( fn.getLayoutedWidth() );
b.append( ", layouted-height=" );
b.append( fn.getLayoutedHeight() );
b.append( ", orphan-leaf=" );
b.append( fn.isOrphanLeaf() );
print( b.toString() );
}
if ( node instanceof RenderableText ) {
final RenderableText text = (RenderableText) node;
b = new StringBuilder();
for ( int i = 0; i < level; i++ ) {
b.append( " " );
}
b.append( "- text='" );
b.append( text.getRawText() );
b.append( "'" );
print( b.toString() );
}
if ( node instanceof RenderableComplexText ) {
final RenderableComplexText text = (RenderableComplexText) node;
b = new StringBuilder();
for ( int i = 0; i < level; i++ ) {
b.append( " " );
}
b.append( "- complex-text='" );
b.append( text.getRawText() );
b.append( "'" );
print( b.toString() );
}
b = new StringBuilder();
for ( int i = 0; i < level; i++ ) {
b.append( " " );
}
b.append( "- nodeLayoutProperties=" );
b.append( node.getNodeLayoutProperties() );
print( b.toString() );
print( " " );
}
}