public void analyseImpact(
      List<DatabaseImpact> impact,
      TransMeta transMeta,
      StepMeta stepMeta,
      RowMetaInterface prev,
      String[] input,
      String[] output,
      RowMetaInterface info,
      Repository repository,
      IMetaStore metaStore)
      throws KettleStepException {
    if (prev != null) {
      // Lookup: we do a lookup on the natural keys
      for (int i = 0; i < keyLookup.length; i++) {
        ValueMetaInterface v = prev.searchValueMeta(keyStream[i]);

        DatabaseImpact ii =
            new DatabaseImpact(
                DatabaseImpact.TYPE_IMPACT_READ,
                transMeta.getName(),
                stepMeta.getName(),
                databaseMeta.getDatabaseName(),
                tableName,
                keyLookup[i],
                keyStream[i],
                v != null ? v.getOrigin() : "?",
                "",
                "Type = " + v.toStringMeta());
        impact.add(ii);
      }

      // Insert update fields : read/write
      for (int i = 0; i < updateLookup.length; i++) {
        ValueMetaInterface v = prev.searchValueMeta(updateStream[i]);

        DatabaseImpact ii =
            new DatabaseImpact(
                DatabaseImpact.TYPE_IMPACT_READ_WRITE,
                transMeta.getName(),
                stepMeta.getName(),
                databaseMeta.getDatabaseName(),
                tableName,
                updateLookup[i],
                updateStream[i],
                v != null ? v.getOrigin() : "?",
                "",
                "Type = " + v.toStringMeta());
        impact.add(ii);
      }
    }
  }
  public void analyseImpact(
      List<DatabaseImpact> impact,
      TransMeta transMeta,
      StepMeta stepMeta,
      RowMetaInterface prev,
      String input[],
      String output[],
      RowMetaInterface info)
      throws KettleStepException {
    if (prev != null) {
      /* DEBUG CHECK THIS */
      // Insert dateMask fields : read/write
      for (int i = 0; i < fieldTable.length; i++) {
        ValueMetaInterface v = prev.searchValueMeta(fieldStream[i]);

        DatabaseImpact ii =
            new DatabaseImpact(
                DatabaseImpact.TYPE_IMPACT_READ_WRITE,
                transMeta.getName(),
                stepMeta.getName(),
                databaseMeta.getDatabaseName(),
                transMeta.environmentSubstitute(tableName),
                fieldTable[i],
                fieldStream[i],
                v != null ? v.getOrigin() : "?",
                "",
                "Type = " + v.toStringMeta()); // $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
        impact.add(ii);
      }
    }
  }
  public void analyseImpact(
      List<DatabaseImpact> impact,
      TransMeta transMeta,
      StepMeta stepMeta,
      RowMetaInterface prev,
      String[] input,
      String[] output,
      RowMetaInterface info)
      throws KettleStepException {
    if (prev != null) {
      // Lookup: we do a lookup on the natural keys
      for (int i = 0; i < keyLookup.length; i++) {
        ValueMetaInterface v = prev.searchValueMeta(keyStream[i]);

        DatabaseImpact ii =
            new DatabaseImpact(
                DatabaseImpact.TYPE_IMPACT_DELETE,
                transMeta.getName(),
                stepMeta.getName(),
                databaseMeta.getDatabaseName(),
                tableName,
                keyLookup[i],
                keyStream[i],
                v != null ? v.getOrigin() : "?",
                "",
                "Type = " + v.toStringMeta()); // $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
        impact.add(ii);
      }
    }
  }
  public void analyseImpact(
      List<DatabaseImpact> impact,
      TransMeta transMeta,
      StepMeta stepMeta,
      RowMetaInterface prev,
      String input[],
      String output[],
      RowMetaInterface info) {
    // The keys are read-only...
    for (int i = 0; i < keyField.length; i++) {
      ValueMetaInterface v = prev.searchValueMeta(keyField[i]);
      DatabaseImpact ii =
          new DatabaseImpact(
              DatabaseImpact.TYPE_IMPACT_READ_WRITE,
              transMeta.getName(),
              stepMeta.getName(),
              databaseWriteMeta.getDatabaseName(),
              tablename,
              keyLookup[i],
              keyField[i],
              v != null ? v.getOrigin() : "?", // $NON-NLS-1$
              "", //$NON-NLS-1$
              useHash
                  ? Messages.getString("ConcurrentCombinationLookupMeta.ReadAndInsert.Label")
                  : Messages.getString(
                      "ConcurrentCombinationLookupMeta.LookupAndInsert.Label") //$NON-NLS-1$
              // //$NON-NLS-2$
              );
      impact.add(ii);
    }

    // Do we lookup-on the hash-field?
    if (useHash) {
      DatabaseImpact ii =
          new DatabaseImpact(
              DatabaseImpact.TYPE_IMPACT_READ_WRITE,
              transMeta.getName(),
              stepMeta.getName(),
              databaseWriteMeta.getDatabaseName(),
              tablename,
              hashField,
              "", //$NON-NLS-1$
              "", //$NON-NLS-1$
              "", //$NON-NLS-1$
              Messages.getString("ConcurrentCombinationLookupMeta.KeyLookup.Label") // $NON-NLS-1$
              );
      impact.add(ii);
    }
  }
  public void analyseImpact(
      List<DatabaseImpact> impact,
      TransMeta transMeta,
      StepMeta stepinfo,
      RowMetaInterface prev,
      String input[],
      String output[],
      RowMetaInterface info) {
    // The keys are read-only...
    for (int i = 0; i < streamKeyField1.length; i++) {
      ValueMetaInterface v = prev.searchValueMeta(streamKeyField1[i]);
      DatabaseImpact ii =
          new DatabaseImpact(
              DatabaseImpact.TYPE_IMPACT_READ,
              transMeta.getName(),
              stepinfo.getName(),
              databaseMeta.getDatabaseName(),
              tablename,
              tableKeyField[i],
              streamKeyField1[i],
              v != null ? v.getOrigin() : "?", // $NON-NLS-1$
              "", //$NON-NLS-1$
              Messages.getString("DatabaseLookupMeta.Impact.Key") // $NON-NLS-1$
              );
      impact.add(ii);
    }

    // The Return fields are read-only too...
    for (int i = 0; i < returnValueField.length; i++) {
      DatabaseImpact ii =
          new DatabaseImpact(
              DatabaseImpact.TYPE_IMPACT_READ,
              transMeta.getName(),
              stepinfo.getName(),
              databaseMeta.getDatabaseName(),
              tablename,
              returnValueField[i],
              "", //$NON-NLS-1$
              "", //$NON-NLS-1$
              "", //$NON-NLS-1$
              Messages.getString("DatabaseLookupMeta.Impact.ReturnValue") // $NON-NLS-1$
              );
      impact.add(ii);
    }
  }
  public static ValueMetaInterface cloneValueMeta(ValueMetaInterface source, int targetType)
      throws KettlePluginException {
    ValueMetaInterface target = null;

    // If we're Cloneable and not changing types, call clone()
    if (source instanceof Cloneable && source.getType() == targetType) {
      target = source.clone();
    } else {
      target =
          createValueMeta(source.getName(), targetType, source.getLength(), source.getPrecision());
    }
    target.setConversionMask(source.getConversionMask());
    target.setDecimalSymbol(source.getDecimalSymbol());
    target.setGroupingSymbol(source.getGroupingSymbol());
    target.setStorageType(source.getStorageType());
    if (source.getStorageMetadata() != null) {
      target.setStorageMetadata(
          cloneValueMeta(source.getStorageMetadata(), source.getStorageMetadata().getType()));
    }
    target.setStringEncoding(source.getStringEncoding());
    target.setTrimType(source.getTrimType());
    target.setDateFormatLenient(source.isDateFormatLenient());
    target.setDateFormatLocale(source.getDateFormatLocale());
    target.setDateFormatTimeZone(source.getDateFormatTimeZone());
    target.setLenientStringToNumber(source.isLenientStringToNumber());
    target.setLargeTextField(source.isLargeTextField());
    target.setComments(source.getComments());
    target.setCaseInsensitive(source.isCaseInsensitive());
    target.setIndex(source.getIndex());

    target.setOrigin(source.getOrigin());

    target.setOriginalAutoIncrement(source.isOriginalAutoIncrement());
    target.setOriginalColumnType(source.getOriginalColumnType());
    target.setOriginalColumnTypeName(source.getOriginalColumnTypeName());
    target.setOriginalNullable(source.isOriginalNullable());
    target.setOriginalPrecision(source.getOriginalPrecision());
    target.setOriginalScale(source.getOriginalScale());
    target.setOriginalSigned(source.isOriginalSigned());

    return target;
  }
  /** Copy information from the meta-data input to the dialog fields. */
  public void getData() {
    int i;

    for (i = 0; i < input.size(); i++) {
      TableItem item = wFields.table.getItem(i);
      ValueMetaInterface v = input.getValueMeta(i);
      int idx = 1;
      if (v.getName() != null) {
        item.setText(idx++, v.getName());
      }
      item.setText(idx++, v.getTypeDesc());
      item.setText(idx++, v.getLength() < 0 ? "-" : "" + v.getLength());
      item.setText(idx++, v.getPrecision() < 0 ? "-" : "" + v.getPrecision());
      item.setText(idx++, Const.NVL(v.getOrigin(), ""));
      item.setText(idx++, ValueMeta.getStorageTypeCode(v.getStorageType()));
      item.setText(idx++, Const.NVL(v.getConversionMask(), ""));
      item.setText(idx++, Const.NVL(v.getCurrencySymbol(), ""));
      item.setText(idx++, Const.NVL(v.getDecimalSymbol(), ""));
      item.setText(idx++, Const.NVL(v.getGroupingSymbol(), ""));
      item.setText(idx++, ValueMeta.getTrimTypeDesc(v.getTrimType()));
      item.setText(idx++, Const.NVL(v.getComments(), ""));
    }
    wFields.optWidth(true);
  }
  /**
   * 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.
   */
  private void generateMappings() {

    // Determine the source and target fields...
    //
    RowMetaInterface sourceFields;
    RowMetaInterface targetFields;

    try {
      sourceFields = transMeta.getPrevStepFields(stepMeta);
    } catch (KettleException e) {
      new ErrorDialog(
          shell,
          BaseMessages.getString(
              PKG, "IngresVectorWiseLoaderDialog.DoMapping.UnableToFindSourceFields.Title"),
          BaseMessages.getString(
              PKG, "IngresVectorWiseLoaderDialog.DoMapping.UnableToFindSourceFields.Message"),
          e);
      return;
    }

    // refresh data
    input.setDatabaseMeta(transMeta.findDatabase(serverConnection.getText()));
    input.setTablename(transMeta.environmentSubstitute(wTable.getText()));
    StepMetaInterface stepMetaInterface = stepMeta.getStepMetaInterface();
    try {
      targetFields = stepMetaInterface.getRequiredFields(transMeta);
    } catch (KettleException e) {
      new ErrorDialog(
          shell,
          BaseMessages.getString(
              PKG, "IngresVectorWiseLoaderDialog.DoMapping.UnableToFindTargetFields.Title"),
          BaseMessages.getString(
              PKG, "IngresVectorWiseLoaderDialog.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>();
    StringBuffer missingSourceFields = new StringBuffer();
    StringBuffer missingTargetFields = new StringBuffer();

    int nrFields = wFields.nrNonEmpty();
    for (int i = 0; i < nrFields; i++) {
      TableItem item = wFields.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);
    }

    // show a confirm dialog if some missing field was found
    //
    if (missingSourceFields.length() > 0 || missingTargetFields.length() > 0) {

      String message = "";
      if (missingSourceFields.length() > 0) {
        message +=
            BaseMessages.getString(
                    PKG,
                    "IngresVectorWiseLoaderDialog.DoMapping.SomeSourceFieldsNotFound",
                    missingSourceFields.toString())
                + Const.CR;
      }
      if (missingTargetFields.length() > 0) {
        message +=
            BaseMessages.getString(
                    PKG,
                    "IngresVectorWiseLoaderDialog.DoMapping.SomeTargetFieldsNotFound",
                    missingSourceFields.toString())
                + Const.CR;
      }
      message += Const.CR;
      message +=
          BaseMessages.getString(
                  PKG, "IngresVectorWiseLoaderDialog.DoMapping.SomeFieldsNotFoundContinue")
              + Const.CR;
      MessageDialog.setDefaultImage(GUIResource.getInstance().getImageSpoon());
      boolean goOn =
          MessageDialog.openConfirm(
              shell,
              BaseMessages.getString(
                  PKG, "IngresVectorWiseLoaderDialog.DoMapping.SomeFieldsNotFoundTitle"),
              message);
      if (!goOn) {
        return;
      }
    }
    EnterMappingDialog d =
        new EnterMappingDialog(
            IngresVectorwiseLoaderDialog.this.shell,
            sourceFields.getFieldNames(),
            targetFields.getFieldNames(),
            mappings);
    mappings = d.open();

    // mappings == null if the user pressed cancel
    //
    if (mappings != null) {
      // Clear and re-populate!
      //
      wFields.table.removeAll();
      wFields.table.setItemCount(mappings.size());
      for (int i = 0; i < mappings.size(); i++) {
        SourceToTargetMapping mapping = mappings.get(i);
        TableItem item = wFields.table.getItem(i);
        item.setText(2, sourceFields.getValueMeta(mapping.getSourcePosition()).getName());
        item.setText(1, targetFields.getValueMeta(mapping.getTargetPosition()).getName());
      }
      wFields.setRowNums();
      wFields.optWidth(true);
    }
  }