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() ) {
      // for this to work the reporting engine must be able to see our classes, we do this by changing the thread
      // classloader to be the plugin's classloader. see #render()
      String bshCode =
        "Object getValue() { "
          + Const.CR + "  return new " + TransJobDrawable.class.getName() + "(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 );
  }
@Test
  public void createReport() throws Exception {
    LoggingObjectInterface log = mock( LoggingObjectInterface.class );

    AutoDocOptionsInterface options = mock( AutoDocOptionsInterface.class );
    when( options.isIncludingImage() ).thenReturn( Boolean.TRUE );

    KettleReportBuilder builder = new KettleReportBuilder( log, Collections.<ReportSubjectLocation>emptyList(), "", options );
    builder.createReport();

    assertNotNull( builder.getReport() );
    assertNotNull( builder.getReport().getDataFactory() );
    assertNotNull( builder.getReport().getReportHeader() );
    assertNotNull( builder.getReport().getReportFooter() );
    assertNotNull( builder.getReport().getRootGroup() );
    assertNotNull( builder.getReport().getPageDefinition() );
    assertTrue( builder.getReport().getExpressions().size() > 0 );
  }