/*! ******************************************************************************
*
* Pentaho Data Integration
*
* Copyright (C) 2002-2017 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.ui.trans.steps.pentahoreporting;
import java.math.BigDecimal;
import java.util.Date;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.pentaho.di.core.Const;
import org.pentaho.di.core.util.Utils;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.core.row.RowMeta;
import org.pentaho.di.core.row.RowMetaInterface;
import org.pentaho.di.core.row.ValueMetaInterface;
import org.pentaho.di.core.row.value.ValueMetaString;
import org.pentaho.di.i18n.BaseMessages;
import org.pentaho.di.trans.TransMeta;
import org.pentaho.di.trans.step.BaseStepMeta;
import org.pentaho.di.trans.step.StepDialogInterface;
import org.pentaho.di.trans.steps.pentahoreporting.PentahoReportingOutput;
import org.pentaho.di.trans.steps.pentahoreporting.PentahoReportingOutputMeta;
import org.pentaho.di.trans.steps.pentahoreporting.PentahoReportingOutputMeta.ProcessorType;
import org.pentaho.di.ui.core.dialog.ErrorDialog;
import org.pentaho.di.ui.core.widget.ColumnInfo;
import org.pentaho.di.ui.core.widget.TableView;
import org.pentaho.di.ui.trans.step.BaseStepDialog;
import org.pentaho.di.ui.trans.step.TableItemInsertListener;
import org.pentaho.reporting.engine.classic.core.MasterReport;
import org.pentaho.reporting.engine.classic.core.parameters.ParameterDefinitionEntry;
import org.pentaho.reporting.engine.classic.core.parameters.ReportParameterDefinition;
public class PentahoReportingOutputDialog extends BaseStepDialog implements StepDialogInterface {
private static Class<?> PKG = PentahoReportingOutput.class; // for i18n purposes, needed by Translator2!!
private Label wlInput;
private Combo wInput;
private Label wlOutput;
private Combo wOutput;
private Label wlProcessor;
private List wProcessor;
private PentahoReportingOutputMeta input;
private TableView wFields;
private Label wlParentFolder;
private Button wParentFolder;
public PentahoReportingOutputDialog( Shell parent, Object in, TransMeta transMeta, String sname ) {
super( parent, (BaseStepMeta) in, transMeta, sname );
input = (PentahoReportingOutputMeta) in;
this.transMeta = transMeta;
if ( sname != null ) {
stepname = sname;
} else {
stepname = BaseMessages.getString( PKG, "PentahoReportingOutputDialog.DefaultStepName" );
}
}
@Override
public String open() {
Shell parent = getParent();
Display display = parent.getDisplay();
shell = new Shell( parent, SWT.DIALOG_TRIM | SWT.RESIZE | SWT.MAX | SWT.MIN );
props.setLook( shell );
setShellImage( shell, input );
ModifyListener lsMod = new ModifyListener() {
@Override
public void modifyText( ModifyEvent e ) {
input.setChanged();
}
};
SelectionListener selMod = new SelectionAdapter( ) {
@Override
public void widgetSelected( SelectionEvent e ) {
input.setChanged();
}
};
changed = input.hasChanged();
FormLayout formLayout = new FormLayout();
formLayout.marginWidth = Const.FORM_MARGIN;
formLayout.marginHeight = Const.FORM_MARGIN;
shell.setLayout( formLayout );
shell.setText( BaseMessages.getString( PKG, "PentahoReportingOutputDialog.Shell.Text" ) );
int middle = props.getMiddlePct();
int margin = Const.MARGIN;
// Stepname line
wlStepname = new Label( shell, SWT.RIGHT );
wlStepname.setText( BaseMessages.getString( PKG, "PentahoReportingOutputDialog.Stepname.Label" ) );
props.setLook( wlStepname );
fdlStepname = new FormData();
fdlStepname.left = new FormAttachment( 0, 0 );
fdlStepname.top = new FormAttachment( 0, margin );
fdlStepname.right = new FormAttachment( middle, -margin );
wlStepname.setLayoutData( fdlStepname );
wStepname = new Text( shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER );
wStepname.setText( stepname );
props.setLook( wStepname );
wStepname.addModifyListener( lsMod );
fdStepname = new FormData();
fdStepname.left = new FormAttachment( middle, 0 );
fdStepname.top = new FormAttachment( 0, margin );
fdStepname.right = new FormAttachment( 100, 0 );
wStepname.setLayoutData( fdStepname );
// input file line (report definition)
wlInput = new Label( shell, SWT.RIGHT );
wlInput.setText( BaseMessages.getString( PKG, "PentahoReportingOutputDialog.InputFilename.Label" ) );
props.setLook( wlInput );
FormData fdlInput = new FormData();
fdlInput.left = new FormAttachment( 0, 0 );
fdlInput.top = new FormAttachment( wStepname, margin + 5 );
fdlInput.right = new FormAttachment( middle, -margin );
wlInput.setLayoutData( fdlInput );
wInput = new Combo( shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER );
props.setLook( wInput );
wInput.addModifyListener( lsMod );
FormData fdInput = new FormData();
fdInput.left = new FormAttachment( middle, 0 );
fdInput.top = new FormAttachment( wStepname, margin + 5 );
fdInput.right = new FormAttachment( 100, 0 );
wInput.setLayoutData( fdInput );
String[] fieldNames = new String[] {};
try {
fieldNames = Const.sortStrings( transMeta.getPrevStepFields( stepMeta ).getFieldNames() );
} catch ( KettleException e ) {
log.logError( "Unexpected error getting fields from previous steps...", e );
}
wInput.setItems( fieldNames );
// output file line
wlOutput = new Label( shell, SWT.RIGHT );
wlOutput.setText( BaseMessages.getString( PKG, "PentahoReportingOutputDialog.OutputFilename.Label" ) );
props.setLook( wlOutput );
FormData fdlOutput = new FormData();
fdlOutput.left = new FormAttachment( 0, 0 );
fdlOutput.top = new FormAttachment( wInput, margin + 5 );
fdlOutput.right = new FormAttachment( middle, -margin );
wlOutput.setLayoutData( fdlOutput );
wOutput = new Combo( shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER );
props.setLook( wOutput );
wOutput.addModifyListener( lsMod );
FormData fdOutput = new FormData();
fdOutput.left = new FormAttachment( middle, 0 );
fdOutput.top = new FormAttachment( wInput, margin + 5 );
fdOutput.right = new FormAttachment( 100, 0 );
wOutput.setLayoutData( fdOutput );
wOutput.setItems( fieldNames );
//ParentFolder
wlParentFolder = new Label( shell, SWT.RIGHT );
wlParentFolder.setText( BaseMessages.getString( PKG, "PentahoReportingOutputDialog.ParentFolder.Label" ) );
props.setLook( wlParentFolder );
FormData fdlParentFolder = new FormData();
fdlParentFolder.left = new FormAttachment( 10, 10 );
fdlParentFolder.top = new FormAttachment( wlOutput, margin + 15 );
fdlParentFolder.right = new FormAttachment( middle, -margin );
wlParentFolder.setLayoutData( fdlParentFolder );
wParentFolder = new Button( shell, SWT.CHECK );
props.setLook( wParentFolder );
wParentFolder.addSelectionListener( selMod );
FormData fdParentFolder = new FormData();
fdParentFolder.left = new FormAttachment( middle, 10 );
fdParentFolder.top = new FormAttachment( wlOutput, margin + 15 );
fdParentFolder.right = new FormAttachment( 100, 10 );
wParentFolder.setLayoutData( fdParentFolder );
wParentFolder.setSelection( input.getCreateParentfolder() );
// Fields
ColumnInfo[] colinf =
new ColumnInfo[] {
new ColumnInfo(
BaseMessages.getString( PKG, "PentahoReportingOutput.Column.ParameterName" ),
ColumnInfo.COLUMN_TYPE_TEXT, false ),
new ColumnInfo(
BaseMessages.getString( PKG, "PentahoReportingOutput.Column.FieldName" ),
ColumnInfo.COLUMN_TYPE_CCOMBO, fieldNames, true ), };
wFields =
new TableView( transMeta, shell, SWT.FULL_SELECTION | SWT.MULTI | SWT.BORDER, colinf, 1, lsMod, props );
FormData fdFields = new FormData();
fdFields.top = new FormAttachment( wParentFolder, margin * 2 );
fdFields.bottom = new FormAttachment( wParentFolder, 250 );
fdFields.left = new FormAttachment( 0, 0 );
fdFields.right = new FormAttachment( 100, 0 );
wFields.setLayoutData( fdFields );
// output types
//
wlProcessor = new Label( shell, SWT.RIGHT );
wlProcessor.setText( BaseMessages.getString( PKG, "PentahoReportingOutputDialog.Processor.Label" ) );
props.setLook( wlProcessor );
FormData fdlProcessor = new FormData();
fdlProcessor.left = new FormAttachment( 0, 0 );
fdlProcessor.top = new FormAttachment( wFields, margin + 5 );
fdlProcessor.right = new FormAttachment( middle, -margin );
wlProcessor.setLayoutData( fdlProcessor );
wProcessor = new List( shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER );
props.setLook( wProcessor );
FormData fdProcessor = new FormData();
fdProcessor.left = new FormAttachment( middle, 0 );
fdProcessor.top = new FormAttachment( wFields, margin + 5 );
fdProcessor.right = new FormAttachment( 100, 0 );
wProcessor.setLayoutData( fdProcessor );
wProcessor.setItems( ProcessorType.getDescriptions() );
wProcessor.addListener( SWT.Selection, new Listener() {
@Override
public void handleEvent( Event e ) {
input.setChanged();
}
} );
wOK = new Button( shell, SWT.PUSH );
wOK.setText( BaseMessages.getString( "System.Button.OK" ) );
wCancel = new Button( shell, SWT.PUSH );
wCancel.setText( BaseMessages.getString( "System.Button.Cancel" ) );
wGet = new Button( shell, SWT.PUSH );
wGet.setText( BaseMessages.getString( PKG, "PentahoReportingOutputDialog.Button.GetParameters" ) );
setButtonPositions( new Button[] { wOK, wGet, wCancel }, margin, wProcessor );
// Add listeners
wOK.addListener( SWT.Selection, new Listener() {
@Override
public void handleEvent( Event e ) {
ok();
}
} );
wCancel.addListener( SWT.Selection, new Listener() {
@Override
public void handleEvent( Event e ) {
cancel();
}
} );
wGet.addListener( SWT.Selection, new Listener() {
@Override
public void handleEvent( Event e ) {
get();
}
} );
lsDef = new SelectionAdapter() {
@Override
public void widgetDefaultSelected( SelectionEvent e ) {
ok();
}
};
wStepname.addSelectionListener( lsDef );
wInput.addSelectionListener( lsDef );
wOutput.addSelectionListener( lsDef );
wParentFolder.addSelectionListener( lsDef );
// Detect X or ALT-F4 or something that kills this window...
shell.addShellListener( new ShellAdapter() {
@Override
public void shellClosed( ShellEvent e ) {
cancel();
}
} );
// Set the shell size, based upon previous time...
setSize();
getData();
input.setChanged( changed );
shell.open();
while ( !shell.isDisposed() ) {
if ( !display.readAndDispatch() ) {
display.sleep();
}
}
return stepname;
}
/**
* Copy information from the meta-data input to the dialog fields.
*/
public void getData() {
wInput.setText( Const.NVL( input.getInputFileField(), "" ) );
wOutput.setText( Const.NVL( input.getOutputFileField(), "" ) );
for ( String name : input.getParameterFieldMap().keySet() ) {
String field = input.getParameterFieldMap().get( name );
TableItem item = new TableItem( wFields.table, SWT.NONE );
item.setText( 1, name );
item.setText( 2, field );
}
wFields.removeEmptyRows();
wFields.setRowNums();
wFields.optWidth( true );
wProcessor.select( input.getOutputProcessorType().ordinal() );
wStepname.selectAll();
wStepname.setFocus();
wParentFolder.setSelection( input.getCreateParentfolder() );
}
private void cancel() {
stepname = null;
input.setChanged( changed );
dispose();
}
private void ok() {
stepname = wStepname.getText(); // return value
input.getParameterFieldMap().clear();
for ( int i = 0; i < wFields.nrNonEmpty(); i++ ) {
TableItem item = wFields.getNonEmpty( i );
String name = item.getText( 1 );
String field = item.getText( 2 );
if ( !Utils.isEmpty( name ) && !Utils.isEmpty( field ) ) {
input.getParameterFieldMap().put( name, field );
}
}
input.setInputFileField( wInput.getText() );
input.setOutputFileField( wOutput.getText() );
input.setOutputProcessorType( ProcessorType.values()[wProcessor.getSelectionIndex()] );
input.setCreateParentfolder( wParentFolder.getSelection() );
dispose();
}
private static String lastFilename;
private void get() {
Cursor busy = new Cursor( shell.getDisplay(), SWT.CURSOR_WAIT );
// See if we need to boot the reporting engine. Since this takes time we do it in the background...
//
Runnable runnable = new Runnable() {
@Override
public void run() {
PentahoReportingOutput.performPentahoReportingBoot( log, input.getClass() );
}
};
Thread thread = new Thread( runnable );
thread.start();
try {
// Browse for a PRPT...
//
FileDialog dialog = new FileDialog( shell, SWT.OPEN );
dialog.setText( BaseMessages.getString( PKG, "PentahoReportingOutputDialog.ExtractParameters.FileDialog" ) );
dialog.setFilterExtensions( new String[] { "*.prpt;*.PRPT", "*" } );
if ( lastFilename != null ) {
dialog.setFileName( lastFilename );
}
dialog.setFilterNames( new String[] {
BaseMessages.getString( PKG, "PentahoReportingOutputDialog.PentahoReportingFiles" ),
BaseMessages.getString( PKG, "System.FileType.AllFiles" ), } );
if ( dialog.open() == null ) {
return;
}
thread.join();
String sourceFilename =
dialog.getFilterPath() + System.getProperty( "file.separator" ) + dialog.getFileName();
lastFilename = sourceFilename;
shell.setCursor( busy );
// Load the master report...
//
MasterReport report = PentahoReportingOutput.loadMasterReport( sourceFilename );
// Extract the definitions...
//
ReportParameterDefinition definition = report.getParameterDefinition();
RowMetaInterface r = new RowMeta();
for ( int i = 0; i < definition.getParameterCount(); i++ ) {
ParameterDefinitionEntry entry = definition.getParameterDefinition( i );
ValueMetaInterface valueMeta = new ValueMetaString( entry.getName() );
valueMeta.setComments( getParameterDefinitionEntryTypeDescription( entry ) );
r.addValueMeta( valueMeta );
}
shell.setCursor( null );
BaseStepDialog.getFieldsFromPrevious(
r, wFields, 1, new int[] { 1 }, new int[] {}, -1, -1, new TableItemInsertListener() {
@Override
public boolean tableItemInserted( TableItem item, ValueMetaInterface valueMeta ) {
item.setText( 2, valueMeta.getComments() );
return true;
}
} );
} catch ( Exception e ) {
shell.setCursor( null );
new ErrorDialog( shell,
BaseMessages.getString( PKG, "PentahoReportingOutputDialog.ErrorReadingParameters.Title" ),
BaseMessages.getString( PKG, "PentahoReportingOutputDialog.ErrorReadingParameters.Message" ), e );
} finally {
shell.setCursor( null );
busy.dispose();
}
}
private String getParameterDefinitionEntryTypeDescription( ParameterDefinitionEntry entry ) {
Class<?> clazz = entry.getValueType();
String extra = " (";
String namespace = entry.getParameterAttributeNamespaces()[0];
String[] attributes = entry.getParameterAttributeNames( namespace );
for ( int i = 0; i < attributes.length; i++ ) {
if ( i > 0 ) {
extra += ", ";
}
String attr = entry.getParameterAttribute( namespace, attributes[i], null );
extra += attributes[i] + "=" + attr;
}
extra += ")";
String type;
if ( clazz.equals( String.class ) ) {
type = BaseMessages.getString( PKG, "PentahoReportingOutputDialog.ParameterType.String" );
} else if ( clazz.equals( ( new String[0] ).getClass() ) ) {
type = BaseMessages.getString( PKG, "PentahoReportingOutputDialog.ParameterType.StringArray" );
} else if ( clazz.equals( Date.class ) ) {
type = BaseMessages.getString( PKG, "PentahoReportingOutputDialog.ParameterType.Date" );
} else if ( clazz.equals( byte.class ) || clazz.equals( Byte.class ) ) {
type = BaseMessages.getString( PKG, "PentahoReportingOutputDialog.ParameterType.Integer" );
} else if ( clazz.equals( Short.class ) || clazz.equals( short.class ) ) {
type = BaseMessages.getString( PKG, "PentahoReportingOutputDialog.ParameterType.Integer" );
} else if ( clazz.equals( Integer.class ) || clazz.equals( int.class ) ) {
type = BaseMessages.getString( PKG, "PentahoReportingOutputDialog.ParameterType.Integer" );
} else if ( clazz.equals( Long.class ) || clazz.equals( long.class ) ) {
type = BaseMessages.getString( PKG, "PentahoReportingOutputDialog.ParameterType.Integer" );
} else if ( clazz.equals( Double.class ) || clazz.equals( double.class ) ) {
type = BaseMessages.getString( PKG, "PentahoReportingOutputDialog.ParameterType.Number" );
} else if ( clazz.equals( Float.class ) || clazz.equals( float.class ) ) {
type = BaseMessages.getString( PKG, "PentahoReportingOutputDialog.ParameterType.Number" );
} else if ( clazz.equals( Number.class ) ) {
type = BaseMessages.getString( PKG, "PentahoReportingOutputDialog.ParameterType.Numeric" );
} else if ( clazz.equals( Boolean.class ) || clazz.equals( boolean.class ) ) {
type = BaseMessages.getString( PKG, "PentahoReportingOutputDialog.ParameterType.Boolean" );
} else if ( clazz.equals( BigDecimal.class ) ) {
type = BaseMessages.getString( PKG, "PentahoReportingOutputDialog.ParameterType.BigNumber" );
} else if ( clazz.equals( ( new byte[0] ).getClass() ) ) {
type = BaseMessages.getString( PKG, "PentahoReportingOutputDialog.ParameterType.Binary" );
} else {
// We don't know
type =
BaseMessages.getString( PKG, "PentahoReportingOutputDialog.ParameterType.Unknown", entry
.getValueType().getSimpleName() );
}
if ( attributes.length == 0 ) {
return type;
} else {
return type + extra;
}
}
}