blob: f42eb1219030ad2ea4c5fb12c0604ae30cce981f [file] [log] [blame]
package org.apache.maven.shared.utils.xml;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
*
*/
public class Xpp3DomUtils
{
/**
* @param dominant {@link Xpp3Dom}
* @param recessive {@link Xpp3Dom}
* @param childMergeOverride true/false.
* @return Merged dom.
*/
public static Xpp3Dom mergeXpp3Dom( Xpp3Dom dominant, Xpp3Dom recessive, Boolean childMergeOverride )
{
return dominant != null ? merge( dominant, recessive, childMergeOverride ) : recessive;
}
/**
* @param dominant {@link Xpp3Dom}
* @param recessive {@link Xpp3Dom}
* @return Merged dom.
*/
public static Xpp3Dom mergeXpp3Dom( Xpp3Dom dominant, Xpp3Dom recessive )
{
return dominant != null ? merge( dominant, recessive, null ) : recessive;
}
/**
* @param dominant {@link Xpp3Dom}
* @param recessive {@link Xpp3Dom}
* @param childMergeOverride true/false.
* @return Merged dom.
*/
public static Xpp3Dom merge( Xpp3Dom dominant, Xpp3Dom recessive, Boolean childMergeOverride )
{
if ( recessive == null || isCombineSelfOverride( dominant ) )
{
return dominant;
}
if ( isEmpty( dominant.getValue() ) )
{
dominant.setValue( recessive.getValue() );
}
for ( String attr : recessive.getAttributeNames() )
{
if ( isEmpty( dominant.getAttribute( attr ) ) )
{
dominant.setAttribute( attr, recessive.getAttribute( attr ) );
}
}
if ( recessive.getChildCount() > 0 )
{
boolean mergeChildren = isMergeChildren( dominant, childMergeOverride );
if ( mergeChildren )
{
Map<String, Iterator<Xpp3Dom>> commonChildren = getCommonChildren( dominant, recessive );
for ( Xpp3Dom recessiveChild : recessive )
{
Iterator<Xpp3Dom> it = commonChildren.get( recessiveChild.getName() );
if ( it == null )
{
dominant.addChild( new Xpp3Dom( recessiveChild ) );
}
else if ( it.hasNext() )
{
Xpp3Dom dominantChild = it.next();
merge( dominantChild, recessiveChild, childMergeOverride );
}
}
}
else
{
Xpp3Dom[] dominantChildren = dominant.getChildren();
dominant.childList.clear();
for ( Xpp3Dom child : recessive )
{
dominant.addChild( new Xpp3Dom( child ) );
}
for ( Xpp3Dom aDominantChildren : dominantChildren )
{
dominant.addChild( aDominantChildren );
}
}
}
return dominant;
}
private static Map<String, Iterator<Xpp3Dom>> getCommonChildren( Xpp3Dom dominant, Xpp3Dom recessive )
{
Map<String, Iterator<Xpp3Dom>> commonChildren = new HashMap<>();
for ( String childName : recessive.childMap.keySet() )
{
List<Xpp3Dom> dominantChildren = dominant.getChildrenList( childName );
if ( dominantChildren.size() > 0 )
{
commonChildren.put( childName, dominantChildren.iterator() );
}
}
return commonChildren;
}
private static boolean isCombineSelfOverride( Xpp3Dom xpp3Dom )
{
String selfMergeMode = xpp3Dom.getAttribute( Xpp3Dom.SELF_COMBINATION_MODE_ATTRIBUTE );
return Xpp3Dom.SELF_COMBINATION_OVERRIDE.equals( selfMergeMode );
}
private static boolean isMergeChildren( Xpp3Dom dominant, Boolean override )
{
return override != null ? override : !isMergeChildren( dominant );
}
private static boolean isMergeChildren( Xpp3Dom dominant )
{
return Xpp3Dom.CHILDREN_COMBINATION_APPEND.equals(
dominant.getAttribute( Xpp3Dom.CHILDREN_COMBINATION_MODE_ATTRIBUTE ) );
}
/**
* @param str The string to be checked.
* @return <code>true</code> in case string is empty <code>false</code> otherwise.
*/
public static boolean isEmpty( String str )
{
return str == null || str.trim().length() == 0;
}
}