This repository has been archived on 2025-12-25. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
tcommon-studio-se/main/plugins/org.talend.librariesmanager/resources/java/routines/system/DocumentToFlat.java
bhe-talendbj 4f32054c45 bugfix(TUP-25495) Update to dom4j 2.1.1 (#2959)
* bugfix(TUP-25495) Upgrade dom4j to 2.1.1

* bugfix(TUP-25495) Upgrade dom4j to 2.1.1

* bugfix(TUP-25495) Add dom4j license

* bugfix(TUP-25495) Add back version number of jar

* bugfix(TUP-25495) Revert plug.xml

* bugfix(TUP-25495) Keep dom4j-1.6.1.jar

* bugfix(TUP-25495) Upgrade jaxen to 1.1.6 and add keep jaxen-1.1.1.jar

* bugfix(TUP-25495) Upgrade jaxen to 1.1.6 and add keep jaxen-1.1.1.jar

* bugfix(TUP-25495) Upgrade jaxen to 1.1.6 and add keep jaxen-1.1.1.jar
2020-01-07 15:15:13 +08:00

252 lines
7.0 KiB
Java

package routines.system;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.dom4j.Node;
import org.dom4j.XPath;
public class DocumentToFlat {
private org.dom4j.Document doc;
private String currentLoop;
private String originalLoop;
private String[] currentRelativePathMappings;
private String[] absolutePathMappings;
private Map<String,String> xmlNameSpaceMap;
private boolean top = false;
boolean isOptional = false; // use to judge if the loop node is mandotary in the source file.
//check whether namespace define exist in UI
private boolean defineNS = true;
private NameSpaceTool namespaceTool;
private List<Node> nodes;
//result show
private List<Map<String,String>> resultSet = new ArrayList<Map<String,String>>();
public DocumentToFlat() {
}
/**
* Document to Flat
*/
public void flat() {
XPath loopXpath = null;
if(!defineNS) {
loopXpath = doc.createXPath(namespaceTool.addDefaultNSPrefix(currentLoop, currentLoop));
} else {
loopXpath = doc.createXPath(currentLoop);
}
loopXpath.setNamespaceURIs(xmlNameSpaceMap);
nodes = loopXpath.selectNodes(doc);
if(this.isOptional && nodes.size() == 0 && !top) {
setParentAsLoop();
flat();
} else if (nodes !=null ) {
//reset relative paths
if(currentLoop != originalLoop) {//not point to the same string
for(int i=0;i<currentRelativePathMappings.length;i++) {
currentRelativePathMappings[i] = resetRelativeXPath(currentRelativePathMappings[i]);
}
}
for (Node node : nodes) {
//init row
Map<String,String> row = new HashMap<String,String>();
resultSet.add(row);
//init columns for one row
for(int i=0;i<currentRelativePathMappings.length;i++) {
String relativePath = currentRelativePathMappings[i];
XPath xpath = null;
if(!defineNS) {
xpath = node.createXPath(namespaceTool.addDefaultNSPrefix(relativePath, currentLoop));
} else {
xpath = node.createXPath(relativePath);
}
xpath.setNamespaceURIs(xmlNameSpaceMap);
Object obj = xpath.evaluate(node);
if(obj instanceof String || obj instanceof Number){
row.put(absolutePathMappings[i], String.valueOf(obj));
}else{
row.put(absolutePathMappings[i], xpath.selectSingleNode(node)!=null ? xpath.valueOf(node) : null);
}
}
}
doc = null;
nodes = null;
}
}
private String resetRelativeXPath(String relativePath) {
//get absolute path by original loop path
String absolutePath = originalLoop;
for(String step : relativePath.split("/")) {
if("..".equals(step)) {
absolutePath = absolutePath.substring(0,absolutePath.lastIndexOf("/"));
} else if(".".equals(step)){
//do nothing
} else if(!"".equals(step)){
absolutePath += "/" + step;
}
}
//get relative path by new loop path
if(absolutePath.equals(currentLoop)) {
return ".";
} else if(absolutePath.startsWith(currentLoop)){
return absolutePath.substring(currentLoop.length() + 1);
} else {
StringBuilder relativeXPath = new StringBuilder();
String tmp = currentLoop;
while(!absolutePath.startsWith(tmp)){
int index = tmp.lastIndexOf("/");
if(index<0){ break; }
tmp = tmp.substring(0,index);
relativeXPath.append("../");
}
relativeXPath.append(absolutePath.substring(tmp.length() + 1));
return relativeXPath.toString();
}
}
private void setParentAsLoop() {
int end = currentLoop.length();
int idx = currentLoop.lastIndexOf('/');
if(idx > 0) {
end = idx;
} else if(idx == 0) {//currentLoop is root
top = true;
}
currentLoop = currentLoop.substring(0, end);
}
public List<Map<String, String>> getResultSet() {
return resultSet;
}
public void setDoc(org.dom4j.Document doc) {
this.doc = doc;
}
public void setOriginalLoop(String originalLoop) {
this.originalLoop = originalLoop;
this.currentLoop = originalLoop;
}
public void setCurrentRelativePathMappings(String[] currentRelativePathMappings) {
this.currentRelativePathMappings = currentRelativePathMappings;
}
public void setAbsolutePathMappings(String[] absolutePathMappings) {
this.absolutePathMappings = absolutePathMappings;
}
public void setXmlNameSpaceMap(Map<String, String> xmlNameSpaceMap) {
this.xmlNameSpaceMap = xmlNameSpaceMap;
}
public void setDefineNS(boolean defineNS) {
this.defineNS = defineNS;
}
public void setNamespaceTool(NameSpaceTool namespaceTool) {
this.namespaceTool = namespaceTool;
}
private Map<String, Object> lookupInfo;
private Map<String, String> xpathOfResults;
private Map<String, String> xpathToTypeMap;
private Map<String, String> xpathToPatternMap;
private boolean loopChanged = false;
public DocumentToFlat(Map<String, Object> lookupInfo,
Map<String, String> xpathOfResults,
Map<String, String> xpathToTypeMap,
Map<String, String> xpathToPatternMap) {
this.lookupInfo = lookupInfo;
this.xpathOfResults = xpathOfResults;
this.xpathToTypeMap = xpathToTypeMap;
this.xpathToPatternMap = xpathToPatternMap;
}
public void flatForLookup(boolean isOptionalLoop) {
XPath loopXpath = doc.createXPath(currentLoop);
loopXpath.setNamespaceURIs(xmlNameSpaceMap);
nodes = loopXpath.selectNodes(doc);
if(isOptionalLoop && nodes.size() == 0 && !top) {
setParentAsLoop();
flatForLookup(isOptionalLoop);
} else if(currentLoop != originalLoop) {//not point to the same string
loopChanged = true;
reset();
}
}
private void reset() {
lookupInfo = resetMapRelativeXpathKey(lookupInfo);
xpathToTypeMap = resetMapRelativeXpathKey(xpathToTypeMap);
xpathToPatternMap = resetMapRelativeXpathKey(xpathToPatternMap);
xpathOfResults = resetMapRelativeXpathValue(xpathOfResults);
}
private Map resetMapRelativeXpathKey(Map<String, ? extends Object> source) {
Map content = new HashMap();
for(String key : source.keySet()) {
String newKey = resetRelativeXPath(key);
content.put(newKey, source.get(key));
}
return content;
}
private Map resetMapRelativeXpathValue(Map<String,String> source) {
Map content = new HashMap();
for(String key : source.keySet()) {
String value = source.get(key);
String newValue = resetRelativeXPath(value);
content.put(key, newValue);
}
return content;
}
public List<Node> getNodes() {
return nodes;
}
public Map<String, Object> getLookupInfo() {
return lookupInfo;
}
public Map<String, String> getXpathOfResults() {
return xpathOfResults;
}
public Map<String, String> getXpathToTypeMap() {
return xpathToTypeMap;
}
public Map<String, String> getXpathToPatternMap() {
return xpathToPatternMap;
}
public boolean isLoopChanged() {
return loopChanged;
}
public void setIsOptional(boolean isLoopOptional) {
this.isOptional = isLoopOptional;
}
}