private void processNode()

in plugins/misc/import/src/main/java/org/apache/hop/imports/kettle/KettleImport.java [505:816]


  private void processNode(Document doc, Node node, EntryType entryType, int depth) {
    Node nodeToProcess = node;
    NodeList nodeList = nodeToProcess.getChildNodes();

    // Set depth level
    depth += 1;

    // do a first pass to remove repository definitions
    for (int i = 0; i < nodeList.getLength(); i++) {
      Node repositoryNode = nodeList.item(i);
      if (repositoryNode.getNodeType() == Node.ELEMENT_NODE
          && KettleConst.repositoryTypes.contains(repositoryNode.getTextContent())) {
        for (int j = 0; j < node.getChildNodes().getLength(); j++) {
          Node childNode = node.getChildNodes().item(j);
          if (childNode.getNodeName().equals("jobname")
              || childNode.getNodeName().equals("transname")
              || childNode.getNodeName().equals("trans_name")) {
            if (!StringUtil.isEmpty(childNode.getTextContent())) {
              nodeToProcess = processRepositoryNode(node);
            }
          }
        }
        nodeList = nodeToProcess.getChildNodes();
      }
    }

    Node firstFormulaNode = null;

    for (int i = 0; i < nodeList.getLength(); i++) {
      Node currentNode = nodeList.item(i);

      if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
        // Identify if an entry is of type START or DUMMY type because they must be managed properly
        if (currentNode.getNodeName().equals("entry")) {
          entryType = EntryType.OTHER;
          Node entryTypeNode = null;
          boolean isEntryTypeSpecial = false;
          NodeList currentNodeChildNodes = currentNode.getChildNodes();
          for (int i1 = 0; i1 < currentNodeChildNodes.getLength(); i1++) {
            Node childNode = currentNodeChildNodes.item(i1);
            if (childNode.getNodeType() == Node.ELEMENT_NODE) {
              if (childNode.getNodeName().equals("type")
                  && childNode.getChildNodes().item(0).getNodeValue().equals("SPECIAL")) {
                isEntryTypeSpecial = true;
                entryTypeNode = childNode;
              } else if (childNode.getNodeName().equals("type")
                  && childNode.getChildNodes().item(0).getNodeValue().equals("TRANS")) {
                entryType = EntryType.TRANS;
              } else if (childNode.getNodeName().equals("type")
                  && childNode.getChildNodes().item(0).getNodeValue().equals("JOB")) {
                entryType = EntryType.JOB;
              } else if (isEntryTypeSpecial
                  && childNode.getNodeName().equals("start")
                  && childNode.getChildNodes().item(0).getNodeValue().equals("Y")) {
                entryType = EntryType.START;
              } else if (isEntryTypeSpecial
                  && childNode.getNodeName().equals("dummy")
                  && childNode.getChildNodes().item(0).getNodeValue().equals("Y")) {
                entryType = EntryType.DUMMY;
                // Immediately change entry type to DUMMY to not bother about it later on
                entryTypeNode.getFirstChild().setTextContent("DUMMY");
              }
            }
          }
        }

        if (currentNode.getNodeName().equals("step")) {
          entryType = EntryType.OTHER;
          NodeList currentNodeChildNodes = currentNode.getChildNodes();
          for (int i1 = 0; i1 < currentNodeChildNodes.getLength(); i1++) {
            Node childNode = currentNodeChildNodes.item(i1);
            if (childNode.getNodeType() == Node.ELEMENT_NODE) {
              if (childNode.getNodeName().equals("type")
                  && childNode.getChildNodes().item(0).getNodeValue().equals("Formula")) {
                entryType = EntryType.FORMULA;
              }
              if (childNode.getNodeName().equals("type")
                  && childNode
                      .getChildNodes()
                      .item(0)
                      .getNodeValue()
                      .equals("PentahoGoogleSheetsPluginInputMeta")) {
                entryType = EntryType.GOOGLE_SHEETS_INPUT;
              }
              if (childNode.getNodeName().equals("type")
                  && childNode.getChildNodes().item(0).getNodeValue().equals("Mapping")) {
                entryType = EntryType.SIMPLE_MAPPING;
              }
              if (childNode.getNodeName().equals("type")
                  && childNode.getChildNodes().item(0).getNodeValue().equals("MetaInject")) {
                entryType = EntryType.METAINJECT;
              }
            }
          }
        }

        // remove superfluous elements
        if (entryType == EntryType.OTHER) {
          if (KettleConst.kettleElementsToRemove.containsKey(currentNode.getNodeName())) {
            if (!StringUtils.isEmpty(
                KettleConst.kettleElementsToRemove.get(currentNode.getNodeName()))) {
              // see if we have multiple parent nodes to check for:
              if (KettleConst.kettleElementsToRemove.get(currentNode.getNodeName()).contains(",")) {
                Node parentNode = currentNode.getParentNode();
                String[] parentNodeNames =
                    KettleConst.kettleElementsToRemove.get(currentNode.getNodeName()).split(",");
                for (String parentNodeName : parentNodeNames) {
                  if (parentNode.getNodeName().equals(parentNodeName)) {
                    parentNode.removeChild(currentNode);
                  }
                }
              } else {
                if (currentNode
                    .getParentNode()
                    .getNodeName()
                    .equals(KettleConst.kettleElementsToRemove.get(currentNode.getNodeName()))) {
                  currentNode.getParentNode().removeChild(currentNode);
                }
              }
            } else {
              currentNode.getParentNode().removeChild(currentNode);
            }
          }
        } else if (entryType == EntryType.START) {
          if (KettleConst.kettleStartEntryElementsToRemove.containsKey(currentNode.getNodeName())) {
            currentNode.getParentNode().removeChild(currentNode);
          }
        } else if (entryType == EntryType.DUMMY
            && KettleConst.kettleDummyEntryElementsToRemove.containsKey(
                currentNode.getNodeName())) {
          currentNode.getParentNode().removeChild(currentNode);
        }

        if (entryType == EntryType.FORMULA && currentNode.getNodeName().equals("formula")) {
          if (firstFormulaNode == null) {
            Element formulasElement = doc.createElement("formulas");
            formulasElement.appendChild(currentNode);
            firstFormulaNode = formulasElement;
          } else {
            // Append new one to collection of new formula nodes
            firstFormulaNode.appendChild(currentNode);
          }
        } else if (entryType == EntryType.FORMULA
            && !currentNode.getNodeName().equals("formula")
            && firstFormulaNode != null
            && depth == 2) {
          // Always in same steps' nodeset, same depth level and we finished formula definition
          // nodes
          // Add new collections to formlua nodeset
          node.appendChild(firstFormulaNode);
          // reset the entry type to OTHER because we left the formula nodeset
          entryType = EntryType.OTHER;
          firstFormulaNode = null;
        } else if (entryType == EntryType.FORMULA
            && currentNode.getNodeName().equals("formula_string")) {
          String formulaValue = currentNode.getFirstChild().getNodeValue();
          currentNode.getFirstChild().setNodeValue(formulaValue.replaceAll(";", ","));
        } else if (entryType == EntryType.FORMULA
            && currentNode.getNodeName().equals("value_type")) {
          String formulaType = currentNode.getFirstChild().getNodeValue();
          currentNode
              .getFirstChild()
              .setNodeValue(Integer.toString(ValueMetaFactory.getIdForValueMeta(formulaType)));
        }

        if ((entryType == EntryType.JOB || entryType == EntryType.TRANS)
            && currentNode.getNodeName().equals("run_configuration")) {
          if (entryType == EntryType.JOB)
            currentNode.setTextContent(defaultWorkflowRunConfiguration);
          else if (entryType == EntryType.TRANS)
            currentNode.setTextContent(defaultPipelineRunConfiguration);
        }

        // rename Kettle elements to Hop elements
        if (KettleConst.kettleElementReplacements.containsKey(currentNode.getNodeName())) {
          renameNode(
              doc,
              (Element) currentNode,
              KettleConst.kettleElementReplacements.get(currentNode.getNodeName()));
        }

        // replace element contents with Hop equivalent
        if (KettleConst.kettleReplaceContent.containsKey(currentNode.getTextContent())) {
          currentNode.setTextContent(
              KettleConst.kettleReplaceContent.get(currentNode.getTextContent()));
        }

        processNode(doc, currentNode, entryType, depth);
      }

      // partial node content replacement
      if (currentNode.getNodeType() == Node.TEXT_NODE
          && !StringUtils.isEmpty(currentNode.getTextContent())) {
        for (Map.Entry<String, String> entry : KettleConst.kettleReplaceInContent.entrySet()) {
          if (currentNode.getTextContent().contains(entry.getKey())) {
            currentNode.setTextContent(
                currentNode.getTextContent().replace(entry.getKey(), entry.getValue()));
          }
        }
      }

      if ((entryType == EntryType.SIMPLE_MAPPING || entryType == EntryType.METAINJECT)
          && currentNode.getNodeName().equals("transform")) {

        Node filenameNode = null;
        String transName = "";
        String directoryPath = "";
        // get trans name, file name, path, set correct filename when needed.
        for (int j = 0; j < currentNode.getChildNodes().getLength(); j++) {
          if (currentNode.getChildNodes().item(j).getNodeName().equals("directory_path")) {
            directoryPath = currentNode.getChildNodes().item(j).getTextContent();
            currentNode.removeChild(currentNode.getChildNodes().item(j));
          }
          if (currentNode.getChildNodes().item(j).getNodeName().equals("trans_name")) {
            transName = currentNode.getChildNodes().item(j).getTextContent();
            currentNode.removeChild(currentNode.getChildNodes().item(j));
          }
          if (currentNode.getChildNodes().item(j).getNodeName().equals("filename")) {
            filenameNode = currentNode.getChildNodes().item(j);
          }
        }

        // if we have a trans name and directory path, use it to update the mapping or injectable
        // pipeline
        // filename.
        if (!StringUtils.isEmpty(transName) && !StringUtils.isEmpty(directoryPath)) {
          filenameNode.setTextContent("${PROJECT_HOME}" + directoryPath + '/' + transName + ".hpl");
        }

        // add the default pipeline run configuration.
        Element runConfigElement = doc.createElement("runConfiguration");
        runConfigElement.appendChild(doc.createTextNode(defaultPipelineRunConfiguration));
        currentNode.appendChild(runConfigElement);
      }

      if (entryType == EntryType.GOOGLE_SHEETS_INPUT
          && currentNode.getNodeName().equals("jsonCredentialPath")) {
        String jsonCredentialKeyPath = currentNode.getTextContent();
        currentNode.setTextContent(jsonCredentialKeyPath.replace('\\', '/'));
      }
      if (entryType == EntryType.GOOGLE_SHEETS_INPUT && currentNode.getNodeName().equals("field")) {

        // get the second (1) child node to replace data types
        for (int j = 0; j < currentNode.getChildNodes().getLength(); j++) {
          Node childNode = currentNode.getChildNodes().item(j);
          if (childNode.getNodeName().equals("type")) {
            String typeNodeValue = childNode.getTextContent();
            switch (typeNodeValue) {
              case "Avro Record":
                childNode.setTextContent("20");
                break;
              case "BigNumber":
                childNode.setTextContent("6");
                break;
              case "Binary":
                childNode.setTextContent("8");
                break;
              case "Boolean":
                childNode.setTextContent("4");
                break;
              case "Date":
                childNode.setTextContent("3");
                break;
              case "Integer":
                childNode.setTextContent("5");
                break;
              case "Internet Address":
                childNode.setTextContent("10");
                break;
              case "Number":
                childNode.setTextContent("1");
                break;
              case "Serializable":
                childNode.setTextContent("7");
                break;
              case "String":
                childNode.setTextContent("2");
                break;
              case "Timestamp":
                childNode.setTextContent("9");
                break;
                // default to String
              default:
                childNode.setTextContent("2");
                break;
            }
          }
          if (childNode.getNodeName().equals("trim_type")) {
            String trimTypeNode = childNode.getTextContent();
            switch (trimTypeNode) {
              case "none":
                childNode.setTextContent("0");
                break;
              case "left":
                childNode.setTextContent("1");
                break;
              case "right":
                childNode.setTextContent("2");
                break;
              case "both":
                childNode.setTextContent("3");
                break;
                // don't trim if not known
              default:
                childNode.setTextContent("0");
                break;
            }
          }
        }
      }
    }
  }