001package org.apache.maven.toolchain.merge;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *  http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import java.util.LinkedHashMap;
023import java.util.List;
024import java.util.Map;
025
026import org.apache.maven.toolchain.model.PersistedToolchains;
027import org.apache.maven.toolchain.model.ToolchainModel;
028import org.codehaus.plexus.util.xml.Xpp3Dom;
029
030/**
031 * 
032 * @author Robert Scholte
033 * @since 3.2.4
034 */
035public class MavenToolchainMerger
036{
037
038    public void merge( PersistedToolchains dominant, PersistedToolchains recessive, String recessiveSourceLevel )
039    {
040        if ( dominant == null || recessive == null )
041        {
042            return;
043        }
044
045        recessive.setSourceLevel( recessiveSourceLevel );
046
047        shallowMerge( dominant.getToolchains(), recessive.getToolchains(), recessiveSourceLevel );
048    }
049
050    private void shallowMerge( List<ToolchainModel> dominant, List<ToolchainModel> recessive,
051                               String recessiveSourceLevel )
052    {
053        Map<Object, ToolchainModel> merged = new LinkedHashMap<>();
054
055        for ( ToolchainModel dominantModel : dominant )
056        {
057            Object key = getToolchainModelKey( dominantModel );
058            
059            merged.put( key, dominantModel );
060        }
061
062        for ( ToolchainModel recessiveModel : recessive )
063        {
064            Object key = getToolchainModelKey( recessiveModel );
065            
066            ToolchainModel dominantModel = merged.get( key );
067            if ( dominantModel == null )
068            {
069                recessiveModel.setSourceLevel( recessiveSourceLevel );
070                dominant.add( recessiveModel );
071            }
072            else
073            {
074                mergeToolchainModel_Configuration( dominantModel, recessiveModel );
075            }
076        }
077    }
078
079    protected void mergeToolchainModel_Configuration( ToolchainModel target,
080                                                      ToolchainModel source )
081    {
082        Xpp3Dom src = (Xpp3Dom) source.getConfiguration();
083        if ( src != null )
084        {
085            Xpp3Dom tgt = (Xpp3Dom) target.getConfiguration();
086            if ( tgt == null )
087            {
088                tgt = Xpp3Dom.mergeXpp3Dom( new Xpp3Dom( src ), tgt );
089            }
090            else
091            {
092                tgt = Xpp3Dom.mergeXpp3Dom( tgt, src );
093            }
094            target.setConfiguration( tgt );
095        }
096    }
097
098    protected Object getToolchainModelKey( ToolchainModel model )
099    {
100        return model;
101    }
102
103}