From a20951889a91bda8586bc757b5adc5663b54bfc2 Mon Sep 17 00:00:00 2001 From: tomazas Date: Mon, 25 Jan 2016 12:01:28 +0200 Subject: [PATCH] Add ability to change merging behavior at runtime. --- .../org/atteo/xmlcombiner/XmlCombiner.java | 37 +++- .../atteo/xmlcombiner/XmlCombinerTest.java | 165 +++++++++++++++++- 2 files changed, 198 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/atteo/xmlcombiner/XmlCombiner.java b/src/main/java/org/atteo/xmlcombiner/XmlCombiner.java index 1c72b0e..517c4dd 100644 --- a/src/main/java/org/atteo/xmlcombiner/XmlCombiner.java +++ b/src/main/java/org/atteo/xmlcombiner/XmlCombiner.java @@ -84,6 +84,17 @@ public interface Filter { */ void postProcess(Element recessive, Element dominant, Element result); } + + /** + * Allows to change the element merge behavior at runtime. + */ + public interface MergeFilter { + /** + * Specify merging technique for the element. + * @param element current element for which to provide the merging behavior + */ + CombineChildren query(Element element); + } private final DocumentBuilder documentBuilder; private final Document document; @@ -93,7 +104,14 @@ public interface Filter { public void postProcess(Element recessive, Element dominant, Element result) { } }; + private static final MergeFilter DEFAULT_MERGE_FILTER = new MergeFilter() { + @Override + public CombineChildren query(Element element) { + return CombineChildren.MERGE; + } + }; private Filter filter = NULL_FILTER; + private MergeFilter mergeFilter = DEFAULT_MERGE_FILTER; private final ChildContextsMapper childContextMapper = new KeyAttributesChildContextsMapper(); public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException, @@ -176,6 +194,17 @@ public void setFilter(Filter filter) { } this.filter = filter; } + + /** + * Sets the merging behavior filter. + */ + public void setFilter(MergeFilter mergeFilter) { + if (mergeFilter == null) { + this.mergeFilter = DEFAULT_MERGE_FILTER; + return; + } + this.mergeFilter = mergeFilter; + } /** * Combine given file. @@ -260,7 +289,13 @@ private Context combine(Context recessive, Context dominant) { if (combineChildren == null) { combineChildren = getCombineChildren(recessive.getElement()); if (combineChildren == null) { - combineChildren = CombineChildren.MERGE; + combineChildren = mergeFilter.query(dominant.getElement()); + if (combineChildren == null) { + combineChildren = mergeFilter.query(recessive.getElement()); + if (combineChildren == null) { + combineChildren = CombineChildren.MERGE; + } + } } } diff --git a/src/test/java/org/atteo/xmlcombiner/XmlCombinerTest.java b/src/test/java/org/atteo/xmlcombiner/XmlCombinerTest.java index 9740756..1ad7a94 100644 --- a/src/test/java/org/atteo/xmlcombiner/XmlCombinerTest.java +++ b/src/test/java/org/atteo/xmlcombiner/XmlCombinerTest.java @@ -13,6 +13,11 @@ */ package org.atteo.xmlcombiner; +import static org.assertj.core.api.Assertions.assertThat; +import static org.custommonkey.xmlunit.XMLAssert.assertXMLIdentical; +import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual; +import static org.custommonkey.xmlunit.XMLAssert.assertXMLNotEqual; + import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.StringWriter; @@ -31,10 +36,8 @@ import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; -import static org.assertj.core.api.Assertions.assertThat; import org.custommonkey.xmlunit.Diff; -import static org.custommonkey.xmlunit.XMLAssert.assertXMLIdentical; -import static org.custommonkey.xmlunit.XMLAssert.assertXMLNotEqual; +import org.junit.Ignore; import org.junit.Test; import org.w3c.dom.Attr; import org.w3c.dom.Document; @@ -674,6 +677,162 @@ public void postProcess(Element recessive, Element dominant, Element result) { assertXMLIdentical(new Diff(result, combineWithKeysAndFilter(Lists.newArrayList(), filter, recessive, dominant)), true); } + + @Ignore + @Test + public void supportRuntimeMergeFilterSelective() throws Exception { + //TODO: make it work - needs XmlCombiner logic fix + String recessive = "\n" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + String dominant = "\n" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + String expected = "\n" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " " + + ""; + + XmlCombiner.MergeFilter filter = new XmlCombiner.MergeFilter() { + @Override + public CombineChildren query(Element element) { + if (element.getTagName().equals("root")) { + return CombineChildren.MERGE; // for config tags + } else if (element.getTagName().equals("config")) { + return CombineChildren.APPEND; // for service tags + } + + return CombineChildren.MERGE; // for config tags + } + }; + + applyMergeFilter(new String[]{recessive, dominant}, filter, expected, false); + } + + @Test + public void supportRuntimeMergeFilterAppendDifferent() throws Exception { + String recessive = "\n" + + "\n" + + " \n" + + " \n" + + ""; + String dominant = "\n" + + "\n" + + " \n" + + " \n" + + ""; + String expected = "\n" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + XmlCombiner.MergeFilter filter = new XmlCombiner.MergeFilter() { + @Override + public CombineChildren query(Element element) { + return CombineChildren.APPEND; + } + }; + + applyMergeFilter(new String[]{recessive, dominant}, filter, expected, true); + } + + @Test + public void supportRuntimeMergeFilterSameAppend() throws Exception { + String recessive = "\n" + + "\n" + + " \n" + + " \n" + + ""; + String dominant = "\n" + + "\n" + + " \n" + + " \n" + + ""; + String expected = "\n" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + XmlCombiner.MergeFilter filter = new XmlCombiner.MergeFilter() { + @Override + public CombineChildren query(Element element) { + return CombineChildren.APPEND; + } + }; + + applyMergeFilter(new String[]{recessive, dominant}, filter, expected, true); + } + + private void applyMergeFilter(String[] inputs, XmlCombiner.MergeFilter filter, String expected, boolean identical) throws Exception { + XmlCombiner combiner = new XmlCombiner(); + combiner.setFilter(filter); + + for (String input : inputs) { + combiner.combine(new ByteArrayInputStream(input.getBytes())); + } + Document combinedResult = combiner.buildDocument(); + + Transformer transformer = TransformerFactory.newInstance().newTransformer(); + StringWriter writer = new StringWriter(); + transformer.transform(new DOMSource(combinedResult), new StreamResult(writer)); + String result = writer.toString(); + + if (identical) { + assertXMLIdentical(new Diff(result, expected), true); + } else { + System.out.println(expected); + System.out.println("-"); + System.out.println(result); + assertXMLEqual(expected, result); + } + } @Test