
org.codehaus.plexus.configuration.PlexusConfigurationUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of maven-site-plugin Show documentation
Show all versions of maven-site-plugin Show documentation
The Maven Site Plugin is a plugin that generates a site for the current project.
The newest version!
package org.codehaus.plexus.configuration;
/*
* 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.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.TreeSet;
/**
* Utilities for working with {@link PlexusConfiguration} objects
*
* @author Eric Dalquist
* @version $Revision: 25140 $
*/
public final class PlexusConfigurationUtils {
/**
* How duplicate entries should be handled post-merge, if true they are removed, if false they are not removed.
* Defaults to false.
*/
public static final String REMOVE_DUPLICATE_POLICY = "merge:removeDuplicates";
/**
* Defines the various types of merge policy type attributes
*/
public enum MergePolicyType {
/**
* {@link MergePolicy} to apply to the element itself
* @see MergePolicy
*/
SELF_MERGE_POLICY("merge:self"),
/**
* {@link MergePolicy} to apply to children, only applicable if the {@link MergePolicy} for the element itself is MERGE
* @see MergePolicy
*/
CHILDREN_MERGE_POLICY("merge:children");
private final String attributeName;
private MergePolicyType(String attributeName) {
this.attributeName = attributeName;
}
/**
* @see #getMergePolicy(PlexusConfiguration, MergePolicy)
*/
public MergePolicy getMergePolicy(PlexusConfiguration configuration) {
return getMergePolicy(configuration, null);
}
/**
* Get the {@link MergePolicy} configured on the {@link PlexusConfiguration} for this attribute type.
*
* @param configuration The configuration element
* @param defaultMergePolicy The default value to return if no {@link MergePolicy} is specified
*/
public MergePolicy getMergePolicy(PlexusConfiguration configuration, MergePolicy defaultMergePolicy) {
if (configuration == null) {
return defaultMergePolicy;
}
final String duplicatePolicy = configuration.getAttribute(attributeName);
if (duplicatePolicy == null) {
return defaultMergePolicy;
}
try {
return MergePolicy.valueOf(duplicatePolicy);
}
catch (IllegalArgumentException e) {
throw new IllegalArgumentException(
"Cannot assign value " + duplicatePolicy +
" to property " + attributeName + " of " + configuration.getName() +
". No enum const class " + MergePolicy.class.getName() + "." +
duplicatePolicy);
}
}
}
/**
* Does a deep-comparison of two PlexusConfiguration objects
*/
public static Comparator PLEXUS_CONFIG_COMPARATOR = new PlexusConfigurationComparator();
private PlexusConfigurationUtils() {
}
/**
* Merge two elements, treats the two elements as if {@link MergePolicyType#SELF_MERGE_POLICY} is set to
* {@link MergePolicy#MERGE} on the secondary argument
*/
public static PlexusConfiguration merge(PlexusConfiguration primary, PlexusConfiguration secondary) {
//Shortcuts for null configs
if (secondary == null) {
return primary;
}
if (primary == null) {
return secondary;
}
//Sanity check the config element names
final String newName = secondary.getName();
final String existingName = primary.getName();
if (!newName.equals(existingName)) {
throw new IllegalArgumentException("Cannot merge two PlexusConfiguration elements with different names " +
newName + "!=" + existingName);
}
//Merge the attributes
mergeAttributes(primary, secondary);
if (secondary.getChildCount() == 0 && primary.getChildCount() == 0) {
//No children, just merge (overwrite) the existing value
final String newValue = secondary.getValue();
primary.setValue(newValue);
return primary;
}
if (primary.getChildCount() == 0 && primary.getValue() != null) {
//primary has no children but has a value, convert it to a child element with the same name as the parent
final String value = primary.getValue();
primary.setValue(null);
primary.addChild(primary.getName(), value);
}
if (secondary.getChildCount() == 0 && secondary.getValue() != null) {
//secondary has no children but has a value, convert it to a child element with the same name as the parent
final String value = secondary.getValue();
secondary.setValue(null);
secondary.addChild(secondary.getName(), value);
}
//Clone the primary config so we can overwrite children if needed
final MutablePlexusConfiguration mergedConfiguration = new MutablePlexusConfiguration(primary);
for (final PlexusConfiguration newChildConfiguration : secondary.getChildren()) {
final MergePolicy selfMergePolicy = MergePolicyType.SELF_MERGE_POLICY.getMergePolicy(newChildConfiguration, MergePolicy.MERGE);
switch (selfMergePolicy) {
case FIRST: {
//Only add the newChildConfiguration if there is no existing child
final String childName = newChildConfiguration.getName();
final PlexusConfiguration existingChildConfiguration = mergedConfiguration.getChild(childName, false);
if (existingChildConfiguration == null) {
mergedConfiguration.addChild(newChildConfiguration);
}
break;
}
case LAST: {
//Just wholesale replace the existing child
//If primary has more than one child with the specified name only replace the last instance
mergedConfiguration.replaceLastChild(newChildConfiguration);
break;
}
case MERGE: {
final MergePolicy childrenMergePolicy = MergePolicyType.CHILDREN_MERGE_POLICY.getMergePolicy(newChildConfiguration, selfMergePolicy);
switch (childrenMergePolicy) {
case BOTH: {
final String childName = newChildConfiguration.getName();
final PlexusConfiguration existingChildConfiguration = mergedConfiguration.getChild(childName, false);
if (existingChildConfiguration == null) {
mergedConfiguration.addChild(newChildConfiguration);
}
else {
//Merge attributes
mergeAttributes(existingChildConfiguration, newChildConfiguration);
//If removing duplicates create set of all existing children for easy comparison
final Set existingChildren;
final boolean removeDuplicates = Boolean.parseBoolean(newChildConfiguration.getAttribute(REMOVE_DUPLICATE_POLICY));
if (removeDuplicates) {
existingChildren = new TreeSet(PLEXUS_CONFIG_COMPARATOR);
Collections.addAll(existingChildren, existingChildConfiguration.getChildren());
}
else {
existingChildren = Collections.emptySet();
}
//Copy over new childrent into existing parent, not adding any new child that is in the existingChildConfiguration set
for (final PlexusConfiguration child : newChildConfiguration.getChildren()) {
if (!existingChildren.contains(child)) {
existingChildConfiguration.addChild(child);
}
}
}
break;
}
case FIRST: {
final String childName = newChildConfiguration.getName();
final PlexusConfiguration existingChildConfiguration = mergedConfiguration.getChild(childName, false);
if (existingChildConfiguration == null) {
mergedConfiguration.addChild(newChildConfiguration);
}
break;
}
case LAST:
case MERGE: {
final String childName = newChildConfiguration.getName();
final PlexusConfiguration existingChildConfiguration = mergedConfiguration.getChild(childName);
final PlexusConfiguration mergedChildConfiguration = merge(existingChildConfiguration, newChildConfiguration);
mergedConfiguration.replaceLastChild(mergedChildConfiguration);
break;
}
}
break;
}
case BOTH: {
//Just add the new child
mergedConfiguration.addChild(newChildConfiguration);
break;
}
}
}
return mergedConfiguration;
}
/**
* Copies attributes from the secondary config item into the primar config item
*/
private static void mergeAttributes(PlexusConfiguration primary, PlexusConfiguration secondary) {
//merge attributes means overwriting existing attributes with new values
for (final String attributeName : secondary.getAttributeNames()) {
final String value = secondary.getAttribute(attributeName);
primary.setAttribute(attributeName, value);
}
}
private static class PlexusConfigurationComparator implements Comparator {
/* (non-Javadoc)
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
*/
public int compare(PlexusConfiguration o1, PlexusConfiguration o2) {
//Check name
final int name = nullSafeCompare(o1.getName(), o2.getName());
if (name != 0) {
return name;
}
//Check value
final int value = nullSafeCompare(o1.getValue(), o2.getValue());
if (value != 0) {
return value;
}
//Check attributes (order doesn't matter)
final Set attrNames1 = new LinkedHashSet(Arrays.asList(o1.getAttributeNames()));
final Set attrNames2 = new LinkedHashSet(Arrays.asList(o2.getAttributeNames()));
if (!attrNames1.equals(attrNames2)) {
return -1;
}
for (final String attrName : attrNames1) {
final int attrComp = nullSafeCompare(o1.getAttribute(attrName), o2.getAttribute(attrName));
if (attrComp != 0) {
return attrComp;
}
}
//Check children (order matters)
if (o1.getChildCount() < o2.getChildCount()) {
return -1;
}
if (o1.getChildCount() > o2.getChildCount()) {
return 1;
}
if (o1.getChildCount() > 0) {
final PlexusConfiguration[] children1 = o1.getChildren();
final PlexusConfiguration[] children2 = o2.getChildren();
for (int index = 0; index < children1.length; index++) {
final int child = compare(children1[index], children2[index]);
if (child != 0) {
return child;
}
}
}
return 0;
}
private > int nullSafeCompare(T o1, T o2) {
if (o1 == o2) {
return 0;
}
if (o1 == null) {
return -1;
}
if (o2 == null) {
return 1;
}
return o1.compareTo(o2);
}
};
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy