Created
July 6, 2016 13:57
-
-
Save adamish/ecb59b45befff7d3f7db418f3fc2a115 to your computer and use it in GitHub Desktop.
Merge 2 or more spring contexts to find common beans, output them to a common file, then remove them from original files. Take into account formatting differences
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.File; | |
import java.io.FileInputStream; | |
import java.io.FileWriter; | |
import java.io.IOException; | |
import java.io.StringWriter; | |
import java.util.ArrayList; | |
import java.util.Collections; | |
import java.util.LinkedHashMap; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.Map.Entry; | |
import javax.xml.parsers.DocumentBuilderFactory; | |
import javax.xml.parsers.ParserConfigurationException; | |
import javax.xml.transform.Transformer; | |
import javax.xml.transform.TransformerException; | |
import javax.xml.transform.TransformerFactory; | |
import javax.xml.transform.dom.DOMSource; | |
import javax.xml.transform.stream.StreamResult; | |
import javax.xml.xpath.XPath; | |
import javax.xml.xpath.XPathConstants; | |
import javax.xml.xpath.XPathExpression; | |
import javax.xml.xpath.XPathExpressionException; | |
import javax.xml.xpath.XPathFactory; | |
import org.w3c.dom.Document; | |
import org.w3c.dom.Element; | |
import org.w3c.dom.Node; | |
import org.w3c.dom.NodeList; | |
public class XmlMerge { | |
private Transformer transformer; | |
public XmlMerge() throws Exception { | |
Document xml1 = load("foo.xml"); | |
Document xml2 = load("bar.xml"); | |
Document xml3 = load("baz.xml"); | |
TransformerFactory transformerFactory = TransformerFactory.newInstance(); | |
transformer = transformerFactory.newTransformer(); | |
List<Node> allCommon = compare(xml1, xml3, xml2); | |
remove(xml1, allCommon); | |
remove(xml2, allCommon); | |
remove(xml3, allCommon); | |
write(allCommon, "common.xml"); | |
List<Node> common1and2 = compare(xml1, xml3); | |
remove(xml1, common1and2); | |
remove(xml3, common1and2); | |
write(common1and2, "sonar.xml"); | |
write(xml1, "foo.xml"); | |
write(xml2, "bar.xml"); | |
write(xml3, "baz.xml"); | |
} | |
private void write(Document doc, String string) throws IOException, TransformerException { | |
FileWriter writer = new FileWriter(new File(string)); | |
StreamResult result = new StreamResult(writer); | |
transformer.transform(new DOMSource(doc), result); | |
} | |
private void write(List<Node> nodes, String string) | |
throws TransformerException, ParserConfigurationException, IOException { | |
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); | |
Element beans = doc.createElement("beans"); | |
doc.appendChild(beans); | |
for (Node each : nodes) { | |
Node clone = each.cloneNode(true); | |
doc.adoptNode(clone); | |
beans.appendChild(clone); | |
System.out.println(toXml(clone)); | |
} | |
FileWriter writer = new FileWriter(new File(string)); | |
StreamResult result = new StreamResult(writer); | |
transformer.transform(new DOMSource(doc), result); | |
} | |
private void remove(Document bscan, List<Node> allCommon) throws Exception { | |
Map<String, Node> mappings = getBeans(bscan); | |
for (Node each : allCommon) { | |
String hash = hashAttributes((Element) each); | |
Node toRemove = mappings.get(hash); | |
if (toRemove == null) { | |
System.err.println("Cannot find " + hash); | |
continue; | |
} | |
Node parentNode = toRemove.getParentNode(); | |
if (parentNode != null) { | |
parentNode.removeChild(toRemove); | |
} else { | |
System.err.println("Cannot remove " + each); | |
} | |
} | |
} | |
private boolean isEqual(Node a, Node b) throws XPathExpressionException, TransformerException { | |
Node aClone = a.cloneNode(true); | |
Node bClone = b.cloneNode(true); | |
strip(aClone); | |
strip(bClone); | |
return toXml(aClone).equals(toXml(bClone)); | |
} | |
private String toXml(Node node) throws TransformerException { | |
StringWriter stringWriter = new StringWriter(); | |
StreamResult result = new StreamResult(stringWriter); | |
transformer.transform(new DOMSource(node), result); | |
return stringWriter.toString(); | |
} | |
private void strip(Node doc) throws XPathExpressionException { | |
XPathFactory xpathFactory = XPathFactory.newInstance(); | |
// XPath to find empty text nodes. | |
XPathExpression xpathExp = xpathFactory.newXPath().compile("//text()[normalize-space(.) = '']"); | |
NodeList emptyTextNodes = (NodeList) xpathExp.evaluate(doc, XPathConstants.NODESET); | |
// Remove each empty text node from document. | |
for (int i = 0; i < emptyTextNodes.getLength(); i++) { | |
Node emptyTextNode = emptyTextNodes.item(i); | |
emptyTextNode.getParentNode().removeChild(emptyTextNode); | |
} | |
} | |
private List<Node> compare(Document... docs) throws Exception { | |
List<Node> nodes = new ArrayList<Node>(); | |
List<Map<String, Node>> mappings = new ArrayList<>(); | |
for (int i = 0; i < docs.length; i++) { | |
mappings.add(getBeans(docs[i])); | |
} | |
for (Entry<String, Node> leftBeans : mappings.get(0).entrySet()) { | |
System.out.println(leftBeans.getKey()); | |
boolean match = true; | |
for (int i = 1; i < docs.length; i++) { | |
Node rightBean = mappings.get(i).get(leftBeans.getKey()); | |
if (rightBean == null) { | |
match = false; | |
break; | |
} | |
if (!isEqual(rightBean, leftBeans.getValue())) { | |
match = false; | |
break; | |
} | |
} | |
if (match) { | |
System.out.println(leftBeans.getKey() + " found in all"); | |
nodes.add(leftBeans.getValue()); | |
} | |
} | |
return nodes; | |
} | |
private Map<String, Node> getBeans(Document doc) throws Exception { | |
Map<String, Node> map = new LinkedHashMap<String, Node>(); | |
XPath xpath = XPathFactory.newInstance().newXPath(); | |
NodeList result = (NodeList) xpath.compile("/beans/bean").evaluate(doc, XPathConstants.NODESET); | |
for (int i = 0; i < result.getLength(); i++) { | |
Element element = (Element) result.item(i); | |
map.put(hashAttributes(element), element); | |
} | |
return map; | |
} | |
private String hashAttributes(Element element) { | |
List<String> each = new ArrayList<>(); | |
for (int i = 0; i < element.getAttributes().getLength(); i++) { | |
each.add(String.format("%s=%s", element.getAttributes().item(i).getNodeName(), | |
element.getAttributes().item(i).getNodeValue())); | |
} | |
Collections.sort(each); | |
return each.toString(); | |
} | |
public static void main(String[] args) throws Exception { | |
new XmlMerge(); | |
} | |
private Document load(String file) throws Exception { | |
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder() | |
.parse(new FileInputStream(new File(file))); | |
return document; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment