All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.maven.toolchain.v4.MavenToolchainsMerger Maven / Gradle / Ivy

// =================== DO NOT EDIT THIS FILE ====================
//  Generated by Modello Velocity from merger.vm
//  template, any modifications will be overwritten.
// ==============================================================
package org.apache.maven.toolchain.v4;

import java.io.ObjectStreamException;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.apache.maven.api.annotations.Generated;
import org.apache.maven.api.xml.XmlNode;
import org.apache.maven.api.toolchain.TrackableBase;
import org.apache.maven.api.toolchain.PersistedToolchains;
import org.apache.maven.api.toolchain.ToolchainModel;
import org.apache.maven.api.toolchain.InputLocation;
import org.apache.maven.api.toolchain.InputSource;

@Generated
public class MavenToolchainsMerger {

    private final boolean deepMerge;

    public MavenToolchainsMerger() {
        this(true);
    }

    public MavenToolchainsMerger(boolean deepMerge) {
        this.deepMerge = deepMerge;
    }

    /**
     * Merges the specified source object into the given target object.
     *
     * @param target The target object whose existing contents should be merged with the source, must not be
     *            null.
     * @param source The (read-only) source object that should be merged into the target object, may be
     *            null.
     * @param sourceDominant A flag indicating whether either the target object or the source object provides the
     *            dominant data.
     * @param hints A set of key-value pairs that customized merger implementations can use to carry domain-specific
     *            information along, may be null.
     */
    public PersistedToolchains merge(PersistedToolchains target, PersistedToolchains source, boolean sourceDominant, Map hints) {
        Objects.requireNonNull(target, "target cannot be null");
        if (source == null) {
            return target;
        }
        Map context = new HashMap<>();
        if (hints != null) {
            context.putAll(hints);
        }
        return mergePersistedToolchains(target, source, sourceDominant, context);
    }

    protected TrackableBase mergeTrackableBase(TrackableBase target, TrackableBase source, boolean sourceDominant, Map context) {
        TrackableBase.Builder builder = TrackableBase.newBuilder(target);
        mergeTrackableBase(builder, target, source, sourceDominant, context);
        return builder.build();
    }

    protected void mergeTrackableBase(TrackableBase.Builder builder, TrackableBase target, TrackableBase source, boolean sourceDominant, Map context) {
    }


    protected PersistedToolchains mergePersistedToolchains(PersistedToolchains target, PersistedToolchains source, boolean sourceDominant, Map context) {
        PersistedToolchains.Builder builder = PersistedToolchains.newBuilder(target);
        mergePersistedToolchains(builder, target, source, sourceDominant, context);
        return builder.build();
    }

    protected void mergePersistedToolchains(PersistedToolchains.Builder builder, PersistedToolchains target, PersistedToolchains source, boolean sourceDominant, Map context) {
        mergeTrackableBase(builder, target, source, sourceDominant, context);
        mergePersistedToolchains_Toolchains(builder, target, source, sourceDominant, context);
    }

    protected void mergePersistedToolchains_Toolchains(PersistedToolchains.Builder builder, PersistedToolchains target, PersistedToolchains source, boolean sourceDominant, Map context) {
        if (deepMerge) {
            builder.toolchains(merge(target.getToolchains(), source.getToolchains(), getToolchainModelKey(),
                    (t, s) -> mergeToolchainModel(t, s, sourceDominant, context)));
        } else {
            builder.toolchains(merge(target.getToolchains(), source.getToolchains(), sourceDominant, getToolchainModelKey()));
        }
    }

    protected ToolchainModel mergeToolchainModel(ToolchainModel target, ToolchainModel source, boolean sourceDominant, Map context) {
        ToolchainModel.Builder builder = ToolchainModel.newBuilder(target);
        mergeToolchainModel(builder, target, source, sourceDominant, context);
        return builder.build();
    }

    protected void mergeToolchainModel(ToolchainModel.Builder builder, ToolchainModel target, ToolchainModel source, boolean sourceDominant, Map context) {
        mergeTrackableBase(builder, target, source, sourceDominant, context);
        mergeToolchainModel_Type(builder, target, source, sourceDominant, context);
        mergeToolchainModel_Provides(builder, target, source, sourceDominant, context);
        mergeToolchainModel_Configuration(builder, target, source, sourceDominant, context);
    }

