private SapType getSapType(SAPField field) {
   String type = field.getType();
   if (type != null && type.startsWith("input_")) {
     type = type.substring("input_".length());
   } else if (type != null && type.startsWith("output_")) {
     type = type.substring("output_".length());
   }
   return SapType.findTypeForCode(type);
 }
  private void getInfo(SapInputMeta meta) {
    meta.setDatabaseMeta(transMeta.findDatabase(wConnection.getText()));
    meta.setFunction(function);

    // Grab the parameters...
    //
    meta.getParameters().clear();
    int nrParameters = wInput.nrNonEmpty();
    for (int i = 0; i < nrParameters; i++) {
      TableItem item = wInput.getNonEmpty(i);
      int colnr = 1;
      String fieldName = item.getText(colnr++);
      SapType sapType = SapType.findTypeForDescription(item.getText(colnr++));
      String tableName = item.getText(colnr++);
      String parameterName = item.getText(colnr++);
      int targetType = ValueMeta.getType(item.getText(colnr++));
      meta.getParameters()
          .add(new SapParameter(fieldName, sapType, tableName, parameterName, targetType));
    }

    // and the output fields.
    //
    meta.getOutputFields().clear();
    int nrFields = wOutput.nrNonEmpty();
    for (int i = 0; i < nrFields; i++) {
      TableItem item = wOutput.getNonEmpty(i);
      int colnr = 1;
      String sapFieldName = item.getText(colnr++);
      SapType sapType = SapType.findTypeForDescription(item.getText(colnr++));
      String tableName = item.getText(colnr++);
      String newName = item.getText(colnr++);
      int targetType = ValueMeta.getType(item.getText(colnr++));
      meta.getOutputFields()
          .add(new SapOutputField(sapFieldName, sapType, tableName, newName, targetType));
    }
  }
  private void get() {
    try {
      RowMetaInterface r = transMeta.getPrevStepFields(stepname);
      if (r != null && !r.isEmpty()) {
        TableItemInsertListener listener =
            new TableItemInsertListener() {
              public boolean tableItemInserted(TableItem tableItem, ValueMetaInterface v) {
                tableItem.setText(2, "=");
                return true;
              }
            };
        BaseStepDialog.getFieldsFromPrevious(
            r, wInput, 1, new int[] {1, 3}, new int[] {}, -1, -1, listener);
      }

      DatabaseMeta databaseMeta = transMeta.findDatabase(wConnection.getText());
      if (databaseMeta == null) {
        showDatabaseWarning(false);
        return;
      }

      // Fill in the parameters too
      //
      if (function != null) {

        wFunction.setText(function.getName());

        if (wInput.nrNonEmpty() != 0 || wOutput.nrNonEmpty() != 0) {
          MessageBox mb = new MessageBox(shell, SWT.YES | SWT.NO | SWT.ICON_QUESTION);
          mb.setMessage(
              BaseMessages.getString(PKG, "SapInputDialog.ClearInputOutput.DialogMessage"));
          mb.setText(BaseMessages.getString(PKG, "SapInputDialog.ClearInputOutput.DialogTitle"));
          int answer = mb.open();
          if (answer == SWT.NO) {
            return;
          }
        }

        wInput.clearAll(false);
        wOutput.clearAll(false);
        Cursor hourGlass = new Cursor(shell.getDisplay(), SWT.CURSOR_WAIT);
        SAPConnection sc = SAPConnectionFactory.create();
        try {
          shell.setCursor(hourGlass);
          sc.open(databaseMeta);
          SAPFunctionSignature signature = sc.getFunctionSignature(function);

          // Populate the input view
          // TODO: clean this up a bit, feels a bit messy
          //
          int rownr = 0;
          for (SAPField field : signature.getInput()) {
            TableItem item;
            if (rownr == 0) {
              item = wInput.table.getItem(0);
            } else {
              item = new TableItem(wInput.table, SWT.NONE);
            }
            rownr++;

            SapType type = getSapType(field);

            int colnr = 1;
            item.setText(colnr++, Const.NVL(field.getName(), ""));
            item.setText(colnr++, type == null ? "" : type.getDescription());
            item.setText(colnr++, Const.NVL(field.getTable(), ""));
            item.setText(colnr++, Const.NVL(field.getName(), ""));
            item.setText(colnr++, field.getTypePentaho());
          }
          wInput.setRowNums();
          wInput.optWidth(true);

          // Get the output rows
          //
          rownr = 0;
          for (SAPField field : signature.getOutput()) {
            TableItem item;
            if (rownr == 0) {
              item = wOutput.table.getItem(0);
            } else {
              item = new TableItem(wOutput.table, SWT.NONE);
            }
            rownr++;

            SapType type = getSapType(field);

            int colnr = 1;
            item.setText(colnr++, Const.NVL(field.getName(), ""));
            item.setText(colnr++, type == null ? "" : type.getDescription());
            item.setText(colnr++, Const.NVL(field.getTable(), ""));
            item.setText(colnr++, Const.NVL(field.getName(), ""));
            item.setText(colnr++, field.getTypePentaho());
          }
          wOutput.setRowNums();
          wOutput.optWidth(true);

        } catch (Exception e) {
          throw new KettleException(e);
        } finally {
          sc.close();
          shell.setCursor(null);
          hourGlass.dispose();
        }
      }
    } catch (KettleException ke) {
      new ErrorDialog(
          shell,
          BaseMessages.getString(PKG, "SapInputDialog.GetFieldsFailed.DialogTitle"),
          BaseMessages.getString(PKG, "SapInputDialog.GetFieldsFailed.DialogMessage"),
          ke);
    }
  }
  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);

    if (!SAPLibraryTester.isJCoLibAvailable()) {
      int style = SWT.ICON_ERROR;
      MessageBox messageBox = new MessageBox(shell, style);
      messageBox.setMessage(BaseMessages.getString(PKG, "SapInputDialog.JCoLibNotFound"));
      messageBox.open();
      // dispose();
      // return stepname;
    }

    if (!SAPLibraryTester.isJCoImplAvailable()) {
      int style = SWT.ICON_ERROR;
      MessageBox messageBox = new MessageBox(shell, style);
      messageBox.setMessage(BaseMessages.getString(PKG, "SapInputDialog.JCoImplNotFound"));
      messageBox.open();
      // dispose();
      // return stepname;
    }

    ModifyListener lsMod =
        new ModifyListener() {
          public void modifyText(ModifyEvent e) {
            input.setChanged();
          }
        };

    ModifyListener lsConnectionMod =
        new ModifyListener() {
          public void modifyText(ModifyEvent e) {
            input.setChanged();
          }
        };
    backupChanged = input.hasChanged();

    FormLayout formLayout = new FormLayout();
    formLayout.marginWidth = Const.FORM_MARGIN;
    formLayout.marginHeight = Const.FORM_MARGIN;

    shell.setLayout(formLayout);
    shell.setText(BaseMessages.getString(PKG, "SapInputDialog.shell.Title"));

    int middle = props.getMiddlePct();
    int margin = Const.MARGIN;

    // Stepname line
    wlStepname = new Label(shell, SWT.RIGHT);
    wlStepname.setText(BaseMessages.getString(PKG, "SapInputDialog.Stepname.Label"));
    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);
    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);
    Control lastControl = wStepname;

    // Connection line
    //
    wConnection = addConnectionLine(shell, lastControl, middle, margin);
    List<String> items = new ArrayList<String>();
    for (DatabaseMeta dbMeta : transMeta.getDatabases()) {
      if (dbMeta.getDatabaseInterface() instanceof SAPR3DatabaseMeta) {
        items.add(dbMeta.getName());
      }
    }
    wConnection.setItems(items.toArray(new String[items.size()]));
    if (input.getDatabaseMeta() == null && transMeta.nrDatabases() == 1) {
      wConnection.select(0);
    }
    wConnection.addModifyListener(lsConnectionMod);
    lastControl = wConnection;

    // Function
    //
    wlFunction = new Label(shell, SWT.RIGHT);
    wlFunction.setText(BaseMessages.getString(PKG, "SapInputDialog.Function.Label"));
    props.setLook(wlFunction);
    FormData fdlFunction = new FormData();
    fdlFunction.left = new FormAttachment(0, 0);
    fdlFunction.right = new FormAttachment(middle, -margin);
    fdlFunction.top = new FormAttachment(lastControl, margin);
    wlFunction.setLayoutData(fdlFunction);
    wbFunction = new Button(shell, SWT.PUSH);
    props.setLook(wbFunction);

    wbFunction.setText(BaseMessages.getString(PKG, "SapInputDialog.FindFunctionButton.Label"));
    FormData fdbFunction = new FormData();
    fdbFunction.right = new FormAttachment(100, 0);
    fdbFunction.top = new FormAttachment(lastControl, margin);
    wbFunction.setLayoutData(fdbFunction);
    wbFunction.addSelectionListener(
        new SelectionAdapter() {
          public void widgetSelected(SelectionEvent e) {
            getFunction();
          }
        });

    wFunction = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
    props.setLook(wFunction);
    wFunction.addModifyListener(
        new ModifyListener() {
          public void modifyText(ModifyEvent e) {
            function = new SAPFunction(((Text) e.widget).getText());
            input.setChanged();
          }
        });
    FormData fdFunction = new FormData();
    fdFunction.left = new FormAttachment(middle, 0);
    fdFunction.right = new FormAttachment(wbFunction, -margin);
    fdFunction.top = new FormAttachment(lastControl, margin);
    wFunction.setLayoutData(fdFunction);
    lastControl = wFunction;

    // The parameter input fields...
    //
    wlInput = new Label(shell, SWT.NONE);
    wlInput.setText(BaseMessages.getString(PKG, "SapInputDialog.Input.Label"));
    props.setLook(wlInput);
    FormData fdlInput = new FormData();
    fdlInput.left = new FormAttachment(0, 0);
    fdlInput.top = new FormAttachment(lastControl, margin);
    wlInput.setLayoutData(fdlInput);

    ColumnInfo[] ciKey =
        new ColumnInfo[] {
          new ColumnInfo(
              BaseMessages.getString(PKG, "SapInputDialog.ColumnInfo.Field"),
              ColumnInfo.COLUMN_TYPE_CCOMBO,
              new String[] {""},
              false),
          new ColumnInfo(
              BaseMessages.getString(PKG, "SapInputDialog.ColumnInfo.SAPType"),
              ColumnInfo.COLUMN_TYPE_CCOMBO,
              SapType.getDescriptions()),
          new ColumnInfo(
              BaseMessages.getString(PKG, "SapInputDialog.ColumnInfo.TableOrStruct"),
              ColumnInfo.COLUMN_TYPE_TEXT,
              false,
              false),
          new ColumnInfo(
              BaseMessages.getString(PKG, "SapInputDialog.ColumnInfo.SAPParameterName"),
              ColumnInfo.COLUMN_TYPE_TEXT,
              false,
              false),
          new ColumnInfo(
              BaseMessages.getString(PKG, "SapInputDialog.ColumnInfo.TargetType"),
              ColumnInfo.COLUMN_TYPE_CCOMBO,
              ValueMeta.getTypes()),
        };
    inputFieldColumns.add(ciKey[0]);

    wInput =
        new TableView(
            transMeta,
            shell,
            SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL,
            ciKey,
            input.getParameters().size(),
            lsMod,
            props);

    FormData fdInput = new FormData();
    fdInput.left = new FormAttachment(0, 0);
    fdInput.top = new FormAttachment(wlInput, margin);
    fdInput.right = new FormAttachment(100, 0);
    fdInput.bottom = new FormAttachment(40, 0);
    wInput.setLayoutData(fdInput);
    lastControl = wInput;

    // THE BUTTONS
    wOK = new Button(shell, SWT.PUSH);
    wOK.setText(BaseMessages.getString(PKG, "System.Button.OK"));
    // wPreview = new Button(shell, SWT.PUSH);
    // wPreview.setText(BaseMessages.getString(PKG, "System.Button.Preview"));
    wGet = new Button(shell, SWT.PUSH);
    wGet.setText(BaseMessages.getString(PKG, "SapInputDialog.GetFields.Button"));
    wCancel = new Button(shell, SWT.PUSH);
    wCancel.setText(BaseMessages.getString(PKG, "System.Button.Cancel"));
    wAbout = new Button(shell, SWT.PUSH);
    wAbout.setText(BaseMessages.getString(PKG, "SapInputDialog.About.Button"));
    // Preview not possible without inputRowSets in BaseStep.getRow()
    // setButtonPositions(new Button[] { wOK, wPreview, wAbout , wGet, wCancel}, margin, null);
    setButtonPositions(new Button[] {wOK, wAbout, wGet, wCancel}, margin, null);

    // The output fields...
    //
    wlOutput = new Label(shell, SWT.NONE);
    wlOutput.setText(BaseMessages.getString(PKG, "SapInputDialog.Output.Label"));
    props.setLook(wlOutput);
    FormData fdlOutput = new FormData();
    fdlOutput.left = new FormAttachment(0, 0);
    fdlOutput.top = new FormAttachment(wInput, margin);
    wlOutput.setLayoutData(fdlOutput);

    ColumnInfo[] ciReturn =
        new ColumnInfo[] {
          new ColumnInfo(
              BaseMessages.getString(PKG, "SapInputDialog.ColumnInfo.SAPField"),
              ColumnInfo.COLUMN_TYPE_CCOMBO,
              new String[] {},
              false),
          new ColumnInfo(
              BaseMessages.getString(PKG, "SapInputDialog.ColumnInfo.SAPType"),
              ColumnInfo.COLUMN_TYPE_CCOMBO,
              SapType.getDescriptions(),
              false),
          new ColumnInfo(
              BaseMessages.getString(PKG, "SapInputDialog.ColumnInfo.TableOrStruct"),
              ColumnInfo.COLUMN_TYPE_TEXT,
              false),
          new ColumnInfo(
              BaseMessages.getString(PKG, "SapInputDialog.ColumnInfo.NewName"),
              ColumnInfo.COLUMN_TYPE_TEXT,
              false),
          new ColumnInfo(
              BaseMessages.getString(PKG, "SapInputDialog.ColumnInfo.TargetType"),
              ColumnInfo.COLUMN_TYPE_CCOMBO,
              ValueMeta.getTypes()),
        };
    outputFieldColumns.add(ciReturn[0]);

    wOutput =
        new TableView(
            transMeta,
            shell,
            SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL,
            ciReturn,
            input.getOutputFields().size(),
            lsMod,
            props);

    FormData fdOutput = new FormData();
    fdOutput.left = new FormAttachment(0, 0);
    fdOutput.top = new FormAttachment(wlOutput, margin);
    fdOutput.right = new FormAttachment(100, 0);
    fdOutput.bottom = new FormAttachment(wOK, -8 * margin);
    wOutput.setLayoutData(fdOutput);
    lastControl = wOutput;

    this.wAscLink = new Link(this.shell, SWT.NONE);
    FormData fdAscLink = new FormData();
    fdAscLink.left = new FormAttachment(0, 0);
    fdAscLink.top = new FormAttachment(wOutput, margin);
    wAscLink.setLayoutData(fdAscLink);
    this.wAscLink.setText(BaseMessages.getString(PKG, "SapInputDialog.Provided.Info"));
    lastControl = wAscLink;

    // Add listeners
    lsOK =
        new Listener() {
          public void handleEvent(Event e) {
            ok();
          }
        };
    lsPreview =
        new Listener() {
          public void handleEvent(Event e) {
            preview();
          }
        };
    lsGet =
        new Listener() {
          public void handleEvent(Event e) {
            get();
          }
        };
    lsCancel =
        new Listener() {
          public void handleEvent(Event e) {
            cancel();
          }
        };
    Listener lsAbout =
        new Listener() {
          public void handleEvent(Event e) {
            about();
          }
        };

    wOK.addListener(SWT.Selection, lsOK);
    // wPreview.addListener(SWT.Selection, lsPreview);
    wGet.addListener(SWT.Selection, lsGet);
    wCancel.addListener(SWT.Selection, lsCancel);
    this.wAbout.addListener(SWT.Selection, lsAbout);

    this.wAscLink.addListener(
        SWT.Selection,
        new Listener() {
          public void handleEvent(final Event event) {
            Program.launch(event.text);
          }
        });

    lsDef =
        new SelectionAdapter() {
          public void widgetDefaultSelected(SelectionEvent e) {
            ok();
          }
        };

    wStepname.addSelectionListener(lsDef);
    wFunction.addSelectionListener(lsDef);

    // Detect X or ALT-F4 or something that kills this window...
    shell.addShellListener(
        new ShellAdapter() {
          public void shellClosed(ShellEvent e) {
            cancel();
          }
        });

    getData();

    // Set the shell size, based upon previous time...
    setSize();

    input.setChanged(backupChanged);

    setComboValues();
    shell.open();
    while (!shell.isDisposed()) {
      if (!display.readAndDispatch()) {
        display.sleep();
      }
    }
    return stepname;
  }