Skip to content

Commit

Permalink
Support combine.self="remove"
Browse files Browse the repository at this point in the history
  • Loading branch information
belingueres authored and rfscholte committed Dec 7, 2019
1 parent ecdbeeb commit 89f74c5
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 3 deletions.
24 changes: 21 additions & 3 deletions src/main/java/org/codehaus/plexus/util/xml/Xpp3Dom.java
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
// ----------------------------------------------------------------------
Expand Down Expand Up @@ -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 ) );
}
Expand Down Expand Up @@ -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 );
}
}
}
}
Expand Down
30 changes: 30 additions & 0 deletions src/test/java/org/codehaus/plexus/util/xml/Xpp3DomTest.java
Expand Up @@ -329,6 +329,36 @@ public void testDupeChildren()
assertEquals( "y", dom.getChild( "foo" ).getValue() );
}

@Test
public void testShouldRemoveEntireElementWithAttributesAndChildren()
throws Exception
{
String dominantStr = "<config><service combine.self=\"remove\"/></config>";
String recessiveStr = "<config><service><parameter>parameter</parameter></service></config>";
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 = "<config><service combine.self=\"remove\"/></config>";
String recessiveStr = "<config><service><parameter>parameter</parameter></service></config>";
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
{
Expand Down

0 comments on commit 89f74c5

Please sign in to comment.