    protected void mergeToolchainModel_Type(ToolchainModel.Builder builder, ToolchainModel target, ToolchainModel source, boolean sourceDominant, Map context) {
        String src = source.getType();
        String tgt = target.getType();
        if (src != null && (sourceDominant || tgt == null)) {
            builder.type(src);
            builder.location("type", source.getLocation("type"));
        }
    }
    protected void mergeToolchainModel_Provides(ToolchainModel.Builder builder, ToolchainModel target, ToolchainModel source, boolean sourceDominant, Map context) {
        Map src = source.getProvides();
        if (!src.isEmpty()) {
            Map tgt = target.getProvides();
            if (tgt.isEmpty()) {
                builder.provides(src);
                builder.location("provides", source.getLocation("provides"));
            } else {
                Map merged = new HashMap<>();
                merged.putAll(sourceDominant ? target.getProvides() : source.getProvides());
                merged.putAll(sourceDominant ? source.getProvides() : target.getProvides());
                builder.provides(merged);
                builder.location("provides", InputLocation.merge(target.getLocation("provides"), source.getLocation("provides"), sourceDominant));
            }
        }
    }
    protected void mergeToolchainModel_Configuration(ToolchainModel.Builder builder, ToolchainModel target, ToolchainModel source, boolean sourceDominant, Map context) {
        XmlNode src = source.getConfiguration();
        if (src != null) {
            XmlNode tgt = target.getConfiguration();
            if (tgt == null) {
                builder.configuration(src);
                builder.location("configuration", source.getLocation("configuration"));
            } else if (sourceDominant) {
                builder.configuration(src.merge(tgt));
                builder.location("configuration", target.getLocation("configuration"));
            } else {
                builder.configuration(tgt.merge(src));
                builder.location("configuration", null);
            }
        }
    }


    protected KeyComputer getTrackableBaseKey() {
        return v -> v;
    }
    protected KeyComputer getPersistedToolchainsKey() {
        return v -> v;
    }
    protected KeyComputer getToolchainModelKey() {
        return v -> v;
    }

    /**
     * Use to compute keys for data structures
     * @param  the data structure type
     */
    @FunctionalInterface
    public interface KeyComputer extends Function {
    }

    /**
     * Merge two lists
     */
    public static  List merge(List tgt, List src, boolean sourceDominant, KeyComputer computer) {
        return merge(tgt, src, computer, (t, s) -> sourceDominant ? s : t);
    }

    public static  List merge(List tgt, List src, KeyComputer computer, BinaryOperator remapping) {
        if (src.isEmpty()) {
            return tgt;
        }

        MergingList list;
        if (tgt instanceof MergingList) {
            list = (MergingList) tgt;
        } else {
            list = new MergingList<>(computer, src.size() + tgt.size());
            list.mergeAll(tgt, (t, s) -> s);
        }

        list.mergeAll(src, remapping);
        return list;
    }

    /**
     * Merging list
     * @param 
     */
    private static class MergingList extends AbstractList implements java.io.Serializable {

        private final KeyComputer keyComputer;
        private Map map;
        private List list;

        MergingList(KeyComputer keyComputer, int initialCapacity) {
            this.map = new LinkedHashMap<>(initialCapacity);
            this.keyComputer = keyComputer;
        }

        Object writeReplace() throws ObjectStreamException {
            return new ArrayList<>(this);
        }

        @Override
        public Iterator iterator() {
            if (map != null) {
                return map.values().iterator();
            } else {
                return list.iterator();
            }
        }

        void mergeAll(Collection vs, BinaryOperator remapping) {
            if (map == null) {
                map = list.stream().collect(Collectors.toMap(keyComputer,
                    Function.identity(),
                    null,
                    LinkedHashMap::new));
                list = null;
            }

            if (vs instanceof MergingList && ((MergingList) vs).map != null) {
                for (Map.Entry e : ((MergingList) vs).map.entrySet()) {
                    Object key = e.getKey();
                    V v = e.getValue();
                    map.merge(key, v, remapping);
                }
            } else {
                for (V v : vs) {
                    Object key = keyComputer.apply(v);
                    map.merge(key, v, remapping);
                }
            }
        }

        @Override
        public boolean contains(Object o) {
            if (map != null) {
                return map.containsValue(o);
            } else {
                return list.contains(o);
            }
        }

        private List asList() {
            if (list == null) {
                list = new ArrayList<>(map.values());
                map = null;
            }
            return list;
        }

        @Override
        public void add(int index, V element) {
            asList().add(index, element);
        }

        @Override
        public V remove(int index) {
            return asList().remove(index);
        }

        @Override
        public V get(int index) {
            return asList().get(index);
        }

        @Override
        public int size() {
            if (map != null) {
                return map.size();
            } else {
                return list.size();
            }
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy