/*! ******************************************************************************
*
* 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.job.entries.trans;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.graphics.Image;
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.Composite;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TableItem;
import org.pentaho.di.core.Const;
import org.pentaho.di.core.ObjectLocationSpecificationMethod;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.core.extension.ExtensionPointHandler;
import org.pentaho.di.core.extension.KettleExtensionPoint;
import org.pentaho.di.core.logging.LogLevel;
import org.pentaho.di.core.util.Utils;
import org.pentaho.di.core.vfs.KettleVFS;
import org.pentaho.di.i18n.BaseMessages;
import org.pentaho.di.job.JobMeta;
import org.pentaho.di.job.entries.trans.JobEntryTrans;
import org.pentaho.di.job.entry.JobEntryBase;
import org.pentaho.di.job.entry.JobEntryDialogInterface;
import org.pentaho.di.job.entry.JobEntryInterface;
import org.pentaho.di.repository.ObjectId;
import org.pentaho.di.repository.Repository;
import org.pentaho.di.repository.RepositoryObject;
import org.pentaho.di.repository.RepositoryObjectType;
import org.pentaho.di.trans.TransExecutionConfiguration;
import org.pentaho.di.trans.TransMeta;
import org.pentaho.di.ui.core.ConstUI;
import org.pentaho.di.ui.core.dialog.ErrorDialog;
import org.pentaho.di.ui.core.gui.WindowProperty;
import org.pentaho.di.ui.core.widget.ComboVar;
import org.pentaho.di.ui.job.dialog.JobDialog;
import org.pentaho.di.ui.repository.dialog.SelectObjectDialog;
import org.pentaho.di.ui.spoon.Spoon;
import org.pentaho.di.ui.trans.step.BaseStepDialog;
import org.pentaho.di.ui.util.SwtSvgImageUtil;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
* This dialog allows you to edit the transformation job entry (JobEntryTrans)
*
* @author Matt
* @since 19-06-2003
*/
public class JobEntryTransDialog extends JobEntryBaseDialog implements JobEntryDialogInterface {
private static Class<?> PKG = JobEntryTrans.class; // for i18n purposes, needed by Translator2!!
protected JobEntryTrans jobEntry;
protected ComboVar wRunConfiguration;
private static final String[] FILE_FILTERLOGNAMES = new String[] {
BaseMessages.getString( PKG, "JobTrans.Fileformat.TXT" ),
BaseMessages.getString( PKG, "JobTrans.Fileformat.LOG" ),
BaseMessages.getString( PKG, "JobTrans.Fileformat.All" ) };
public JobEntryTransDialog( Shell parent, JobEntryInterface jobEntryInt, Repository rep, JobMeta jobMeta ) {
super( parent, jobEntryInt, rep, jobMeta );
jobEntry = (JobEntryTrans) jobEntryInt;
}
public JobEntryInterface open() {
Shell parent = getParent();
display = parent.getDisplay();
shell = new Shell( parent, props.getJobsDialogStyle() );
props.setLook( shell );
JobDialog.setShellImage( shell, jobEntry );
backupChanged = jobEntry.hasChanged();
createElements();
// Detect [X] or ALT-F4 or something that kills this window...
shell.addShellListener( new ShellAdapter() {
public void shellClosed( ShellEvent e ) {
cancel();
}
} );
getData();
setActive();
BaseStepDialog.setSize( shell );
int width = 750;
int height = Const.isWindows() ? 730 : 720;
shell.setSize( width, height );
shell.open();
while ( !shell.isDisposed() ) {
if ( !display.readAndDispatch() ) {
display.sleep();
}
}
return jobEntry;
}
protected void createElements() {
super.createElements();
shell.setText( BaseMessages.getString( PKG, "JobTrans.Header" ) );
wlPath.setText( BaseMessages.getString( PKG, "JobTrans.JobStep.Transformation.Label" ) );
wlDescription.setText( BaseMessages.getString( PKG, "JobTrans.Local.Label" ) );
wPassParams.setText( BaseMessages.getString( PKG, "JobTrans.PassAllParameters.Label" ) );
wClearRows = new Button( gExecution, SWT.CHECK );
props.setLook( wClearRows );
wClearRows.setText( BaseMessages.getString( PKG, "JobTrans.ClearResultList.Label" ) );
FormData fdbClearRows = new FormData();
fdbClearRows.left = new FormAttachment( 0, 0 );
fdbClearRows.top = new FormAttachment( wEveryRow, 10 );
wClearRows.setLayoutData( fdbClearRows );
wClearFiles = new Button( gExecution, SWT.CHECK );
props.setLook( wClearFiles );
wClearFiles.setText( BaseMessages.getString( PKG, "JobTrans.ClearResultFiles.Label" ) );
FormData fdbClearFiles = new FormData();
fdbClearFiles.left = new FormAttachment( 0, 0 );
fdbClearFiles.top = new FormAttachment( wClearRows, 10 );
wClearFiles.setLayoutData( fdbClearFiles );
wWaitingToFinish = new Button( gExecution, SWT.CHECK );
props.setLook( wWaitingToFinish );
wWaitingToFinish.setText( BaseMessages.getString( PKG, "JobTrans.WaitToFinish.Label" ) );
FormData fdWait = new FormData();
fdWait.top = new FormAttachment( wClearFiles, 10 );
fdWait.left = new FormAttachment( 0, 0 );
wWaitingToFinish.setLayoutData( fdWait );
wFollowingAbortRemotely = new Button( gExecution, SWT.CHECK );
props.setLook( wFollowingAbortRemotely );
wFollowingAbortRemotely.setText( BaseMessages.getString( PKG, "JobTrans.AbortRemote.Label" ) );
FormData fdFollow = new FormData();
fdFollow.top = new FormAttachment( wWaitingToFinish, 10 );
fdFollow.left = new FormAttachment( 0, 0 );
wFollowingAbortRemotely.setLayoutData( fdFollow );
gEnvironmentType.setVisible( false );
Composite cRunConfiguration = new Composite( wOptions, SWT.NONE );
cRunConfiguration.setLayout( new FormLayout() );
props.setLook( cRunConfiguration );
FormData fdLocal = new FormData();
fdLocal.top = new FormAttachment( 0 );
fdLocal.right = new FormAttachment( 100 );
fdLocal.left = new FormAttachment( 0 );
cRunConfiguration.setBackground( shell.getBackground() ); // the default looks ugly
cRunConfiguration.setLayoutData( fdLocal );
Label wlRunConfiguration = new Label( cRunConfiguration, SWT.LEFT );
props.setLook( wlRunConfiguration );
wlRunConfiguration.setText( "Run configuration:" );
FormData fdlRunConfiguration = new FormData();
fdlRunConfiguration.top = new FormAttachment( 0 );
fdlRunConfiguration.left = new FormAttachment( 0 );
wlRunConfiguration.setLayoutData( fdlRunConfiguration );
wRunConfiguration = new ComboVar( jobMeta, cRunConfiguration, SWT.BORDER );
props.setLook( wRunConfiguration );
FormData fdRunConfiguration = new FormData();
fdRunConfiguration.width = 200;
fdRunConfiguration.top = new FormAttachment( wlRunConfiguration, 5 );
fdRunConfiguration.left = new FormAttachment( 0 );
wRunConfiguration.setLayoutData( fdRunConfiguration );
fdgExecution.top = new FormAttachment( cRunConfiguration, 10 );
wbGetParams.addSelectionListener( new SelectionAdapter() {
@Override
public void widgetSelected( SelectionEvent arg0 ) {
getParameters( null ); // force reload from file specification
}
} );
wbBrowse.addSelectionListener( new SelectionAdapter() {
public void widgetSelected( SelectionEvent e ) {
if ( rep != null ) {
selectTransformation();
} else {
pickFileVFS();
}
}
} );
wbLogFilename.addSelectionListener( new SelectionAdapter() {
public void widgetSelected( SelectionEvent e ) {
selectLogFile( FILE_FILTERLOGNAMES );
}
} );
}
protected JobEntryBase getJobEntry() {
return jobEntry;
}
protected Image getImage() {
return SwtSvgImageUtil
.getImage( shell.getDisplay(), getClass().getClassLoader(), "TRN.svg", ConstUI.ICON_SIZE,
ConstUI.ICON_SIZE );
}
protected boolean getArgFromPrev() {
return jobEntry.argFromPrevious;
}
protected String[] getArguments() {
return jobEntry.arguments;
}
protected String[] getParamters() {
return jobEntry.parameters;
}
private void getParameters( TransMeta inputTransMeta ) {
try {
if ( inputTransMeta == null ) {
JobEntryTrans jet = new JobEntryTrans();
getInfo( jet );
inputTransMeta = jet.getTransMeta( rep, metaStore, jobMeta );
}
String[] parameters = inputTransMeta.listParameters();
String[] existing = wParameters.getItems( 1 );
for ( int i = 0; i < parameters.length; i++ ) {
if ( Const.indexOfString( parameters[ i ], existing ) < 0 ) {
TableItem item = new TableItem( wParameters.table, SWT.NONE );
item.setText( 1, parameters[ i ] );
}
}
wParameters.removeEmptyRows();
wParameters.setRowNums();
wParameters.optWidth( true );
} catch ( Exception e ) {
new ErrorDialog( shell,
BaseMessages.getString( PKG, "JobEntryTransDialog.Exception.UnableToLoadTransformation.Title" ),
BaseMessages.getString( PKG, "JobEntryTransDialog.Exception.UnableToLoadTransformation.Message" ), e );
}
}
protected void selectTransformation() {
if ( rep != null ) {
SelectObjectDialog sod = new SelectObjectDialog( shell, rep, true, false );
String transname = sod.open();
if ( transname != null ) {
String path = getPath( sod.getDirectory().getPath() );
String fullPath = path + "/" + transname;
wPath.setText( fullPath );
}
}
}
protected void pickFileVFS() {
FileDialog dialog = new FileDialog( shell, SWT.OPEN );
dialog.setFilterExtensions( Const.STRING_TRANS_FILTER_EXT );
dialog.setFilterNames( Const.getTransformationFilterNames() );
String prevName = jobMeta.environmentSubstitute( wPath.getText() );
String parentFolder = null;
try {
parentFolder =
KettleVFS.getFilename( KettleVFS
.getFileObject( jobMeta.environmentSubstitute( jobMeta.getFilename() ) ).getParent() );
} catch ( Exception e ) {
// not that important
}
if ( !Utils.isEmpty( prevName ) ) {
try {
if ( KettleVFS.fileExists( prevName ) ) {
dialog.setFilterPath( KettleVFS.getFilename( KettleVFS.getFileObject( prevName ).getParent() ) );
} else {
if ( !prevName.endsWith( ".ktr" ) ) {
prevName = getEntryName( Const.trim( wPath.getText() ) + ".ktr" );
}
if ( KettleVFS.fileExists( prevName ) ) {
specificationMethod = ObjectLocationSpecificationMethod.FILENAME;
wPath.setText( prevName );
return;
} else {
// File specified doesn't exist. Ask if we should create the file...
//
MessageBox mb = new MessageBox( shell, SWT.YES | SWT.NO | SWT.ICON_QUESTION );
mb.setMessage( BaseMessages.getString( PKG, "JobTrans.Dialog.CreateTransformationQuestion.Message" ) );
mb.setText( BaseMessages.getString( PKG, "JobTrans.Dialog.CreateTransformationQuestion.Title" ) ); // Sorry!
int answer = mb.open();
if ( answer == SWT.YES ) {
Spoon spoon = Spoon.getInstance();
spoon.newTransFile();
TransMeta transMeta = spoon.getActiveTransformation();
transMeta.initializeVariablesFrom( jobEntry );
transMeta.setFilename( jobMeta.environmentSubstitute( prevName ) );
wPath.setText( prevName );
specificationMethod = ObjectLocationSpecificationMethod.FILENAME;
spoon.saveFile();
return;
}
}
}
} catch ( Exception e ) {
dialog.setFilterPath( parentFolder );
}
} else if ( !Utils.isEmpty( parentFolder ) ) {
dialog.setFilterPath( parentFolder );
}
String fname = dialog.open();
if ( fname != null ) {
File file = new File( fname );
String name = file.getName();
String parentFolderSelection = file.getParentFile().toString();
if ( !Utils.isEmpty( parentFolder ) && parentFolder.equals( parentFolderSelection ) ) {
wPath.setText( getEntryName( name ) );
} else {
wPath.setText( fname );
}
}
}
String getEntryName( String name ) {
return "${"
+ Const.INTERNAL_VARIABLE_ENTRY_CURRENT_DIRECTORY + "}/" + name;
}
public void dispose() {
WindowProperty winprop = new WindowProperty( shell );
props.setScreen( winprop );
shell.dispose();
}
public void getData() {
wName.setText( Const.NVL( jobEntry.getName(), "" ) );
specificationMethod = jobEntry.getSpecificationMethod();
switch ( specificationMethod ) {
case FILENAME:
wPath.setText( Const.NVL( jobEntry.getFilename(), "" ) );
break;
case REPOSITORY_BY_NAME:
String fullPath = Const.NVL( jobEntry.getDirectory(), "" ) + "/" + Const.NVL( jobEntry.getTransname(), "" );
wPath.setText( fullPath );
break;
case REPOSITORY_BY_REFERENCE:
referenceObjectId = jobEntry.getTransObjectId();
if ( rep != null && jobEntry.getTransObjectId() != null ) {
getByReferenceData( jobEntry.getTransObjectId() );
}
break;
default:
break;
}
// Arguments
if ( jobEntry.arguments != null ) {
for ( int i = 0; i < jobEntry.arguments.length; i++ ) {
TableItem ti = wFields.table.getItem( i );
if ( jobEntry.arguments[ i ] != null ) {
ti.setText( 1, jobEntry.arguments[ i ] );
}
}
wFields.setRowNums();
wFields.optWidth( true );
}
// Parameters
if ( jobEntry.parameters != null ) {
for ( int i = 0; i < jobEntry.parameters.length; i++ ) {
TableItem ti = wParameters.table.getItem( i );
if ( !Utils.isEmpty( jobEntry.parameters[ i ] ) ) {
ti.setText( 1, Const.NVL( jobEntry.parameters[ i ], "" ) );
ti.setText( 2, Const.NVL( jobEntry.parameterFieldNames[ i ], "" ) );
ti.setText( 3, Const.NVL( jobEntry.parameterValues[ i ], "" ) );
}
}
wParameters.setRowNums();
wParameters.optWidth( true );
}
wPassParams.setSelection( jobEntry.isPassingAllParameters() );
if ( jobEntry.logfile != null ) {
wLogfile.setText( jobEntry.logfile );
}
if ( jobEntry.logext != null ) {
wLogext.setText( jobEntry.logext );
}
wPrevious.setSelection( jobEntry.argFromPrevious );
wPrevToParams.setSelection( jobEntry.paramsFromPrevious );
wEveryRow.setSelection( jobEntry.execPerRow );
wSetLogfile.setSelection( jobEntry.setLogfile );
wAddDate.setSelection( jobEntry.addDate );
wAddTime.setSelection( jobEntry.addTime );
wClearRows.setSelection( jobEntry.clearResultRows );
wClearFiles.setSelection( jobEntry.clearResultFiles );
wWaitingToFinish.setSelection( jobEntry.isWaitingToFinish() );
wFollowingAbortRemotely.setSelection( jobEntry.isFollowingAbortRemotely() );
wAppendLogfile.setSelection( jobEntry.setAppendLogfile );
wbLogFilename.setSelection( jobEntry.setAppendLogfile );
wCreateParentFolder.setSelection( jobEntry.createParentFolder );
if ( jobEntry.logFileLevel != null ) {
wLoglevel.select( jobEntry.logFileLevel.getLevel() );
}
List<String> runConfigurations = new ArrayList<>();
try {
ExtensionPointHandler
.callExtensionPoint( Spoon.getInstance().getLog(), KettleExtensionPoint.SpoonRunConfiguration.id,
runConfigurations );
} catch ( KettleException e ) {
// Ignore errors
}
wRunConfiguration.setItems( runConfigurations.toArray( new String[ 0 ] ) );
if ( Utils.isEmpty( jobEntry.getRunConfiguration() ) ) {
wRunConfiguration.select( 0 );
} else {
wRunConfiguration.setText( jobEntry.getRunConfiguration() );
}
}
private void getByReferenceData( ObjectId transObjectId ) {
try {
RepositoryObject transInf = rep.getObjectInformation( transObjectId, RepositoryObjectType.TRANSFORMATION );
String path = getPath( transInf.getRepositoryDirectory().getPath() );
String fullPath =
Const.NVL( path, "" ) + "/" + Const.NVL( transInf.getName(), "" );
wPath.setText( fullPath );
} catch ( KettleException e ) {
new ErrorDialog( shell,
BaseMessages.getString( PKG, "JobEntryTransDialog.Exception.UnableToReferenceObjectId.Title" ),
BaseMessages.getString( PKG, "JobEntryTransDialog.Exception.UnableToReferenceObjectId.Message" ), e );
}
}
protected void cancel() {
jobEntry.setChanged( backupChanged );
jobEntry = null;
dispose();
}
private void getInfo( JobEntryTrans jet ) throws KettleException {
jet.setName( wName.getText() );
if ( rep != null ) {
specificationMethod = ObjectLocationSpecificationMethod.REPOSITORY_BY_NAME;
} else {
specificationMethod = ObjectLocationSpecificationMethod.FILENAME;
}
jet.setSpecificationMethod( specificationMethod );
switch ( specificationMethod ) {
case FILENAME:
jet.setFileName( wPath.getText() );
if ( jet.getFilename().isEmpty() ) {
throw new KettleException( BaseMessages.getString( PKG,
"JobTrans.Dialog.Exception.NoValidMappingDetailsFound" ) );
}
jet.setDirectory( null );
jet.setTransname( null );
jet.setTransObjectId( null );
break;
case REPOSITORY_BY_NAME:
String transPath = wPath.getText();
String transName = transPath;
String directory = "";
int index = transPath.lastIndexOf( "/" );
if ( index != -1 ) {
transName = transPath.substring( index + 1 );
directory = transPath.substring( 0, index );
}
jet.setDirectory( directory );
if ( jet.getDirectory().isEmpty() ) {
throw new KettleException( BaseMessages.getString( PKG,
"JobTrans.Dialog.Exception.UnableToFindRepositoryDirectory" ) );
}
jet.setTransname( transName );
jet.setFileName( null );
jet.setTransObjectId( null );
break;
default:
break;
}
int nritems = wFields.nrNonEmpty();
int nr = 0;
for ( int i = 0; i < nritems; i++ ) {
String arg = wFields.getNonEmpty( i ).getText( 1 );
if ( arg != null && arg.length() != 0 ) {
nr++;
}
}
jet.arguments = new String[ nr ];
nr = 0;
for ( int i = 0; i < nritems; i++ ) {
String arg = wFields.getNonEmpty( i ).getText( 1 );
if ( arg != null && arg.length() != 0 ) {
jet.arguments[ nr ] = arg;
nr++;
}
}
// Do the parameters
nritems = wParameters.nrNonEmpty();
nr = 0;
for ( int i = 0; i < nritems; i++ ) {
String param = wParameters.getNonEmpty( i ).getText( 1 );
if ( param != null && param.length() != 0 ) {
nr++;
}
}
jet.parameters = new String[ nr ];
jet.parameterFieldNames = new String[ nr ];
jet.parameterValues = new String[ nr ];
nr = 0;
for ( int i = 0; i < nritems; i++ ) {
String param = wParameters.getNonEmpty( i ).getText( 1 );
String fieldName = wParameters.getNonEmpty( i ).getText( 2 );
String value = wParameters.getNonEmpty( i ).getText( 3 );
jet.parameters[ nr ] = param;
if ( !Utils.isEmpty( Const.trim( fieldName ) ) ) {
jet.parameterFieldNames[ nr ] = fieldName;
} else {
jet.parameterFieldNames[ nr ] = "";
}
if ( !Utils.isEmpty( Const.trim( value ) ) ) {
jet.parameterValues[ nr ] = value;
} else {
jet.parameterValues[ nr ] = "";
}
nr++;
}
jet.setPassingAllParameters( wPassParams.getSelection() );
jet.logfile = wLogfile.getText();
jet.logext = wLogext.getText();
if ( wLoglevel.getSelectionIndex() >= 0 ) {
jet.logFileLevel = LogLevel.values()[ wLoglevel.getSelectionIndex() ];
} else {
jet.logFileLevel = LogLevel.BASIC;
}
jet.argFromPrevious = wPrevious.getSelection();
jet.paramsFromPrevious = wPrevToParams.getSelection();
jet.execPerRow = wEveryRow.getSelection();
jet.setLogfile = wSetLogfile.getSelection();
jet.addDate = wAddDate.getSelection();
jet.addTime = wAddTime.getSelection();
jet.clearResultRows = wClearRows.getSelection();
jet.clearResultFiles = wClearFiles.getSelection();
jet.createParentFolder = wCreateParentFolder.getSelection();
jet.setRunConfiguration( wRunConfiguration.getText() );
jet.setAppendLogfile = wAppendLogfile.getSelection();
jet.setWaitingToFinish( wWaitingToFinish.getSelection() );
jet.setFollowingAbortRemotely( wFollowingAbortRemotely.getSelection() );
TransExecutionConfiguration executionConfiguration = new TransExecutionConfiguration();
executionConfiguration.setRunConfiguration( jet.getRunConfiguration() );
try {
ExtensionPointHandler.callExtensionPoint( jobEntry.getLogChannel(), KettleExtensionPoint.SpoonTransBeforeStart.id,
new Object[] { executionConfiguration, jobMeta, jobMeta } );
} catch ( KettleException e ) {
// Ignore errors
}
try {
ExtensionPointHandler.callExtensionPoint( jobEntry.getLogChannel(), KettleExtensionPoint.JobEntryTransSave.id,
new Object[] { jobMeta, jet.getRunConfiguration() } );
} catch ( KettleException e ) {
// Ignore errors
}
jet.setClustering( executionConfiguration.isExecutingClustered() );
if ( executionConfiguration.getRemoteServer() != null ) {
jet.setRemoteSlaveServerName( executionConfiguration.getRemoteServer().getName() );
}
jet.setLoggingRemoteWork( executionConfiguration.isLogRemoteExecutionLocally() );
}
protected void ok() {
if ( Utils.isEmpty( wName.getText() ) ) {
MessageBox mb = new MessageBox( shell, SWT.OK | SWT.ICON_ERROR );
mb.setText( BaseMessages.getString( PKG, "System.StepJobEntryNameMissing.Title" ) );
mb.setMessage( BaseMessages.getString( PKG, "System.JobEntryNameMissing.Msg" ) );
mb.open();
return;
}
jobEntry.setName( wName.getText() );
try {
getInfo( jobEntry );
jobEntry.setChanged();
dispose();
} catch ( KettleException e ) {
new ErrorDialog( shell, BaseMessages.getString( PKG, "JobTrans.Dialog.ErrorShowingTransformation.Title" ),
BaseMessages.getString( PKG, "JobTrans.Dialog.ErrorShowingTransformation.Message" ), e );
}
}
}