From 89f74c56f4e15b0603c5e8f76cbe4b3c0a1e880a Mon Sep 17 00:00:00 2001 From: Gabriel Belingueres Date: Sat, 7 Dec 2019 08:41:30 -0300 Subject: [PATCH] Support combine.self="remove" --- .../org/codehaus/plexus/util/xml/Xpp3Dom.java | 24 +++++++++++++-- .../codehaus/plexus/util/xml/Xpp3DomTest.java | 30 +++++++++++++++++++ 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/codehaus/plexus/util/xml/Xpp3Dom.java b/src/main/java/org/codehaus/plexus/util/xml/Xpp3Dom.java index 49b25f89..a7026384 100644 --- a/src/main/java/org/codehaus/plexus/util/xml/Xpp3Dom.java +++ b/src/main/java/org/codehaus/plexus/util/xml/Xpp3Dom.java @@ -22,7 +22,6 @@ import java.io.Serializable; import java.io.StringWriter; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; @@ -76,6 +75,8 @@ public class Xpp3Dom public static final String SELF_COMBINATION_MERGE = "merge"; + public static final String SELF_COMBINATION_REMOVE = "remove"; + /** * This default mode for combining a DOM node during merge means that where element names match, the process will * try to merge the element attributes and values, rather than overriding the recessive element completely with the @@ -301,6 +302,13 @@ public void removeChild( int i ) child.setParent( null ); } + public void removeChild( Xpp3Dom child ) + { + childList.remove( child ); + // In case of any dangling references + child.setParent( null ); + } + // ---------------------------------------------------------------------- // Parent handling // ---------------------------------------------------------------------- @@ -418,7 +426,7 @@ private static void mergeIntoXpp3Dom( Xpp3Dom dominant, Xpp3Dom recessive, Boole { for ( String attr : recessive.attributes.keySet() ) { - if ( isEmpty( dominant.getAttribute( attr ) ) ) + if ( isEmpty( dominant.getAttribute( attr ) ) && !SELF_COMBINATION_MODE_ATTRIBUTE.equals( attr ) ) { dominant.setAttribute( attr, recessive.getAttribute( attr ) ); } @@ -489,7 +497,17 @@ private static void mergeIntoXpp3Dom( Xpp3Dom dominant, Xpp3Dom recessive, Boole else if ( it.hasNext() ) { Xpp3Dom dominantChild = it.next(); - mergeIntoXpp3Dom( dominantChild, recessiveChild, childMergeOverride ); + + String dominantChildCombinationMode = + dominantChild.getAttribute( SELF_COMBINATION_MODE_ATTRIBUTE ); + if ( SELF_COMBINATION_REMOVE.equals( dominantChildCombinationMode ) ) + { + dominant.removeChild( dominantChild ); + } + else + { + mergeIntoXpp3Dom( dominantChild, recessiveChild, childMergeOverride ); + } } } } diff --git a/src/test/java/org/codehaus/plexus/util/xml/Xpp3DomTest.java b/src/test/java/org/codehaus/plexus/util/xml/Xpp3DomTest.java index 04444f31..35fb5590 100644 --- a/src/test/java/org/codehaus/plexus/util/xml/Xpp3DomTest.java +++ b/src/test/java/org/codehaus/plexus/util/xml/Xpp3DomTest.java @@ -329,6 +329,36 @@ public void testDupeChildren() assertEquals( "y", dom.getChild( "foo" ).getValue() ); } + @Test + public void testShouldRemoveEntireElementWithAttributesAndChildren() + throws Exception + { + String dominantStr = ""; + String recessiveStr = "parameter"; + Xpp3Dom dominantConfig = Xpp3DomBuilder.build( new StringReader( dominantStr ) ); + Xpp3Dom recessiveConfig = Xpp3DomBuilder.build( new StringReader( recessiveStr ) ); + + Xpp3Dom result = Xpp3Dom.mergeXpp3Dom( dominantConfig, recessiveConfig ); + + assertEquals( 0, result.getChildCount() ); + assertEquals( "config", result.getName() ); + } + + @Test + public void testShouldRemoveDoNotRemoveTagWhenSwappedInputDOMs() + throws Exception + { + String dominantStr = ""; + String recessiveStr = "parameter"; + Xpp3Dom dominantConfig = Xpp3DomBuilder.build( new StringReader( dominantStr ) ); + Xpp3Dom recessiveConfig = Xpp3DomBuilder.build( new StringReader( recessiveStr ) ); + + // same DOMs as testShouldRemoveEntireElementWithAttributesAndChildren(), swapping dominant <--> recessive + Xpp3Dom result = Xpp3Dom.mergeXpp3Dom( recessiveConfig, dominantConfig ); + + assertEquals( recessiveConfig.toString(), result.toString() ); + } + private static class FixedInputLocationBuilder implements Xpp3DomBuilder.InputLocationBuilder {