package bi.know.kettle.neo4j.steps.graph; import bi.know.kettle.neo4j.model.GraphModelUtils; import bi.know.kettle.neo4j.shared.NeoConnectionUtils; import org.apache.commons.lang.StringUtils; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CCombo; 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.widgets.Button; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.Text; import org.neo4j.kettle.core.metastore.MetaStoreFactory; import org.neo4j.kettle.model.GraphModel; import org.neo4j.kettle.model.GraphNode; import org.neo4j.kettle.model.GraphProperty; import org.neo4j.kettle.model.GraphRelationship; import org.neo4j.kettle.shared.NeoConnection; import org.pentaho.di.core.Const; import org.pentaho.di.core.SourceToTargetMapping; import org.pentaho.di.core.exception.KettleException; import org.pentaho.di.core.exception.KettleStepException; import org.pentaho.di.core.logging.LogChannel; import org.pentaho.di.core.row.RowMetaInterface; 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.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.TableView; import org.pentaho.di.ui.core.widget.TextVar; import org.pentaho.di.ui.spoon.Spoon; import org.pentaho.di.ui.trans.step.BaseStepDialog; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; public class GraphOutputDialog extends BaseStepDialog implements StepDialogInterface { private static Class<?> PKG = GraphOutputMeta.class; // for i18n purposes, needed by Translator2!! private Text wStepname; private Label wlConnection; private CCombo wConnection; private Button wEditConnection; private Button wNewConnection; private CCombo wModel; private Label wlBatchSize; private TextVar wBatchSize; private Label wlCreateIndexes; private Button wCreateIndexes; private Button wReturnGraph; private Label wlReturnGraphField; private TextVar wReturnGraphField; private Button wValidateAgainstModel; private TableView wFieldMappings; private GraphOutputMeta input; private GraphModel activeModel; public GraphOutputDialog( Shell parent, Object inputMetadata, TransMeta transMeta, String stepname ) { super( parent, (BaseStepMeta) inputMetadata, transMeta, stepname ); input = (GraphOutputMeta) inputMetadata; // Hack the metastore... // metaStore = Spoon.getInstance().getMetaStore(); } @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 = 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( "Neo4j GraphOutput" ); int middle = props.getMiddlePct(); int margin = Const.MARGIN; // Step name line // Label wlStepname = new Label( shell, SWT.RIGHT ); wlStepname.setText( "Step name" ); props.setLook( wlStepname ); fdlStepname = new FormData(); fdlStepname.left = new FormAttachment( 0, 0 ); fdlStepname.right = new FormAttachment( middle, -margin ); fdlStepname.top = new FormAttachment( 0, margin ); wlStepname.setLayoutData( fdlStepname ); wStepname = new Text( shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER ); props.setLook( wStepname ); wStepname.addModifyListener( lsMod ); fdStepname = new FormData(); fdStepname.left = new FormAttachment( middle, 0 ); fdStepname.top = new FormAttachment( wlStepname, 0, SWT.CENTER ); fdStepname.right = new FormAttachment( 100, 0 ); wStepname.setLayoutData( fdStepname ); Control lastControl = wStepname; // The connection line of items : Label, Combo, NewButton, EditButton // wlConnection = new Label( shell, SWT.RIGHT ); wlConnection.setText( "Connection" ); props.setLook( wlConnection ); FormData fdlConnection = new FormData(); fdlConnection.left = new FormAttachment( 0, 0 ); fdlConnection.right = new FormAttachment( middle, -margin ); fdlConnection.top = new FormAttachment( lastControl, 2 * margin ); wlConnection.setLayoutData( fdlConnection ); wEditConnection = new Button( shell, SWT.PUSH | SWT.BORDER ); wEditConnection.setText( BaseMessages.getString( PKG, "System.Button.Edit" ) ); FormData fdEditConnection = new FormData(); fdEditConnection.top = new FormAttachment( wlConnection, 0, SWT.CENTER ); fdEditConnection.right = new FormAttachment( 100, 0 ); wEditConnection.setLayoutData( fdEditConnection ); wNewConnection = new Button( shell, SWT.PUSH | SWT.BORDER ); wNewConnection.setText( BaseMessages.getString( PKG, "System.Button.New" ) ); FormData fdNewConnection = new FormData(); fdNewConnection.top = new FormAttachment( wlConnection, 0, SWT.CENTER ); fdNewConnection.right = new FormAttachment( wEditConnection, -margin ); wNewConnection.setLayoutData( fdNewConnection ); wConnection = new CCombo( shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER ); props.setLook( wConnection ); wConnection.addModifyListener( lsMod ); FormData fdConnection = new FormData(); fdConnection.left = new FormAttachment( middle, 0 ); fdConnection.right = new FormAttachment( wNewConnection, -margin ); fdConnection.top = new FormAttachment( wlConnection, 0, SWT.CENTER ); wConnection.setLayoutData( fdConnection ); lastControl = wConnection; // The model line of items : Label, Combo, NewButton, EditButton // Label wlModel = new Label( shell, SWT.RIGHT ); wlModel.setText( "Model" ); props.setLook( wlModel ); FormData fdlModel = new FormData(); fdlModel.left = new FormAttachment( 0, 0 ); fdlModel.right = new FormAttachment( middle, -margin ); fdlModel.top = new FormAttachment( lastControl, 2 * margin ); wlModel.setLayoutData( fdlModel ); Button wEditModel = new Button( shell, SWT.PUSH | SWT.BORDER ); wEditModel.setText( BaseMessages.getString( PKG, "System.Button.Edit" ) ); FormData fdEditModel = new FormData(); fdEditModel.top = new FormAttachment( wlModel, 0, SWT.CENTER ); fdEditModel.right = new FormAttachment( 100, 0 ); wEditModel.setLayoutData( fdEditModel ); Button wNewModel = new Button( shell, SWT.PUSH | SWT.BORDER ); wNewModel.setText( BaseMessages.getString( PKG, "System.Button.New" ) ); FormData fdNewModel = new FormData(); fdNewModel.top = new FormAttachment( wlModel, 0, SWT.CENTER ); fdNewModel.right = new FormAttachment( wEditModel, -margin ); wNewModel.setLayoutData( fdNewModel ); wModel = new CCombo( shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER ); props.setLook( wModel ); wModel.addModifyListener( lsMod ); FormData fdModel = new FormData(); fdModel.left = new FormAttachment( middle, 0 ); fdModel.right = new FormAttachment( wNewModel, -margin ); fdModel.top = new FormAttachment( wlModel, 0, SWT.CENTER ); wModel.setLayoutData( fdModel ); lastControl = wModel; wlBatchSize = new Label( shell, SWT.RIGHT ); wlBatchSize.setText( "Batch size (rows)" ); props.setLook( wlBatchSize ); FormData fdlBatchSize = new FormData(); fdlBatchSize.left = new FormAttachment( 0, 0 ); fdlBatchSize.right = new FormAttachment( middle, -margin ); fdlBatchSize.top = new FormAttachment( lastControl, 2 * margin ); wlBatchSize.setLayoutData( fdlBatchSize ); wBatchSize = new TextVar( transMeta, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER ); props.setLook( wBatchSize ); wBatchSize.addModifyListener( lsMod ); FormData fdBatchSize = new FormData(); fdBatchSize.left = new FormAttachment( middle, 0 ); fdBatchSize.right = new FormAttachment( 100, 0 ); fdBatchSize.top = new FormAttachment( wlBatchSize, 0, SWT.CENTER ); wBatchSize.setLayoutData( fdBatchSize ); lastControl = wBatchSize; wlCreateIndexes = new Label( shell, SWT.RIGHT ); wlCreateIndexes.setText( "Create indexes? " ); wlCreateIndexes.setToolTipText( "Create index on first row using label field and primary key properties." ); props.setLook( wlCreateIndexes ); FormData fdlCreateIndexes = new FormData(); fdlCreateIndexes.left = new FormAttachment( 0, 0 ); fdlCreateIndexes.right = new FormAttachment( middle, -margin ); fdlCreateIndexes.top = new FormAttachment( lastControl, 2 * margin ); wlCreateIndexes.setLayoutData( fdlCreateIndexes ); wCreateIndexes = new Button( shell, SWT.CHECK | SWT.BORDER ); wCreateIndexes.setToolTipText( "Create index on first row using label field and primary key properties." ); props.setLook( wCreateIndexes ); FormData fdCreateIndexes = new FormData(); fdCreateIndexes.left = new FormAttachment( middle, 0 ); fdCreateIndexes.right = new FormAttachment( 100, 0 ); fdCreateIndexes.top = new FormAttachment( wlCreateIndexes, 0, SWT.CENTER ); wCreateIndexes.setLayoutData( fdCreateIndexes ); lastControl = wCreateIndexes; Label wlReturnGraph = new Label( shell, SWT.RIGHT ); wlReturnGraph.setText( "Return graph data?" ); String returnGraphTooltipText = "The update data to be updated in the form of Graph a value in the output of this step"; wlReturnGraph.setToolTipText( returnGraphTooltipText ); props.setLook( wlReturnGraph ); FormData fdlReturnGraph = new FormData(); fdlReturnGraph.left = new FormAttachment( 0, 0 ); fdlReturnGraph.right = new FormAttachment( middle, -margin ); fdlReturnGraph.top = new FormAttachment( lastControl, 2 * margin ); wlReturnGraph.setLayoutData( fdlReturnGraph ); wReturnGraph = new Button( shell, SWT.CHECK | SWT.BORDER ); wReturnGraph.setToolTipText( returnGraphTooltipText ); props.setLook( wReturnGraph ); FormData fdReturnGraph = new FormData(); fdReturnGraph.left = new FormAttachment( middle, 0 ); fdReturnGraph.right = new FormAttachment( 100, 0 ); fdReturnGraph.top = new FormAttachment( wlReturnGraph, 0, SWT.CENTER ); wReturnGraph.setLayoutData( fdReturnGraph ); wReturnGraph.addListener( SWT.Selection, e -> enableFields() ); lastControl = wReturnGraph; wlReturnGraphField = new Label( shell, SWT.RIGHT ); wlReturnGraphField.setText( "Graph output field name" ); props.setLook( wlReturnGraphField ); FormData fdlReturnGraphField = new FormData(); fdlReturnGraphField.left = new FormAttachment( 0, 0 ); fdlReturnGraphField.right = new FormAttachment( middle, -margin ); fdlReturnGraphField.top = new FormAttachment( lastControl, 2 * margin ); wlReturnGraphField.setLayoutData( fdlReturnGraphField ); wReturnGraphField = new TextVar( transMeta, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER ); props.setLook( wReturnGraphField ); wReturnGraphField.addModifyListener( lsMod ); FormData fdReturnGraphField = new FormData(); fdReturnGraphField.left = new FormAttachment( middle, 0 ); fdReturnGraphField.right = new FormAttachment( 100, 0 ); fdReturnGraphField.top = new FormAttachment( wlReturnGraphField, 0, SWT.CENTER ); wReturnGraphField.setLayoutData( fdReturnGraphField ); lastControl = wReturnGraphField; Label wlValidateAgainstModel = new Label( shell, SWT.RIGHT ); wlValidateAgainstModel.setText( "Validate against model?" ); wlValidateAgainstModel.setToolTipText( "This validates indexes, constraints and properties as specified in the model" ); props.setLook( wlValidateAgainstModel ); FormData fdlValidateAgainstModel = new FormData(); fdlValidateAgainstModel.left = new FormAttachment( 0, 0 ); fdlValidateAgainstModel.right = new FormAttachment( middle, -margin ); fdlValidateAgainstModel.top = new FormAttachment( lastControl, 2 * margin ); wlValidateAgainstModel.setLayoutData( fdlValidateAgainstModel ); wValidateAgainstModel = new Button( shell, SWT.CHECK | SWT.BORDER ); wValidateAgainstModel.setToolTipText( returnGraphTooltipText ); props.setLook( wValidateAgainstModel ); FormData fdValidateAgainstModel = new FormData(); fdValidateAgainstModel.left = new FormAttachment( middle, 0 ); fdValidateAgainstModel.right = new FormAttachment( 100, 0 ); fdValidateAgainstModel.top = new FormAttachment( wlValidateAgainstModel, 0, SWT.CENTER ); wValidateAgainstModel.setLayoutData( fdValidateAgainstModel ); wValidateAgainstModel.addListener( SWT.Selection, e -> enableFields() ); lastControl = wValidateAgainstModel; // Some buttons at the bottom... // wOK = new Button( shell, SWT.PUSH ); wOK.setText( BaseMessages.getString( PKG, "System.Button.OK" ) ); Button wMapping = new Button( shell, SWT.PUSH ); wMapping.setText( "Map fields" ); wCancel = new Button( shell, SWT.PUSH ); wCancel.setText( BaseMessages.getString( PKG, "System.Button.Cancel" ) ); // Position the buttons at the bottom of the dialog. // setButtonPositions( new Button[] { wOK, wMapping, wCancel }, margin, null ); String[] fieldNames; try { fieldNames = transMeta.getPrevStepFields( stepname ).getFieldNames(); } catch ( Exception e ) { logError( "Unable to get fields from previous steps", e ); fieldNames = new String[] {}; } // Table: field to model mapping // ColumnInfo[] parameterColumns = new ColumnInfo[] { new ColumnInfo( "Field", ColumnInfo.COLUMN_TYPE_CCOMBO, fieldNames, false ), new ColumnInfo( "Target type", ColumnInfo.COLUMN_TYPE_CCOMBO, ModelTargetType.getNames(), false ), new ColumnInfo( "Target", ColumnInfo.COLUMN_TYPE_CCOMBO, new String[ 0 ], false ), new ColumnInfo( "Property", ColumnInfo.COLUMN_TYPE_CCOMBO, new String[ 0 ], false ), }; Label wlFieldMappings = new Label( shell, SWT.LEFT ); wlFieldMappings.setText( "Mappings..." ); props.setLook( wlFieldMappings ); FormData fdlFieldMappings = new FormData(); fdlFieldMappings.left = new FormAttachment( 0, 0 ); fdlFieldMappings.right = new FormAttachment( middle, -margin ); fdlFieldMappings.top = new FormAttachment( lastControl, margin ); wlFieldMappings.setLayoutData( fdlFieldMappings ); wFieldMappings = new TableView( transMeta, shell, SWT.FULL_SELECTION | SWT.MULTI, parameterColumns, input.getFieldModelMappings().size(), lsMod, props ); props.setLook( wFieldMappings ); wFieldMappings.addModifyListener( lsMod ); FormData fdFieldMappings = new FormData(); fdFieldMappings.left = new FormAttachment( 0, 0 ); fdFieldMappings.right = new FormAttachment( 100, 0 ); fdFieldMappings.top = new FormAttachment( wlFieldMappings, margin ); fdFieldMappings.bottom = new FormAttachment( wOK, -margin * 2 ); wFieldMappings.setLayoutData( fdFieldMappings ); lastControl = wFieldMappings; // Add listeners lsCancel = e -> cancel(); lsOK = e -> ok(); wCancel.addListener( SWT.Selection, lsCancel ); wOK.addListener( SWT.Selection, lsOK ); wMapping.addListener( SWT.Selection, ( e ) -> enterMapping() ); lsDef = new SelectionAdapter() { public void widgetDefaultSelected( SelectionEvent e ) { ok(); } }; wConnection.addSelectionListener( lsDef ); wStepname.addSelectionListener( lsDef ); wBatchSize.addSelectionListener( lsDef ); wReturnGraph.addSelectionListener( lsDef ); wNewConnection.addListener( SWT.Selection, e -> newConnection() ); wEditConnection.addListener( SWT.Selection, e -> editConnection() ); wNewModel.addListener( SWT.Selection, e -> newModel() ); wEditModel.addListener( SWT.Selection, e -> editModel() ); // Detect X or ALT-F4 or something that kills this window... shell.addShellListener( new ShellAdapter() { 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; } private void enableFields() { boolean toNeo = !wReturnGraph.getSelection(); wlConnection.setEnabled( toNeo ); wConnection.setEnabled( toNeo ); wEditConnection.setEnabled( toNeo ); wNewConnection.setEnabled( toNeo ); wlBatchSize.setEnabled( toNeo ); wBatchSize.setEnabled( toNeo ); wlCreateIndexes.setEnabled( toNeo ); wCreateIndexes.setEnabled( toNeo ); wlReturnGraphField.setEnabled( !toNeo ); wReturnGraphField.setEnabled( !toNeo ); } private void enterMapping() { // Map input field names to Node/Property values // try { MetaStoreFactory<GraphModel> modelFactory = GraphModelUtils.getModelFactory( metaStore ); if ( activeModel == null ) { if ( StringUtils.isEmpty( wModel.getText() ) ) { return; } activeModel = modelFactory.loadElement( wModel.getText() ); } // Input fields // RowMetaInterface inputRowMeta = transMeta.getPrevStepFields( stepMeta ); String[] inputFields = inputRowMeta.getFieldNames(); // Node properties // String separator = " . "; List<String> targetPropertiesList = new ArrayList<>(); for ( GraphNode node : activeModel.getNodes() ) { for ( GraphProperty property : node.getProperties() ) { String combo = node.getName() + " . " + property.getName(); targetPropertiesList.add( combo ); } } for ( GraphRelationship relationship : activeModel.getRelationships() ) { for ( GraphProperty property : relationship.getProperties() ) { String combo = relationship.getName() + " . " + property.getName(); targetPropertiesList.add( combo ); } } String[] targetProperties = targetPropertiesList.toArray( new String[ 0 ] ); // Preserve mappings... // List<SourceToTargetMapping> mappings = new ArrayList<>(); for ( int i = 0; i < wFieldMappings.nrNonEmpty(); i++ ) { TableItem item = wFieldMappings.getNonEmpty( i ); int sourceIndex = Const.indexOfString( item.getText( 1 ), inputFields ); int targetIndex = Const.indexOfString( item.getText( 3 ) + separator + item.getText( 4 ), targetProperties ); if (sourceIndex>=0 && targetIndex>=0) { mappings.add( new SourceToTargetMapping( sourceIndex, targetIndex ) ); } } EnterMappingDialog dialog = new EnterMappingDialog( shell, inputFields, targetProperties, mappings ); mappings = dialog.open(); if ( mappings != null ) { wFieldMappings.clearAll(); for ( SourceToTargetMapping mapping : mappings ) { String field = mapping.getSourceString( inputFields ); String target = mapping.getTargetString( targetProperties ); int index = target.indexOf( separator ); String targetName = target.substring( 0, index ); String property = target.substring( index + separator.length() ); String targetType = null; if (activeModel.findNode( targetName )!=null) { targetType = "Node"; } else if (activeModel.findRelationship( targetName )!=null) { targetType = "Relationship"; } else { throw new KettleException( "Neither node nor transformation found for target '"+targetName+": internal error" ); } wFieldMappings.add( field, targetType, targetName, property ); } wFieldMappings.removeEmptyRows(); wFieldMappings.setRowNums(); wFieldMappings.optWidth( true ); } } catch ( Exception e ) { new ErrorDialog( shell, "Error", "Error mapping input fields to node properties", e ); } } private void cancel() { stepname = null; input.setChanged( changed ); dispose(); } public void getData() { wStepname.setText( Const.NVL( stepname, "" ) ); wConnection.setText( Const.NVL( input.getConnectionName(), "" ) ); updateConnectionsCombo(); wModel.setText( Const.NVL( input.getModel(), "" ) ); updateModelsCombo(); wBatchSize.setText( Const.NVL( input.getBatchSize(), "" ) ); wCreateIndexes.setSelection( input.isCreatingIndexes() ); for ( int i = 0; i < input.getFieldModelMappings().size(); i++ ) { FieldModelMapping mapping = input.getFieldModelMappings().get( i ); TableItem item = wFieldMappings.table.getItem( i ); int idx = 1; item.setText( idx++, Const.NVL( mapping.getField(), "" ) ); item.setText( idx++, ModelTargetType.getCode( mapping.getTargetType() ) ); item.setText( idx++, Const.NVL( mapping.getTargetName(), "" ) ); item.setText( idx++, Const.NVL( mapping.getTargetProperty(), "" ) ); } wFieldMappings.removeEmptyRows(); wFieldMappings.setRowNums(); wFieldMappings.optWidth( true ); wReturnGraph.setSelection( input.isReturningGraph() ); wReturnGraphField.setText( Const.NVL( input.getReturnGraphField(), "" ) ); wValidateAgainstModel.setSelection( input.isValidatingAgainstModel() ); enableFields(); } private void updateModelsCombo() { // List of models... // try { MetaStoreFactory<GraphModel> modelFactory = GraphModelUtils.getModelFactory( metaStore ); List<String> modelNames = modelFactory.getElementNames(); Collections.sort( modelNames ); wModel.setItems( modelNames.toArray( new String[ 0 ] ) ); // Importer the active model... // if ( StringUtils.isNotEmpty( wModel.getText() ) ) { activeModel = modelFactory.loadElement( wModel.getText() ); if ( activeModel != null ) { // Set combo boxes in the mappings... // List<String> targetNames = new ArrayList<>( ); targetNames.addAll( Arrays.asList(activeModel.getNodeNames()) ); targetNames.addAll( Arrays.asList(activeModel.getRelationshipNames()) ); wFieldMappings.getColumns()[ 2 ].setComboValues( activeModel.getNodeNames() ); } } else { activeModel = null; } } catch ( Exception e ) { new ErrorDialog( shell, "Error", "Unable to list Neo4j Graph Models", e ); } } private void updateConnectionsCombo() { // List of connections... // try { List<String> elementNames = NeoConnectionUtils.getConnectionFactory( metaStore ).getElementNames(); Collections.sort( elementNames ); wConnection.setItems( elementNames.toArray( new String[ 0 ] ) ); } catch ( Exception e ) { new ErrorDialog( shell, "Error", "Unable to list Neo4j connections", e ); } } private void ok() { if ( StringUtils.isEmpty( wStepname.getText() ) ) { return; } stepname = wStepname.getText(); // return value input.setConnectionName( wConnection.getText() ); input.setBatchSize( wBatchSize.getText() ); input.setCreatingIndexes( wCreateIndexes.getSelection() ); input.setModel( wModel.getText() ); input.setReturningGraph( wReturnGraph.getSelection() ); input.setReturnGraphField( wReturnGraphField.getText() ); input.setValidatingAgainstModel( wValidateAgainstModel.getSelection() ); List<FieldModelMapping> mappings = new ArrayList<>(); for ( int i = 0; i < wFieldMappings.nrNonEmpty(); i++ ) { TableItem item = wFieldMappings.getNonEmpty( i ); int idx = 1; String sourceField = item.getText( idx++ ); ModelTargetType targetType = ModelTargetType.parseCode( item.getText( idx++ ) ); String targetName = item.getText( idx++ ); String targetProperty = item.getText( idx++ ); mappings.add( new FieldModelMapping( sourceField, targetType, targetName, targetProperty ) ); } input.setFieldModelMappings( mappings ); dispose(); } protected void newConnection() { NeoConnection connection = NeoConnectionUtils.newConnection( shell, transMeta, NeoConnectionUtils.getConnectionFactory( metaStore ) ); if ( connection != null ) { wConnection.setText( connection.getName() ); updateModelsCombo(); } } protected void editConnection() { NeoConnectionUtils.editConnection( shell, transMeta, NeoConnectionUtils.getConnectionFactory( metaStore ), wConnection.getText() ); } protected void newModel() { GraphModel model = GraphModelUtils.newModel( shell, GraphModelUtils.getModelFactory( metaStore ), getInputRowMeta() ); if ( model != null ) { wModel.setText( model.getName() ); updateModelsCombo(); } } private RowMetaInterface getInputRowMeta() { RowMetaInterface inputRowMeta = null; try { inputRowMeta = transMeta.getPrevStepFields( stepname ); } catch ( KettleStepException e ) { LogChannel.GENERAL.logError( "Unable to find step input field", e ); } return inputRowMeta; } protected void editModel() { GraphModelUtils.editModel( shell, GraphModelUtils.getModelFactory( metaStore ), wModel.getText(), getInputRowMeta() ); updateModelsCombo(); } }