/*! ****************************************************************************** * * 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.ui.trans.steps.terafast; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CCombo; import org.eclipse.swt.events.FocusAdapter; import org.eclipse.swt.events.FocusEvent; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; 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.layout.FormAttachment; import org.eclipse.swt.layout.FormData; import org.eclipse.swt.layout.FormLayout; import org.eclipse.swt.program.Program; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Link; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.TableItem; import org.pentaho.di.core.Const; import org.pentaho.di.core.SourceToTargetMapping; import org.pentaho.di.core.database.TeradataDatabaseMeta; import org.pentaho.di.core.exception.KettleException; import org.pentaho.di.core.row.RowMetaInterface; import org.pentaho.di.core.row.ValueMetaInterface; import org.pentaho.di.core.util.KeyValue; import org.pentaho.di.core.util.PluginProperty; 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.step.StepMeta; import org.pentaho.di.trans.steps.terafast.TeraFastMeta; import org.pentaho.di.ui.core.SimpleFileSelection; import org.pentaho.di.ui.core.dialog.EnterMappingDialog; import org.pentaho.di.ui.core.dialog.ErrorDialog; import org.pentaho.di.ui.core.widget.ColumnInfo; import org.pentaho.di.ui.core.widget.PluginWidgetFactory; import org.pentaho.di.ui.core.widget.TableView; import org.pentaho.di.ui.core.widget.TextVar; import org.pentaho.di.ui.trans.step.BaseStepDialog; import org.pentaho.di.ui.trans.step.TableItemInsertListener; /** * TODO BaseStepDialog should replaced by something like AbstractStepDialog (BaseStepDialog is ... - asc042, 13.05.2009) * * @author <a href="mailto:michael.gugerell@aschauer-edv.at">Michael Gugerell(asc145)</a> * */ public class TeraFastDialog extends BaseStepDialog implements StepDialogInterface { private static Class<?> PKG = TeraFastMeta.class; // for i18n purposes, needed by Translator2!! private static final int FORM_ATTACHMENT_OFFSET = 100; private static final int FORM_ATTACHMENT_FACTOR = -15; private TeraFastMeta meta; private CCombo wConnection; private Label wlConnection; private Button wbwConnection, wbnConnection, wbeConnection; private Label wlTable; private TextVar wTable; private Label wlFastLoadPath; private TextVar wFastLoadPath; private Button wbFastLoadPath; private Label wlControlFile; private TextVar wControlFile; private Button wbControlFile; private Label wlDataFile; private TextVar wDataFile; private Button wbDataFile; private Label wlLogFile; private Button wbLogFile; private TextVar wLogFile; private Label wlErrLimit; private TextVar wErrLimit; private Label wlSessions; private TextVar wSessions; private Label wlUseControlFile; private Button wUseControlFile; private Label wlVariableSubstitution; private Button wVariableSubstitution; private Label wlTruncateTable; private Button wbTruncateTable; private Link wAscLink; private Label wlReturn; private TableView wReturn; private Button wGetLU; private FormData fdGetLU; private Listener lsGetLU; private Button wDoMapping; private FormData fdDoMapping; private Button wAbout; private ColumnInfo[] ciReturn; private Map<String, Integer> inputFields = new HashMap<String, Integer>(); /** * List of ColumnInfo that should have the field names of the selected database table. */ private List<ColumnInfo> tableFieldColumns = new ArrayList<ColumnInfo>(); /** * Constructor. * * @param parent * parent shell. * @param baseStepMeta * step meta * @param transMeta * transaction meta * @param stepname * name of step. */ public TeraFastDialog( final Shell parent, final Object baseStepMeta, final TransMeta transMeta, final String stepname ) { super( parent, (BaseStepMeta) baseStepMeta, transMeta, stepname ); this.meta = (TeraFastMeta) baseStepMeta; } /** * @param property * property. * @param textVar * text varibale. */ public static void setTextIfPropertyValue( final PluginProperty property, final TextVar textVar ) { if ( property.evaluate() ) { textVar.setText( ( (KeyValue<?>) property ).stringValue() ); } } /** * @param property * property. * @param combo * text variable. */ public static void setTextIfPropertyValue( final PluginProperty property, final CCombo combo ) { if ( property.evaluate() ) { combo.setText( ( (KeyValue<?>) property ).stringValue() ); } } /** * {@inheritDoc} * * @see org.pentaho.di.trans.step.StepDialogInterface#open() */ public String open() { this.changed = this.meta.hasChanged(); final Shell parent = getParent(); final Display display = parent.getDisplay(); this.shell = new Shell( parent, SWT.DIALOG_TRIM | SWT.RESIZE | SWT.MIN | SWT.MAX ); this.props.setLook( this.shell ); setShellImage( this.shell, this.meta ); FormLayout formLayout = new FormLayout(); formLayout.marginWidth = Const.FORM_MARGIN; formLayout.marginHeight = Const.FORM_MARGIN; this.shell.setLayout( formLayout ); this.shell.setText( BaseMessages.getString( PKG, "TeraFastDialog.Shell.Title" ) ); buildUi(); assignChangeListener(); listeners(); // // Search the fields in the background // final Runnable runnable = new Runnable() { public void run() { final StepMeta stepMetaSearchFields = TeraFastDialog.this.transMeta.findStep( TeraFastDialog.this.stepname ); if ( stepMetaSearchFields == null ) { return; } try { final RowMetaInterface row = TeraFastDialog.this.transMeta.getPrevStepFields( stepMetaSearchFields ); // Remember these fields... for ( int i = 0; i < row.size(); i++ ) { TeraFastDialog.this.inputFields.put( row.getValueMeta( i ).getName(), Integer.valueOf( i ) ); } setComboBoxes(); } catch ( KettleException e ) { TeraFastDialog.this.logError( BaseMessages.getString( PKG, "System.Dialog.GetFieldsFailed.Message" ) ); } } }; new Thread( runnable ).start(); // // // Set the shell size, based upon previous time... setSize(); getData(); this.meta.setChanged( this.changed ); disableInputs(); this.shell.open(); while ( !this.shell.isDisposed() ) { if ( !display.readAndDispatch() ) { display.sleep(); } } return this.stepname; } /** * ... */ protected void setComboBoxes() { // Something was changed in the row. // final Map<String, Integer> fields = new HashMap<String, Integer>(); // Add the currentMeta fields... fields.putAll( this.inputFields ); Set<String> keySet = fields.keySet(); List<String> entries = new ArrayList<String>( keySet ); String[] fieldNames = entries.toArray( new String[entries.size()] ); Const.sortStrings( fieldNames ); // return fields this.ciReturn[1].setComboValues( fieldNames ); } /** * Set data values in dialog. */ public void getData() { setTextIfPropertyValue( this.meta.getFastloadPath(), this.wFastLoadPath ); setTextIfPropertyValue( this.meta.getControlFile(), this.wControlFile ); setTextIfPropertyValue( this.meta.getDataFile(), this.wDataFile ); setTextIfPropertyValue( this.meta.getLogFile(), this.wLogFile ); setTextIfPropertyValue( this.meta.getTargetTable(), this.wTable ); setTextIfPropertyValue( this.meta.getErrorLimit(), this.wErrLimit ); setTextIfPropertyValue( this.meta.getSessions(), this.wSessions ); setTextIfPropertyValue( this.meta.getConnectionName(), this.wConnection ); this.wbTruncateTable.setSelection( this.meta.getTruncateTable().getValue() ); this.wUseControlFile.setSelection( this.meta.getUseControlFile().getValue() ); this.wVariableSubstitution.setSelection( this.meta.getVariableSubstitution().getValue() ); if ( this.meta.getTableFieldList().getValue().size() == this.meta.getStreamFieldList().getValue().size() ) { for ( int i = 0; i < this.meta.getTableFieldList().getValue().size(); i++ ) { TableItem item = this.wReturn.table.getItem( i ); item.setText( 1, this.meta.getTableFieldList().getValue().get( i ) ); item.setText( 2, this.meta.getStreamFieldList().getValue().get( i ) ); } } // DatabaseMeta dbMeta = this.transMeta.findDatabase(this.meta.getDbConnection().getValue()); if ( this.meta.getDbMeta() != null ) { this.wConnection.setText( this.meta.getConnectionName().getValue() ); } else { if ( this.transMeta.nrDatabases() == 1 ) { this.wConnection.setText( this.transMeta.getDatabase( 0 ).getName() ); } } setTableFieldCombo(); wStepname.selectAll(); wStepname.setFocus(); } /** * Configure listeners. */ private void listeners() { this.lsCancel = new Listener() { public void handleEvent( final Event event ) { cancel(); } }; this.lsOK = new Listener() { public void handleEvent( final Event event ) { ok(); } }; this.wAbout.addListener( SWT.Selection, new Listener() { public void handleEvent( Event arg0 ) { new TeraFastAboutDialog( TeraFastDialog.this.shell ).open(); } } ); this.wCancel.addListener( SWT.Selection, this.lsCancel ); this.wOK.addListener( SWT.Selection, this.lsOK ); this.lsDef = new SelectionAdapter() { @Override public void widgetDefaultSelected( final SelectionEvent event ) { ok(); } }; this.lsGetLU = new Listener() { public void handleEvent( final Event event ) { getUpdate(); } }; this.wGetLU.addListener( SWT.Selection, this.lsGetLU ); this.wStepname.addSelectionListener( this.lsDef ); final String allFileTypes = BaseMessages.getString( PKG, "TeraFastDialog.Filetype.All" ); this.wbControlFile .addSelectionListener( new SimpleFileSelection( this.shell, this.wControlFile, allFileTypes ) ); this.wbDataFile.addSelectionListener( new SimpleFileSelection( this.shell, this.wDataFile, allFileTypes ) ); this.wbFastLoadPath.addSelectionListener( new SimpleFileSelection( this.shell, this.wFastLoadPath, allFileTypes ) ); this.wbLogFile.addSelectionListener( new SimpleFileSelection( this.shell, this.wLogFile, allFileTypes ) ); this.wDoMapping.addListener( SWT.Selection, new Listener() { public void handleEvent( final Event event ) { generateMappings(); } } ); this.wAscLink.addListener( SWT.Selection, new Listener() { public void handleEvent( final Event event ) { Program.launch( event.text ); } } ); // Detect X or ALT-F4 or something that kills this window... this.shell.addShellListener( new ShellAdapter() { @Override public void shellClosed( final ShellEvent event ) { cancel(); } } ); } /** * Reads in the fields from the previous steps and from the ONE next step and opens an EnterMappingDialog with this * information. After the user did the mapping, those information is put into the Select/Rename table. */ public void generateMappings() { // Determine the source and target fields... // RowMetaInterface sourceFields; RowMetaInterface targetFields; try { sourceFields = this.transMeta.getPrevStepFields( this.stepMeta ); } catch ( KettleException e ) { new ErrorDialog( this.shell, BaseMessages.getString( PKG, "TeraFastDialog.DoMapping.UnableToFindSourceFields.Title" ), BaseMessages.getString( PKG, "TeraFastDialog.DoMapping.UnableToFindSourceFields.Message" ), e ); return; } // refresh fields this.meta.getTargetTable().setValue( this.wTable.getText() ); try { targetFields = this.meta.getRequiredFields( this.transMeta ); } catch ( KettleException e ) { new ErrorDialog( this.shell, BaseMessages.getString( PKG, "TeraFastDialog.DoMapping.UnableToFindTargetFields.Title" ), BaseMessages.getString( PKG, "TeraFastDialog.DoMapping.UnableToFindTargetFields.Message" ), e ); return; } String[] inputNames = new String[sourceFields.size()]; for ( int i = 0; i < sourceFields.size(); i++ ) { ValueMetaInterface value = sourceFields.getValueMeta( i ); inputNames[i] = value.getName() + EnterMappingDialog.STRING_ORIGIN_SEPARATOR + value.getOrigin() + ")"; } // Create the existing mapping list... // List<SourceToTargetMapping> mappings = new ArrayList<SourceToTargetMapping>(); StringBuilder missingSourceFields = new StringBuilder(); StringBuilder missingTargetFields = new StringBuilder(); int nrFields = this.wReturn.nrNonEmpty(); for ( int i = 0; i < nrFields; i++ ) { TableItem item = this.wReturn.getNonEmpty( i ); String source = item.getText( 2 ); String target = item.getText( 1 ); int sourceIndex = sourceFields.indexOfValue( source ); if ( sourceIndex < 0 ) { missingSourceFields.append( Const.CR + " " + source + " --> " + target ); } int targetIndex = targetFields.indexOfValue( target ); if ( targetIndex < 0 ) { missingTargetFields.append( Const.CR + " " + source + " --> " + target ); } if ( sourceIndex < 0 || targetIndex < 0 ) { continue; } SourceToTargetMapping mapping = new SourceToTargetMapping( sourceIndex, targetIndex ); mappings.add( mapping ); } EnterMappingDialog d = new EnterMappingDialog( TeraFastDialog.this.shell, sourceFields.getFieldNames(), targetFields .getFieldNames(), mappings ); mappings = d.open(); // mappings == null if the user pressed cancel // if ( mappings != null ) { // Clear and re-populate! // this.wReturn.table.removeAll(); this.wReturn.table.setItemCount( mappings.size() ); for ( int i = 0; i < mappings.size(); i++ ) { SourceToTargetMapping mapping = mappings.get( i ); TableItem item = this.wReturn.table.getItem( i ); item.setText( 2, sourceFields.getValueMeta( mapping.getSourcePosition() ).getName() ); item.setText( 1, targetFields.getValueMeta( mapping.getTargetPosition() ).getName() ); } this.wReturn.setRowNums(); this.wReturn.optWidth( true ); } } /** * ... */ public void getUpdate() { try { final RowMetaInterface row = this.transMeta.getPrevStepFields( this.stepname ); if ( row != null ) { TableItemInsertListener listener = new TableItemInsertListener() { public boolean tableItemInserted( final TableItem tableItem, final ValueMetaInterface value ) { // possible to check format of input fields return true; } }; BaseStepDialog.getFieldsFromPrevious( row, this.wReturn, 1, new int[] { 1, 2 }, new int[] {}, -1, -1, listener ); } } catch ( KettleException ke ) { new ErrorDialog( this.shell, BaseMessages.getString( PKG, "TeraFastDialog.FailedToGetFields.DialogTitle" ), BaseMessages .getString( PKG, "TeraFastDialog.FailedToGetFields.DialogMessage" ), ke ); } } /** * Dialog is closed. */ public void cancel() { this.stepname = null; this.meta.setChanged( this.changed ); dispose(); } /** * Ok clicked. */ public void ok() { this.stepname = this.wStepname.getText(); // return value this.meta.getUseControlFile().setValue( this.wUseControlFile.getSelection() ); this.meta.getVariableSubstitution().setValue( this.wVariableSubstitution.getSelection() ); this.meta.getControlFile().setValue( this.wControlFile.getText() ); this.meta.getFastloadPath().setValue( this.wFastLoadPath.getText() ); this.meta.getDataFile().setValue( this.wDataFile.getText() ); this.meta.getLogFile().setValue( this.wLogFile.getText() ); this.meta.getErrorLimit().setValue( Const.toInt( this.wErrLimit.getText(), TeraFastMeta.DEFAULT_ERROR_LIMIT ) ); this.meta.getSessions().setValue( Const.toInt( this.wSessions.getText(), TeraFastMeta.DEFAULT_SESSIONS ) ); this.meta.getTargetTable().setValue( this.wTable.getText() ); this.meta.getConnectionName().setValue( this.wConnection.getText() ); this.meta.getTruncateTable().setValue( this.wbTruncateTable.getSelection() && this.wbTruncateTable.getEnabled() ); this.meta.setDbMeta( this.transMeta.findDatabase( this.wConnection.getText() ) ); this.meta.getTableFieldList().getValue().clear(); this.meta.getStreamFieldList().getValue().clear(); int nrfields = this.wReturn.nrNonEmpty(); for ( int i = 0; i < nrfields; i++ ) { TableItem item = this.wReturn.getNonEmpty( i ); this.meta.getTableFieldList().getValue().add( item.getText( 1 ) ); this.meta.getStreamFieldList().getValue().add( item.getText( 2 ) ); } dispose(); } /** * Build UI. */ protected void buildUi() { final PluginWidgetFactory factory = new PluginWidgetFactory( this.shell, this.transMeta ); factory.setMiddle( this.props.getMiddlePct() ); this.buildStepNameLine( factory ); this.buildUseControlFileLine( factory ); this.buildControlFileLine( factory ); this.buildVariableSubstitutionLine( factory ); this.buildFastloadLine( factory ); this.buildLogFileLine( factory ); // connection line this.wbwConnection = new Button( this.shell, SWT.PUSH ); this.wbnConnection = new Button( this.shell, SWT.PUSH ); this.wbeConnection = new Button( this.shell, SWT.PUSH ); this.wlConnection = new Label( this.shell, SWT.RIGHT ); this.wConnection = addConnectionLine( this.shell, this.wLogFile, factory.getMiddle(), factory.getMargin(), this.wlConnection, this.wbwConnection, this.wbnConnection, this.wbeConnection, TeradataDatabaseMeta.class ); this.buildTableLine( factory ); this.buildTruncateTableLine( factory ); this.buildDataFileLine( factory ); this.buildSessionsLine( factory ); this.buildErrorLimitLine( factory ); this.buildFieldTable( factory ); this.buildAscLink( factory ); this.wOK = factory.createPushButton( BaseMessages.getString( PKG, "System.Button.OK" ) ); this.wCancel = factory.createPushButton( BaseMessages.getString( PKG, "System.Button.Cancel" ) ); this.wAbout = factory.createPushButton( BaseMessages.getString( PKG, "TeraFastDialog.About.Button" ) ); setButtonPositions( new Button[] { this.wOK, this.wCancel, this.wAbout }, factory.getMargin(), this.wAscLink ); } /** * @param factory * factory to use. */ protected void buildControlFileLine( final PluginWidgetFactory factory ) { final Control topControl = this.wUseControlFile; this.wlControlFile = factory.createRightLabel( BaseMessages.getString( PKG, "TeraFastDialog.ControlFile.Label" ) ); this.props.setLook( this.wlControlFile ); this.wlControlFile.setLayoutData( factory.createLabelLayoutData( topControl ) ); this.wbControlFile = factory.createPushButton( BaseMessages.getString( PKG, "TeraFastDialog.Browse.Button" ) ); this.props.setLook( this.wbControlFile ); FormData formData = factory.createControlLayoutData( topControl ); formData.left = null; this.wbControlFile.setLayoutData( formData ); this.wControlFile = factory.createSingleTextVarLeft(); this.props.setLook( this.wControlFile ); formData = factory.createControlLayoutData( topControl ); formData.right = new FormAttachment( this.wbControlFile, -factory.getMargin() ); this.wControlFile.setLayoutData( formData ); } /** * @param factory * factory to use. */ protected void buildFastloadLine( final PluginWidgetFactory factory ) { final Control topControl = this.wVariableSubstitution; this.wlFastLoadPath = factory.createRightLabel( BaseMessages.getString( PKG, "TeraFastDialog.FastloadPath.Label" ) ); this.props.setLook( this.wlFastLoadPath ); this.wlFastLoadPath.setLayoutData( factory.createLabelLayoutData( topControl ) ); this.wbFastLoadPath = factory.createPushButton( BaseMessages.getString( PKG, "TeraFastDialog.Browse.Button" ) ); this.props.setLook( this.wbFastLoadPath ); FormData formData = factory.createControlLayoutData( topControl ); formData.left = null; this.wbFastLoadPath.setLayoutData( formData ); this.wFastLoadPath = factory.createSingleTextVarLeft(); this.props.setLook( this.wFastLoadPath ); formData = factory.createControlLayoutData( topControl ); formData.right = new FormAttachment( this.wbFastLoadPath, -factory.getMargin() ); this.wFastLoadPath.setLayoutData( formData ); } /** * @param factory * factory to use. */ protected void buildUseControlFileLine( final PluginWidgetFactory factory ) { final Control topControl = this.wStepname; this.wlUseControlFile = factory.createRightLabel( BaseMessages.getString( PKG, "TeraFastDialog.UseControlFile.Label" ) ); this.props.setLook( this.wlUseControlFile ); this.wlUseControlFile.setLayoutData( factory.createLabelLayoutData( topControl ) ); this.wUseControlFile = new Button( this.shell, SWT.CHECK ); this.props.setLook( this.wUseControlFile ); this.wUseControlFile.setLayoutData( factory.createControlLayoutData( topControl ) ); this.wUseControlFile.addSelectionListener( new SelectionAdapter() { @Override public void widgetSelected( final SelectionEvent event ) { disableInputs(); } } ); } /** * @param factory * factory to use. */ protected void buildVariableSubstitutionLine( final PluginWidgetFactory factory ) { final Control topControl = this.wControlFile; this.wlVariableSubstitution = factory.createRightLabel( BaseMessages.getString( PKG, "TeraFastDialog.VariableSubstitution.Label" ) ); this.props.setLook( this.wlVariableSubstitution ); this.wlVariableSubstitution.setLayoutData( factory.createLabelLayoutData( topControl ) ); this.wVariableSubstitution = new Button( this.shell, SWT.CHECK ); this.props.setLook( this.wVariableSubstitution ); this.wVariableSubstitution.setLayoutData( factory.createControlLayoutData( topControl ) ); } /** * @param factory * factory to use. */ protected void buildLogFileLine( final PluginWidgetFactory factory ) { final Control topControl = this.wFastLoadPath; this.wlLogFile = factory.createRightLabel( BaseMessages.getString( PKG, "TeraFastDialog.LogFile.Label" ) ); this.props.setLook( this.wlLogFile ); this.wlLogFile.setLayoutData( factory.createLabelLayoutData( topControl ) ); this.wbLogFile = factory.createPushButton( BaseMessages.getString( PKG, "TeraFastDialog.Browse.Button" ) ); this.props.setLook( this.wbLogFile ); FormData formData = factory.createControlLayoutData( topControl ); formData.left = null; this.wbLogFile.setLayoutData( formData ); this.wLogFile = factory.createSingleTextVarLeft(); this.props.setLook( this.wLogFile ); formData = factory.createControlLayoutData( topControl ); formData.right = new FormAttachment( this.wbLogFile, -factory.getMargin() ); this.wLogFile.setLayoutData( formData ); } /** * Build step name line. * * @param factory * factory to use. */ protected void buildStepNameLine( final PluginWidgetFactory factory ) { this.wlStepname = factory.createRightLabel( BaseMessages.getString( PKG, "TeraFastDialog.StepName.Label" ) ); this.props.setLook( this.wlStepname ); this.fdlStepname = factory.createLabelLayoutData( null ); this.wlStepname.setLayoutData( this.fdlStepname ); this.wStepname = factory.createSingleTextLeft( this.stepname ); this.props.setLook( this.wStepname ); this.fdStepname = factory.createControlLayoutData( null ); this.wStepname.setLayoutData( this.fdStepname ); } /** * @param factory * factory to use. */ protected void buildTableLine( final PluginWidgetFactory factory ) { final Control topControl = this.wConnection; this.wlTable = factory.createRightLabel( BaseMessages.getString( PKG, "TeraFastDialog.TargetTable.Label" ) ); this.props.setLook( this.wlTable ); this.wlTable.setLayoutData( factory.createLabelLayoutData( topControl ) ); this.wTable = factory.createSingleTextVarLeft(); this.props.setLook( this.wTable ); this.wTable.setLayoutData( factory.createControlLayoutData( topControl ) ); this.wTable.addFocusListener( new FocusAdapter() { @Override public void focusLost( final FocusEvent event ) { setTableFieldCombo(); } } ); } /** * @param factory * factory to use. */ protected void buildTruncateTableLine( final PluginWidgetFactory factory ) { final Control topControl = this.wTable; this.wlTruncateTable = factory.createRightLabel( BaseMessages.getString( PKG, "TeraFastDialog.TruncateTable.Label" ) ); this.props.setLook( this.wlTruncateTable ); this.wlTruncateTable.setLayoutData( factory.createLabelLayoutData( topControl ) ); this.wbTruncateTable = new Button( this.shell, SWT.CHECK ); this.props.setLook( this.wbTruncateTable ); this.wbTruncateTable.setLayoutData( factory.createControlLayoutData( topControl ) ); } /** * @param factory * factory to use. */ protected void buildDataFileLine( final PluginWidgetFactory factory ) { final Control topControl = this.wbTruncateTable; this.wlDataFile = factory.createRightLabel( BaseMessages.getString( PKG, "TeraFastDialog.DataFile.Label" ) ); this.props.setLook( this.wlDataFile ); this.wlDataFile.setLayoutData( factory.createLabelLayoutData( topControl ) ); this.wbDataFile = factory.createPushButton( BaseMessages.getString( PKG, "TeraFastDialog.Browse.Button" ) ); this.props.setLook( this.wbDataFile ); FormData formData = factory.createControlLayoutData( topControl ); formData.left = null; this.wbDataFile.setLayoutData( formData ); this.wDataFile = factory.createSingleTextVarLeft(); this.props.setLook( this.wDataFile ); formData = factory.createControlLayoutData( topControl ); formData.right = new FormAttachment( this.wbDataFile, -factory.getMargin() ); this.wDataFile.setLayoutData( formData ); } /** * @param factory * factory to use. */ protected void buildSessionsLine( final PluginWidgetFactory factory ) { final Control topControl = this.wDataFile; this.wlSessions = factory.createRightLabel( BaseMessages.getString( PKG, "TeraFastDialog.Sessions.Label" ) ); this.props.setLook( this.wlSessions ); this.wlSessions.setLayoutData( factory.createLabelLayoutData( topControl ) ); this.wSessions = factory.createSingleTextVarLeft(); this.props.setLook( this.wSessions ); this.wSessions.setLayoutData( factory.createControlLayoutData( topControl ) ); } /** * @param factory * factory to use. */ protected void buildErrorLimitLine( final PluginWidgetFactory factory ) { final Control topControl = this.wSessions; this.wlErrLimit = factory.createRightLabel( BaseMessages.getString( PKG, "TeraFastDialog.ErrLimit.Label" ) ); this.props.setLook( this.wlErrLimit ); this.wlErrLimit.setLayoutData( factory.createLabelLayoutData( topControl ) ); this.wErrLimit = factory.createSingleTextVarLeft(); this.props.setLook( this.wErrLimit ); this.wErrLimit.setLayoutData( factory.createControlLayoutData( topControl ) ); } /** * @param factory * factory to use. */ protected void buildAscLink( final PluginWidgetFactory factory ) { final Control topControl = this.wReturn; this.wAscLink = new Link( this.shell, SWT.NONE ); this.wAscLink.setText( BaseMessages.getString( PKG, "TeraFastDialog.Provided.Info" ) ); FormData formData = factory.createLabelLayoutData( topControl ); formData.right = null; this.wAscLink.setLayoutData( formData ); } /** * @param factory * factory to use. */ protected void buildFieldTable( final PluginWidgetFactory factory ) { final Control topControl = this.wErrLimit; this.wlReturn = factory.createLabel( SWT.NONE, BaseMessages.getString( PKG, "TeraFastDialog.Fields.Label" ) ); this.props.setLook( this.wlReturn ); this.wlReturn.setLayoutData( factory.createLabelLayoutData( topControl ) ); final int upInsCols = 2; final int upInsRows; if ( this.meta.getTableFieldList().isEmpty() ) { upInsRows = 1; } else { upInsRows = this.meta.getTableFieldList().size(); } this.ciReturn = new ColumnInfo[upInsCols]; this.ciReturn[0] = new ColumnInfo( BaseMessages.getString( PKG, "TeraFastDialog.ColumnInfo.TableField" ), ColumnInfo.COLUMN_TYPE_CCOMBO, new String[] { "" }, false ); this.ciReturn[1] = new ColumnInfo( BaseMessages.getString( PKG, "TeraFastDialog.ColumnInfo.StreamField" ), ColumnInfo.COLUMN_TYPE_CCOMBO, new String[] { "" }, false ); this.tableFieldColumns.add( this.ciReturn[0] ); this.wReturn = new TableView( this.transMeta, this.shell, SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL, this.ciReturn, upInsRows, null, this.props ); this.wGetLU = factory.createPushButton( BaseMessages.getString( PKG, "TeraFastDialog.GetFields.Label" ) ); this.fdGetLU = new FormData(); this.fdGetLU.top = new FormAttachment( this.wlReturn, factory.getMargin() ); this.fdGetLU.right = new FormAttachment( FORM_ATTACHMENT_OFFSET, 0 ); this.wGetLU.setLayoutData( this.fdGetLU ); this.wDoMapping = factory.createPushButton( BaseMessages.getString( PKG, "TeraFastDialog.EditMapping.Label" ) ); this.fdDoMapping = new FormData(); this.fdDoMapping.top = new FormAttachment( this.wGetLU, factory.getMargin() ); this.fdDoMapping.right = new FormAttachment( FORM_ATTACHMENT_OFFSET, 0 ); this.wDoMapping.setLayoutData( this.fdDoMapping ); FormData formData = new FormData(); formData.left = new FormAttachment( 0, 0 ); formData.top = new FormAttachment( this.wlReturn, factory.getMargin() ); formData.right = new FormAttachment( this.wGetLU, -factory.getMargin() ); formData.bottom = new FormAttachment( FORM_ATTACHMENT_OFFSET, FORM_ATTACHMENT_FACTOR * factory.getMargin() ); this.wReturn.setLayoutData( formData ); } /** * ... */ protected void assignChangeListener() { final ModifyListener lsMod = new ModifyListener() { public void modifyText( final ModifyEvent event ) { getMeta().setChanged(); } }; final SelectionAdapter lsSel = new SelectionAdapter() { @Override public void widgetSelected( final SelectionEvent event ) { getMeta().setChanged(); } }; this.wStepname.addModifyListener( lsMod ); this.wControlFile.addModifyListener( lsMod ); this.wFastLoadPath.addModifyListener( lsMod ); this.wLogFile.addModifyListener( lsMod ); this.wConnection.addModifyListener( lsMod ); this.wTable.addModifyListener( lsMod ); this.wDataFile.addModifyListener( lsMod ); this.wSessions.addModifyListener( lsMod ); this.wErrLimit.addModifyListener( lsMod ); this.wbTruncateTable.addSelectionListener( lsSel ); this.wUseControlFile.addSelectionListener( lsSel ); this.wVariableSubstitution.addSelectionListener( lsSel ); this.wReturn.addModifyListener( lsMod ); } /** * Disable inputs. */ public void disableInputs() { boolean useControlFile = this.wUseControlFile.getSelection(); this.wbControlFile.setEnabled( useControlFile ); this.wControlFile.setEnabled( useControlFile ); this.wDataFile.setEnabled( !useControlFile ); this.wbDataFile.setEnabled( !useControlFile ); this.wSessions.setEnabled( !useControlFile ); this.wErrLimit.setEnabled( !useControlFile ); this.wReturn.setEnabled( !useControlFile ); this.wGetLU.setEnabled( !useControlFile ); this.wDoMapping.setEnabled( !useControlFile ); this.wTable.setEnabled( !useControlFile ); this.wbTruncateTable.setEnabled( !useControlFile ); this.wConnection.setEnabled( !useControlFile ); this.wbeConnection.setEnabled( !useControlFile ); this.wbwConnection.setEnabled( !useControlFile ); this.wbnConnection.setEnabled( !useControlFile ); this.wVariableSubstitution.setEnabled( useControlFile ); } /** * ... */ public void setTableFieldCombo() { clearColInfo(); new FieldLoader( this ).start(); } /** * Clear. */ private void clearColInfo() { for ( int i = 0, n = this.tableFieldColumns.size(); i < n; i++ ) { final ColumnInfo colInfo = this.tableFieldColumns.get( i ); colInfo.setComboValues( new String[] {} ); } } /** * @return the meta */ public TeraFastMeta getMeta() { return this.meta; } /** * @author <a href="mailto:thomas.hoedl@aschauer-edv.at">Thomas Hoedl(asc042)</a> * */ private static final class FieldLoader extends Thread { private TeraFastDialog dialog; /** * Constructor. * * @param dialog * dialog to set. */ public FieldLoader( final TeraFastDialog dialog ) { this.dialog = dialog; } /** * {@inheritDoc} * * @see java.lang.Runnable#run() */ @Override public void run() { try { final RowMetaInterface rowMeta = this.dialog.meta.getRequiredFields( this.dialog.transMeta ); if ( rowMeta == null ) { return; } final String[] fieldNames = rowMeta.getFieldNames(); if ( fieldNames == null ) { return; } for ( int i = 0; i < this.dialog.tableFieldColumns.size(); i++ ) { final ColumnInfo colInfo = this.dialog.tableFieldColumns.get( i ); if ( this.dialog.shell.isDisposed() ) { return; } this.dialog.shell.getDisplay().asyncExec( new Runnable() { public void run() { if ( FieldLoader.this.dialog.shell.isDisposed() ) { return; } colInfo.setComboValues( fieldNames ); } } ); } } catch ( KettleException e ) { this.dialog.logError( this.toString(), "Error while reading fields", e ); // ignore any errors here. drop downs will not be // filled, but no problem for the user } } } }