public void init(
      INode node,
      IElementParameter schemaParam,
      IMetadataTable currentOutputMetadata,
      IMetadataTable newOutputMetadata) {
    this.node = node;
    this.schemaParam = schemaParam;
    if (schemaParam == null) {
      if (newOutputMetadata.getAttachedConnector() != null) {
        currentConnector = newOutputMetadata.getAttachedConnector();
      } else {
        if (node.isELTComponent()) {
          currentConnector = EConnectionType.TABLE.getName();
        } else {
          currentConnector = EConnectionType.FLOW_MAIN.getName();
        }
      }
      for (IElementParameter param : node.getElementParameters()) {
        if (param.getFieldType().equals(EParameterFieldType.SCHEMA_TYPE)
            && param.getContext().equals(currentConnector)) {
          this.schemaParam = param;
        }
      }
    } else {
      currentConnector = this.schemaParam.getContext();
    }

    this.inputNode = null;
    this.currentInputMetadata = null;
    this.newInputMetadata = null;
    oldInputMetadata = null;
    this.currentOutputMetadata = currentOutputMetadata;
    if (this.currentOutputMetadata == null) {
      this.currentOutputMetadata = node.getMetadataFromConnector(currentConnector);
    }
    if (currentOutputMetadata == null && newOutputMetadata != null) {
      currentOutputMetadata = newOutputMetadata.clone(true);
    }
    oldOutputMetadata = this.currentOutputMetadata.clone(true);
    this.newOutputMetadata = newOutputMetadata.clone(true);
    this.newOutputMetadata.setReadOnly(this.currentOutputMetadata.isReadOnly());
    initializeContainer();
    setLabel(Messages.getString("ChangeMetadataCommand.changeMetadataValues")); // $NON-NLS-1$
  }
 public ChangeMetadataCommand(
     INode node,
     IElementParameter schemaParam,
     INode inputNode,
     IMetadataTable currentInputMetadata,
     IMetadataTable newInputMetadata,
     IMetadataTable currentOutputMetadata,
     IMetadataTable newOutputMetadata) {
   this.node = node;
   this.inputNode = inputNode;
   this.schemaParam = schemaParam;
   if (schemaParam == null) {
     currentConnector = EConnectionType.FLOW_MAIN.getName();
     for (IElementParameter param : node.getElementParameters()) {
       if ((param.getFieldType().equals(EParameterFieldType.SCHEMA_TYPE)
               || param.getFieldType().equals(EParameterFieldType.DCSCHEMA))
           && param.getContext().equals(currentConnector)) {
         this.schemaParam = param;
       }
     }
   } else {
     currentConnector = this.schemaParam.getContext();
   }
   this.currentInputMetadata = currentInputMetadata;
   if (currentInputMetadata != null) {
     oldInputMetadata = currentInputMetadata.clone();
   } else {
     oldInputMetadata = null;
   }
   this.newInputMetadata = newInputMetadata;
   this.currentOutputMetadata = currentOutputMetadata;
   if (this.currentOutputMetadata == null) {
     this.currentOutputMetadata = node.getMetadataFromConnector(currentConnector);
   }
   oldOutputMetadata = this.currentOutputMetadata.clone();
   this.newOutputMetadata = newOutputMetadata;
   initializeContainer();
   setLabel(Messages.getString("ChangeMetadataCommand.changeMetadataValues")); // $NON-NLS-1$
 }
  @Override
  public void execute() {
    propagatedChange.clear();

    propagateDatas(true);
    if (currentInputMetadata != null) {
      if (!currentInputMetadata.sameMetadataAs(newInputMetadata, IMetadataColumn.OPTIONS_NONE)) {
        if (!currentInputMetadata.sameMetadataAs(
            newInputMetadata, IMetadataColumn.OPTIONS_IGNORE_USED)) {
          String type = (String) inputNode.getPropertyValue(EParameterName.SCHEMA_TYPE.getName());
          if (type != null) {
            if (type.equals(EmfComponent.REPOSITORY)) {
              inputWasRepository = true;
              inputNode.setPropertyValue(
                  EParameterName.SCHEMA_TYPE.getName(), EmfComponent.BUILTIN);
            }
          }
        }
        MetadataToolHelper.copyTable(newInputMetadata, currentInputMetadata);
      }
    }

    if (!currentOutputMetadata.sameMetadataAs(newOutputMetadata, IMetadataColumn.OPTIONS_NONE)) {
      if (!currentOutputMetadata.sameMetadataAs(
          newOutputMetadata, IMetadataColumn.OPTIONS_IGNORE_USED)) {
        String type = (String) node.getPropertyValue(EParameterName.SCHEMA_TYPE.getName());
        if (type != null && type.equals(EmfComponent.REPOSITORY) && !repositoryMode) {
          // for one node has several schema_type,set mode for the current one
          if ((node.getElementParameter("SCHEMA_TYPE")
              .getContext()
              .equals(currentOutputMetadata.getAttachedConnector()))) {
            outputWasRepository = true;
            node.setPropertyValue(EParameterName.SCHEMA_TYPE.getName(), EmfComponent.BUILTIN);
          }
        }
      }
      MetadataToolHelper.copyTable(newOutputMetadata, currentOutputMetadata);
    }
    if (inputSchemaParam != null
        && inputSchemaParam.getChildParameters().get(EParameterName.SCHEMA_TYPE.getName()) != null
        && EmfComponent.REPOSITORY.equals(
            inputSchemaParam
                .getChildParameters()
                .get(EParameterName.SCHEMA_TYPE.getName())
                .getValue())) {
      // add by wzhang to fix bug 7898.
      IElementParameter elementParameter =
          node.getElementParameter(EParameterName.MAPPING.getName());
      if (elementParameter != null) {
        if (elementParameter.getValue() instanceof String) {
          String value = (String) elementParameter.getValue();
          if (!isDBComponent(value)) {
            schemaParam
                .getChildParameters()
                .get(EParameterName.SCHEMA_TYPE.getName())
                .setValue(EmfComponent.REPOSITORY);
            schemaParam
                .getChildParameters()
                .get(EParameterName.REPOSITORY_SCHEMA_TYPE.getName())
                .setValue(
                    inputSchemaParam
                        .getChildParameters()
                        .get(EParameterName.REPOSITORY_SCHEMA_TYPE.getName())
                        .getValue());
          }
        }
      }
    }

    for (INodeConnector connector : node.getListConnector()) {
      if ((!connector.getName().equals(currentConnector))
          && connector.getBaseSchema().equals(currentConnector)) {
        if (node.getComponent() != null
            && "tSalesforceOutput".equals(node.getComponent().getName())
            && "REJECT".equals(connector.getName())) {
          IMetadataTable clone = newOutputMetadata.clone(true);
          Iterator<IMetadataColumn> iterator = clone.getListColumns().iterator();
          while (iterator.hasNext()) {
            IMetadataColumn column = iterator.next();
            if (column.isCustom()) {
              iterator.remove();
            }
          }
          MetadataToolHelper.copyTable(clone, node.getMetadataFromConnector(connector.getName()));
        } else {
          // if there is some other schema dependant of this one, modify them
          MetadataToolHelper.copyTable(
              newOutputMetadata, node.getMetadataFromConnector(connector.getName()));
        }
      }
    }

    List<ColumnNameChanged> columnNameChanged =
        MetadataToolHelper.getColumnNameChanged(oldOutputMetadata, newOutputMetadata);
    ColumnListController.updateColumnList(node, columnNameChanged, true);

    if (inputNode != null) {
      List<ColumnNameChanged> inputColumnNameChangedExt =
          MetadataToolHelper.getColumnNameChangedExt(inputNode, oldInputMetadata, newInputMetadata);
      ColumnListController.updateColumnList(node, inputColumnNameChangedExt);
    }
    //
    List<ColumnNameChanged> outputColumnNameChangedExt =
        MetadataToolHelper.getColumnNameChangedExt(node, oldOutputMetadata, newOutputMetadata);
    syncOutputNodeColumnsList(outputColumnNameChangedExt);

    setXMLMAPPING();

    if (!internal) {
      updateColumnList(oldOutputMetadata, newOutputMetadata);
      ((Process) node.getProcess()).checkProcess();
    }
    refreshMetadataChanged();
  }
  private void propagateDatas(boolean isExecute) {
    String baseConnectorForCurrentNode =
        node.getConnectorFromName(currentConnector).getBaseSchema();

    // Propagate :
    if (outputdataContainer != null
        && (!outputdataContainer.getInputs().isEmpty()
            || !outputdataContainer.getOuputs().isEmpty())) {
      for (IODataComponent currentIO : outputdataContainer.getInputs()) {
        INode sourceNode = currentIO.getSource();
        if (currentIO.hasChanged()
            && (sourceNode
                .getConnectorFromName(currentIO.getConnection().getConnectorName())
                .getBaseSchema()
                .equals(baseConnectorForCurrentNode))) {
          sourceNode.metadataOutputChanged(currentIO, currentIO.getName());
          if (isExecute) {
            currentIO.setTable(oldInputMetadata);
            currentIO.setColumnNameChanged(null);
          } else {
            currentIO.setTable(newInputMetadata);
            currentIO.setColumnNameChanged(null);
          }
        }
      }
      for (IODataComponent currentIO : outputdataContainer.getOuputs()) {
        INodeConnector nodeConnector = null;
        String baseConnector = null;

        Node sourceNode = (Node) currentIO.getSource();
        nodeConnector =
            sourceNode.getConnectorFromName(currentIO.getConnection().getConnectorName());
        baseConnector = nodeConnector.getBaseSchema();

        INode targetNode = currentIO.getTarget();

        boolean sourceIsBuiltIn =
            ((Node) currentIO.getSource())
                .getConnectorFromType(currentIO.getConnection().getLineStyle())
                .isMultiSchema();

        boolean targetIsBuiltIn =
            ((Node) targetNode)
                .getConnectorFromType(currentIO.getConnection().getLineStyle())
                .isMultiSchema();
        boolean isJoblet = ((Node) targetNode).isJoblet();
        if (!isJoblet
            && baseConnector.equals(baseConnectorForCurrentNode)
            && (targetIsBuiltIn
                || (targetNode.getMetadataFromConnector(baseConnector) != null
                    && !targetNode
                        .getMetadataFromConnector(baseConnector)
                        .sameMetadataAs(newOutputMetadata)))) {

          targetNode.metadataInputChanged(currentIO, currentIO.getUniqueName());
          if (isExecute) {
            if (targetNode instanceof Node) {
              if (((Node) targetNode).getComponent().isSchemaAutoPropagated()
                  && getPropagate()
                  && targetNode.getMetadataList().size() > 0) {
                IMetadataTable tmpClone;
                if (sourceIsBuiltIn) {
                  IMetadataTable tab =
                      node.getMetadataTable(
                          currentIO.getConnection().getMetadataTable().getTableName());
                  if (tab == null && node.getJobletNode() != null) {
                    tab =
                        node.getJobletNode()
                            .getMetadataTable(
                                currentIO.getConnection().getMetadataTable().getTableName());
                  }
                  tmpClone = tab.clone(true);
                } else {
                  IMetadataTable tab =
                      node.getMetadataFromConnector(currentIO.getConnection().getConnectorName());
                  if (tab == null && node.getJobletNode() != null) {
                    tab =
                        node.getJobletNode()
                            .getMetadataFromConnector(currentIO.getConnection().getConnectorName());
                  }
                  tmpClone = tab.clone(true);
                }
                IMetadataTable toCopy = newOutputMetadata.clone();

                // wzhang modify to add feature 7611

                String dbmsId = null;
                IMetadataTable copy;
                if (((Node) targetNode).getMetadataFromConnector(baseConnector) != null) {
                  dbmsId = targetNode.getMetadataFromConnector(baseConnector).getDbms();
                  MetadataToolHelper.copyTable(dbmsId, toCopy, tmpClone);
                  toCopy = tmpClone;

                  // only if the target node have exactly the same connector
                  copy = ((Node) targetNode).getMetadataFromConnector(baseConnector).clone(true);
                } else {
                  final String mainConnector =
                      "FLOW"; // can only be FLOW right now for this case. //$NON-NLS-1$

                  dbmsId = targetNode.getMetadataFromConnector(mainConnector).getDbms();
                  MetadataToolHelper.copyTable(dbmsId, toCopy, tmpClone);
                  toCopy = tmpClone;
                  // if don't have the same connector, take the main connector of the component.

                  copy = ((Node) targetNode).getMetadataFromConnector(mainConnector).clone(true);
                }
                // MetadataTool.copyTable(toCopy, copy);
                // wzhang modify to add feature 7611
                MetadataToolHelper.copyTable(dbmsId, toCopy, copy);
                ChangeMetadataCommand cmd =
                    new ChangeMetadataCommand(targetNode, null, null, copy, inputSchemaParam);
                if (outputdataContainer.getOuputs().size() > 0) {
                  List<ColumnNameChanged> columnNameChanged =
                      outputdataContainer.getOuputs().get(0).getColumnNameChanged();
                  for (IODataComponent dataComp : cmd.outputdataContainer.getOuputs()) {
                    dataComp.setColumnNameChanged(columnNameChanged);
                  }
                }
                cmd.execute(true);
                propagatedChange.add(cmd);
              }
            }
            currentIO.setTable(oldOutputMetadata);
            currentIO.setColumnNameChanged(null);
          } else {
            if (targetNode instanceof Node) {
              if (!targetIsBuiltIn && getPropagate()) {
                if (((Node) targetNode).getComponent().isSchemaAutoPropagated()) {
                  if (outputdataContainer.getOuputs().size() > 0) {
                    List<ColumnNameChanged> columnNameChanged =
                        outputdataContainer.getOuputs().get(0).getColumnNameChanged();
                    for (ChangeMetadataCommand cmd : propagatedChange) {
                      for (IODataComponent dataComp : cmd.outputdataContainer.getOuputs()) {
                        dataComp.setColumnNameChanged(columnNameChanged);
                      }
                    }
                  }
                }
              }
            }

            currentIO.setTable(newOutputMetadata);
            currentIO.setColumnNameChanged(null);
          }
        }
      }
    } else if (dataComponent != null) {
      for (IConnection outgoingConnection : node.getOutgoingConnections()) {
        if (outgoingConnection.getConnectorName().equals(currentConnector)) {
          outgoingConnection
              .getTarget()
              .metadataInputChanged(dataComponent, outgoingConnection.getName());
        }
      }
    } else {
      if (!node.getOutgoingConnections().isEmpty()) {
        IMetadataTable relativeOldOutputMetadata = null;
        IMetadataTable relativeNewOutputMetadata = null;
        if (isExecute) {
          relativeOldOutputMetadata = oldOutputMetadata;
          relativeNewOutputMetadata = newOutputMetadata;
        } else {
          relativeOldOutputMetadata = newOutputMetadata;
          relativeNewOutputMetadata = oldOutputMetadata;
        }
        for (IConnection outgoingConnection : node.getOutgoingConnections()) {
          final Node target = (Node) outgoingConnection.getTarget();
          if (target != null && target.getExternalNode() != null) {
            List<IMetadataColumn> oldListColumns = relativeOldOutputMetadata.getListColumns();
            List<IMetadataColumn> newListColumns = relativeNewOutputMetadata.getListColumns();
            List<ColumnNameChanged> columnNameChanges = new ArrayList<ColumnNameChanged>();
            int size = oldListColumns.size();
            int newSize = newListColumns.size();
            if (newSize < size) {
              size = newSize;
            }
            IODataComponent output =
                new IODataComponent(outgoingConnection, relativeNewOutputMetadata);
            if (newListColumns != null) {
              List<ColumnNameChanged> newColumnsList = output.getNewMetadataColumns();
              // new added columns list
              Set<String> newAddedColumns = new HashSet<String>();
              // newest columns after user changed
              Set<String> newestColumns = new HashSet<String>();

              // init
              if (newColumnsList != null) {
                for (ColumnNameChanged columnChanged : newColumnsList) {
                  newAddedColumns.add(columnChanged.getNewName());
                }
              }
              for (IMetadataColumn metadataColumn : newListColumns) {
                newestColumns.add(metadataColumn.getLabel());
              }

              // check
              for (int i = 0; i < size; i++) {
                IMetadataColumn oldMetadataColumn = oldListColumns.get(i);
                String columnName = oldMetadataColumn.getLabel();
                // if this column(before changing) is not exists in the new columns(after changing),
                // there are two possible truth: 1. this column has been renamed; 2. this column has
                // been removed
                if (!newestColumns.contains(columnName)) {
                  IMetadataColumn newMetadataColumn = newListColumns.get(i);
                  String newColumnNameAtThisIndex = newMetadataColumn.getLabel();
                  // if the column at the same position in new table is a new column(two possible
                  // truth: 1. an old column's name has been changed; 2. user add a new column);
                  // For now, Seems it is very hard to judge whether it is a renamed column or a new
                  // column, so we suppose the more possible truth is that it is a renamed column
                  if (newAddedColumns.contains(newColumnNameAtThisIndex)) {
                    columnNameChanges.add(
                        new ColumnNameChanged(columnName, newColumnNameAtThisIndex));
                  }
                }
              }
            }

            if (GlobalServiceRegister.getDefault().isServiceRegistered(IXmlMapService.class)) {
              final IXmlMapService service =
                  (IXmlMapService)
                      GlobalServiceRegister.getDefault().getService(IXmlMapService.class);
              if (service.isXmlMapComponent(target.getExternalNode())) {
                output.setColumnNameChanged(columnNameChanges);
                target.metadataInputChanged(output, outgoingConnection.getName());
              }
            }
            if (GlobalServiceRegister.getDefault().isServiceRegistered(ISparkMapService.class)) {
              final ISparkMapService service =
                  (ISparkMapService)
                      GlobalServiceRegister.getDefault().getService(ISparkMapService.class);
              if (service.isSparkMapComponent(target.getExternalNode())) {
                output.setColumnNameChanged(columnNameChanges);
                target.metadataInputChanged(output, outgoingConnection.getName());
              }
            }

            if (GlobalServiceRegister.getDefault().isServiceRegistered(IDbMapService.class)) {
              final IDbMapService service =
                  (IDbMapService)
                      GlobalServiceRegister.getDefault().getService(IDbMapService.class);
              if (service.isDbMapComponent(target.getExternalNode())) {
                // TDI-25307:should setColumNameChanged here for ELtDbMap in case the propagate
                // schema
                // does not affect it.
                output.setColumnNameChanged(columnNameChanges);
                target.metadataInputChanged(output, outgoingConnection.getName());
              }
            }
          }
        }
      }
    }

    if (inputdataContainer != null) {
      for (IODataComponent currentIO : inputdataContainer.getOuputs()) {
        if (currentIO.hasChanged()
            && (currentIO
                .getSource()
                .getConnectorFromName(currentIO.getConnection().getConnectorName())
                .getBaseSchema()
                .equals(currentConnector))) {
          INode targetNode = currentIO.getTarget();
          targetNode.metadataInputChanged(currentIO, currentIO.getUniqueName());
          if (isExecute) {
            currentIO.setTable(oldInputMetadata);
            currentIO.setColumnNameChanged(null);
          } else {
            currentIO.setTable(newInputMetadata);
            currentIO.setColumnNameChanged(null);
          }
        }
      }
    }
    // End propagate
  }
  /** run a ShadowProcess to determined the Metadata. */
  protected void runShadowProcess() {
    initGuessSchema();
    SalesforceSchemaConnection originalValueConnection = getOriginalValueConnection();
    // if no file, the process don't be executed
    if (originalValueConnection.getWebServiceUrl() == null
        || originalValueConnection.getWebServiceUrl().equals("")) { // $NON-NLS-1$
      informationLabel.setText(
          "Salesforce endpoint lost" //$NON-NLS-1$
              + "                                                                              "); //$NON-NLS-1$
      return;
    }

    // try {
    informationLabel.setText(
        "   " + Messages.getString("FileStep3.guessProgress")); // $NON-NLS-1$ //$NON-NLS-2$

    // get the XmlArray width an adapt ProcessDescription
    ProcessDescription processDescription = getProcessDescription(originalValueConnection);

    IMetadataTable metadataTableOrder = readMetadataDetail();
    if (metadataTableOrder != null) {
      metadataTableClone = metadataTableOrder.clone();
      metadataTableOrder = modifyMetadataTable();
    }
    List<IMetadataTable> schema = processDescription.getSchema();
    if (schema != null && schema.size() > 0) {
      if (useAlphbet) {
        if (metadataTableOrder != null) {
          schema.get(0).setListColumns(metadataTableOrder.getListColumns());
        }
      } else {
        if (metadataTableClone != null) {
          schema.get(0).setListColumns(metadataTableClone.getListColumns());
        }
      }
    }
    // the web service url is used by tSalesforceInput, see 0004027: Studio crashes when clicking
    // Next on
    // Step 3 of SF wizard
    // processDescription.getSalesforceSchemaBean().setWebServerUrl(TSALESFORCE_INPUT_URL);
    //            CsvArray csvArray = ShadowProcessHelper.getCsvArray(processDescription,
    // "SALESFORCE_SCHEMA", true); //$NON-NLS-1$
    //
    // if (csvArray == null) {
    //                informationLabel.setText("   " +
    // Messages.getString("FileStep3.guessFailure")); //$NON-NLS-1$ //$NON-NLS-2$
    // } else {
    // refreshMetaDataTable(csvArray, processDescription);
    // }

    // } catch (CoreException e) {
    // if (getParent().getChildren().length == 1) {
    //                new ErrorDialogWidthDetailArea(getShell(), PID,
    // Messages.getString("FileStep3.guessFailureTip") + "\n" //$NON-NLS-1$ //$NON-NLS-2$
    //                        + Messages.getString("FileStep3.guessFailureTip2"), e.getMessage());
    // //$NON-NLS-1$
    // } else {
    //                new ErrorDialogWidthDetailArea(getShell(), PID,
    // Messages.getString("FileStep3.guessFailureTip"), e.getMessage()); //$NON-NLS-1$
    // }
    //            log.error(Messages.getString("FileStep3.guessFailure") + " " + e.getMessage());
    // //$NON-NLS-1$ //$NON-NLS-2$
    // }
    guessSchema(processDescription);
    checkFieldsValue();
  }