/*! ******************************************************************************
*
* Pentaho Data Integration
*
* Copyright (C) 2002-2013 by Pentaho : http://www.pentaho.com
*
*******************************************************************************
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
package org.pentaho.di.trans.steps.autodoc;
import java.awt.Point;
import java.awt.print.PageFormat;
import java.awt.print.Paper;
import java.util.List;
import com.google.common.annotations.VisibleForTesting;
import org.pentaho.di.core.Const;
import org.pentaho.di.core.logging.LoggingObjectInterface;
import org.pentaho.reporting.engine.classic.core.AttributeNames;
import org.pentaho.reporting.engine.classic.core.Element;
import org.pentaho.reporting.engine.classic.core.GroupDataBody;
import org.pentaho.reporting.engine.classic.core.ItemBand;
import org.pentaho.reporting.engine.classic.core.MasterReport;
import org.pentaho.reporting.engine.classic.core.RelationalGroup;
import org.pentaho.reporting.engine.classic.core.ReportFooter;
import org.pentaho.reporting.engine.classic.core.ReportHeader;
import org.pentaho.reporting.engine.classic.core.SimplePageDefinition;
import org.pentaho.reporting.engine.classic.core.TableDataFactory;
import org.pentaho.reporting.engine.classic.core.elementfactory.ContentElementFactory;
import org.pentaho.reporting.engine.classic.core.elementfactory.LabelElementFactory;
import org.pentaho.reporting.engine.classic.core.elementfactory.TextFieldElementFactory;
import org.pentaho.reporting.engine.classic.core.modules.misc.beanshell.BSHExpression;
import org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.PdfReportUtil;
import org.pentaho.reporting.engine.classic.core.modules.output.table.csv.CSVReportUtil;
import org.pentaho.reporting.engine.classic.core.modules.output.table.html.HtmlReportUtil;
import org.pentaho.reporting.engine.classic.core.modules.output.table.rtf.RTFReportUtil;
import org.pentaho.reporting.engine.classic.core.modules.output.table.xls.ExcelReportUtil;
import org.pentaho.reporting.engine.classic.core.style.BandStyleKeys;
import org.pentaho.reporting.engine.classic.core.style.TextStyleKeys;
public class KettleReportBuilder {
public enum OutputType {
PDF, HTML, DOC, XLS, CSV, METADATA
}
private static final float DEF_FONT_HEIGHT = 12f;
private static final int DEF_LABEL_WIDTH = 120;
private static final int DEF_TEXT_WIDTH = 630;
private static final boolean DEF_LABEL_UNDERLINE = false;
private static final boolean DEF_LABEL_BOLD = false;
private static final boolean DEF_LABEL_ITALIC = true;
private List<ReportSubjectLocation> filenames;
private MasterReport report;
private String targetFilename;
private AutoDocOptionsInterface options;
private LoggingObjectInterface parentObject;
public KettleReportBuilder( LoggingObjectInterface parentObject, List<ReportSubjectLocation> locations,
String targetFilename, AutoDocOptionsInterface options ) {
this.parentObject = parentObject;
this.filenames = locations;
this.targetFilename = targetFilename;
this.options = options;
}
private static int createTextField( ItemBand details,
String labelText, String fieldName,
int labelWidth, int textWidth,
int pagePosition, float fontHeight,
boolean labelUnderline, boolean labelBold, boolean labelItalic ) {
ItemBand rowBand = new ItemBand();
rowBand.setLayout( BandStyleKeys.LAYOUT_ROW );
LabelElementFactory labelElementFactory = new LabelElementFactory();
labelElementFactory.setText( labelText );
labelElementFactory.setAbsolutePosition( new Point( 0, pagePosition ) );
labelElementFactory.setMinimumWidth( (float) labelWidth );
labelElementFactory.setMinimumHeight( fontHeight );
labelElementFactory.setUnderline( labelUnderline );
labelElementFactory.setBold( labelBold );
labelElementFactory.setItalic( labelItalic );
labelElementFactory.setDynamicHeight( true );
Element label = labelElementFactory.createElement();
rowBand.addElement( label );
TextFieldElementFactory textFactory = new TextFieldElementFactory();
textFactory.setFieldname( fieldName );
textFactory.setAbsolutePosition( new Point( labelWidth, pagePosition ) );
textFactory.setMinimumWidth( (float) textWidth );
textFactory.setMinimumHeight( fontHeight );
textFactory.setOverflowY( false );
textFactory.setDynamicHeight( true );
Element element = textFactory.createElement();
element.setDynamicContent( true );
rowBand.addElement( element );
details.addElement( rowBand );
return (int) ( pagePosition + fontHeight );
}
private static int createTextField( ItemBand details, String labelText, String fieldName, int pagePosition ) {
return createTextField( details, labelText, fieldName, DEF_LABEL_WIDTH, DEF_TEXT_WIDTH, pagePosition,
DEF_FONT_HEIGHT, DEF_LABEL_UNDERLINE, DEF_LABEL_BOLD, DEF_LABEL_ITALIC );
}
public void createReport() throws Exception {
// Create a new report
//
report = new MasterReport();
// Define where which transformation and step to read from, explain it to the reporting engine
//
KettleFileTableModel transMetaTableModel = new KettleFileTableModel( parentObject, filenames );
TableDataFactory dataFactory = new TableDataFactory( "default", transMetaTableModel );
// Give the data to the report at runtime!
//
report.setDataFactory( dataFactory );
// Add a report header and footer
//
ReportHeader reportHeader = new ReportHeader();
report.setReportHeader( reportHeader );
ReportFooter reportFooter = new ReportFooter();
report.setReportFooter( reportFooter );
// Now we need to define an area on which we can draw report elements, called groups and bands...
//
RelationalGroup group = new RelationalGroup();
group.addField( "filename" );
GroupDataBody groupData = new GroupDataBody();
ItemBand itemBand = new ItemBand();
itemBand.setVisible( true );
itemBand.setLayout( BandStyleKeys.LAYOUT_AUTO );
groupData.setItemBand( itemBand );
group.setBody( groupData );
report.setRootGroup( group );
// Put a title at the top of the report
//
/*
* LabelElementFactory labelElementFactory = new LabelElementFactory();
* labelElementFactory.setText("Kettle documentation"); labelElementFactory.setMinimumWidth(500f);
* labelElementFactory.setMinimumHeight(20f); labelElementFactory.setUnderline(true);
* labelElementFactory.setBold(true); Element label = labelElementFactory.createElement();
*
* // Add the label to the header... // reportHeader.addElement(label);
*/
int pagePosition = 0;
// Set the header to bold...
//
reportHeader.getStyle().setStyleProperty( TextStyleKeys.BOLD, true );
// Now add the filename to the report
//
pagePosition = createTextField( itemBand, "Filename: ", "filename", pagePosition );
// The name of the transformation
//
if ( options.isIncludingName() ) {
pagePosition = createTextField( itemBand, "Name: ", "name", pagePosition );
}
// The description of the transformation...
//
if ( options.isIncludingDescription() ) {
pagePosition = createTextField( itemBand, "Description: ", "description", pagePosition );
}
// The description of the transformation...
//
if ( options.isIncludingExtendedDescription() ) {
pagePosition = createTextField( itemBand, "Long description: ", "extended_description", pagePosition );
}
// Include a line with logging information
//
if ( options.isIncludingLoggingConfiguration() ) {
pagePosition = createTextField( itemBand, "Logging: ", "logging", pagePosition );
}
// Include a line with the creation date and user
//
if ( options.isIncludingCreated() ) {
pagePosition = createTextField( itemBand, "Creation: ", "creation", pagePosition );
}
// Include a line with the modification date and user
//
if ( options.isIncludingModified() ) {
pagePosition = createTextField( itemBand, "Modification: ", "modification", pagePosition );
}
// The last execution result
//
if ( options.isIncludingLastExecutionResult() ) {
pagePosition = createTextField( itemBand, "Last execution result: : ", "last_exec_result", pagePosition );
}
// Optionally include an image of the transformation...
//
if ( options.isIncludingImage() ) {
String packName = KettleReportBuilder.class.getPackage().getName();
String bshCode =
"Object getValue() { "
+ Const.CR + " return new " + packName + ".TransJobDrawable(dataRow, "
+ ( options.getOutputType() == OutputType.PDF ? "true" : "false" ) + ");" + Const.CR + "}";
BSHExpression bshExpression = new BSHExpression();
bshExpression.setExpression( bshCode );
bshExpression.setName( "getImage" );
report.addExpression( bshExpression );
ContentElementFactory contentElementFactory = new ContentElementFactory();
contentElementFactory.setName( "image" );
contentElementFactory.setAbsolutePosition( new Point( 0, pagePosition ) );
contentElementFactory.setMinimumWidth( 750f );
contentElementFactory.setMaximumWidth( 750f );
contentElementFactory.setMinimumHeight( 400f );
contentElementFactory.setMaximumHeight( 750f );
contentElementFactory.setScale( true );
contentElementFactory.setDynamicHeight( true );
Element imageElement = contentElementFactory.createElement();
imageElement
.setAttributeExpression( AttributeNames.Core.NAMESPACE, AttributeNames.Core.VALUE, bshExpression );
imageElement.setAttribute( AttributeNames.Core.NAMESPACE, AttributeNames.Core.IMAGE_ENCODING_QUALITY, "9" );
imageElement.setAttribute( AttributeNames.Core.NAMESPACE, AttributeNames.Core.IMAGE_ENCODING_TYPE, "PNG" );
ItemBand imageBand = new ItemBand();
imageBand.setLayout( BandStyleKeys.LAYOUT_ROW );
imageBand.addElement( imageElement );
itemBand.addElement( imageBand );
}
Paper a4Paper = new Paper();
double paperWidth = 8.26;
double paperHeight = 11.69;
a4Paper.setSize( paperWidth * 72.0, paperHeight * 72.0 );
/*
* set the margins respectively the imageable area
*/
double leftMargin = 0.78; /* should be about 2cm */
double rightMargin = 0.78;
double topMargin = 0.08; // this is a very small topMargin
double bottomMargin = 0.78;
a4Paper.setImageableArea(
leftMargin * 72.0, topMargin * 72.0, ( paperWidth - leftMargin - rightMargin ) * 72.0, ( paperHeight
- topMargin - bottomMargin ) * 72.0 );
/*
* create a PageFormat and associate the Paper with it.
*/
PageFormat pageFormat = new PageFormat();
pageFormat.setOrientation( PageFormat.LANDSCAPE );
pageFormat.setPaper( a4Paper );
SimplePageDefinition pageDefinition = new SimplePageDefinition( pageFormat );
report.setPageDefinition( pageDefinition );
}
public void render() throws Exception {
createReport();
switch ( options.getOutputType() ) {
case PDF:
PdfReportUtil.createPDF( report, targetFilename );
break;
case DOC:
RTFReportUtil.createRTF( report, targetFilename );
break;
case XLS:
ExcelReportUtil.createXLS( report, targetFilename );
break;
case HTML:
HtmlReportUtil.createDirectoryHTML( report, targetFilename );
break;
case CSV:
CSVReportUtil.createCSV( report, targetFilename );
break;
default:
break;
}
}
@VisibleForTesting
MasterReport getReport() {
return report;
}
}