Skip to content

Commit 89f74c5

Browse files
belingueresrfscholte
authored andcommitted
Support combine.self="remove"
1 parent ecdbeeb commit 89f74c5

File tree

2 files changed

+51
-3
lines changed

2 files changed

+51
-3
lines changed

src/main/java/org/codehaus/plexus/util/xml/Xpp3Dom.java

+21-3
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import java.io.Serializable;
2323
import java.io.StringWriter;
2424
import java.util.ArrayList;
25-
import java.util.Arrays;
2625
import java.util.Collections;
2726
import java.util.HashMap;
2827
import java.util.Iterator;
@@ -76,6 +75,8 @@ public class Xpp3Dom
7675

7776
public static final String SELF_COMBINATION_MERGE = "merge";
7877

78+
public static final String SELF_COMBINATION_REMOVE = "remove";
79+
7980
/**
8081
* This default mode for combining a DOM node during merge means that where element names match, the process will
8182
* 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 )
301302
child.setParent( null );
302303
}
303304

305+
public void removeChild( Xpp3Dom child )
306+
{
307+
childList.remove( child );
308+
// In case of any dangling references
309+
child.setParent( null );
310+
}
311+
304312
// ----------------------------------------------------------------------
305313
// Parent handling
306314
// ----------------------------------------------------------------------
@@ -418,7 +426,7 @@ private static void mergeIntoXpp3Dom( Xpp3Dom dominant, Xpp3Dom recessive, Boole
418426
{
419427
for ( String attr : recessive.attributes.keySet() )
420428
{
421-
if ( isEmpty( dominant.getAttribute( attr ) ) )
429+
if ( isEmpty( dominant.getAttribute( attr ) ) && !SELF_COMBINATION_MODE_ATTRIBUTE.equals( attr ) )
422430
{
423431
dominant.setAttribute( attr, recessive.getAttribute( attr ) );
424432
}
@@ -489,7 +497,17 @@ private static void mergeIntoXpp3Dom( Xpp3Dom dominant, Xpp3Dom recessive, Boole
489497
else if ( it.hasNext() )
490498
{
491499
Xpp3Dom dominantChild = it.next();
492-
mergeIntoXpp3Dom( dominantChild, recessiveChild, childMergeOverride );
500+
501+
String dominantChildCombinationMode =
502+
dominantChild.getAttribute( SELF_COMBINATION_MODE_ATTRIBUTE );
503+
if ( SELF_COMBINATION_REMOVE.equals( dominantChildCombinationMode ) )
504+
{
505+
dominant.removeChild( dominantChild );
506+
}
507+
else
508+
{
509+
mergeIntoXpp3Dom( dominantChild, recessiveChild, childMergeOverride );
510+
}
493511
}
494512
}
495513
}

src/test/java/org/codehaus/plexus/util/xml/Xpp3DomTest.java

+30
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,36 @@ public void testDupeChildren()
329329
assertEquals( "y", dom.getChild( "foo" ).getValue() );
330330
}
331331

332+
@Test
333+
public void testShouldRemoveEntireElementWithAttributesAndChildren()
334+
throws Exception
335+
{
336+
String dominantStr = "<config><service combine.self=\"remove\"/></config>";
337+
String recessiveStr = "<config><service><parameter>parameter</parameter></service></config>";
338+
Xpp3Dom dominantConfig = Xpp3DomBuilder.build( new StringReader( dominantStr ) );
339+
Xpp3Dom recessiveConfig = Xpp3DomBuilder.build( new StringReader( recessiveStr ) );
340+
341+
Xpp3Dom result = Xpp3Dom.mergeXpp3Dom( dominantConfig, recessiveConfig );
342+
343+
assertEquals( 0, result.getChildCount() );
344+
assertEquals( "config", result.getName() );
345+
}
346+
347+
@Test
348+
public void testShouldRemoveDoNotRemoveTagWhenSwappedInputDOMs()
349+
throws Exception
350+
{
351+
String dominantStr = "<config><service combine.self=\"remove\"/></config>";
352+
String recessiveStr = "<config><service><parameter>parameter</parameter></service></config>";
353+
Xpp3Dom dominantConfig = Xpp3DomBuilder.build( new StringReader( dominantStr ) );
354+
Xpp3Dom recessiveConfig = Xpp3DomBuilder.build( new StringReader( recessiveStr ) );
355+
356+
// same DOMs as testShouldRemoveEntireElementWithAttributesAndChildren(), swapping dominant <--> recessive
357+
Xpp3Dom result = Xpp3Dom.mergeXpp3Dom( recessiveConfig, dominantConfig );
358+
359+
assertEquals( recessiveConfig.toString(), result.toString() );
360+
}
361+
332362
private static class FixedInputLocationBuilder
333363
implements Xpp3DomBuilder.InputLocationBuilder
334364
{

0 commit comments

Comments
 (0)