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;
}
}
}
}
}
}