001package org.apache.maven.model.profile;
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.ArrayList;
023import java.util.Collection;
024import java.util.HashSet;
025import java.util.List;
026
027import org.apache.maven.model.Activation;
028import org.apache.maven.model.Profile;
029import org.apache.maven.model.building.ModelProblemCollector;
030import org.apache.maven.model.building.ModelProblem.Severity;
031import org.apache.maven.model.building.ModelProblem.Version;
032import org.apache.maven.model.building.ModelProblemCollectorRequest;
033import org.apache.maven.model.profile.activation.ProfileActivator;
034import org.codehaus.plexus.component.annotations.Component;
035import org.codehaus.plexus.component.annotations.Requirement;
036
037/**
038 * Calculates the active profiles among a given collection of profiles.
039 *
040 * @author Benjamin Bentmann
041 */
042@Component( role = ProfileSelector.class )
043public class DefaultProfileSelector
044    implements ProfileSelector
045{
046
047    @Requirement( role = ProfileActivator.class )
048    private List<ProfileActivator> activators = new ArrayList<>();
049
050    public DefaultProfileSelector addProfileActivator( ProfileActivator profileActivator )
051    {
052        if ( profileActivator != null )
053        {
054            activators.add( profileActivator );
055        }
056        return this;
057    }
058
059    @Override
060    public List<Profile> getActiveProfiles( Collection<Profile> profiles, ProfileActivationContext context,
061                                            ModelProblemCollector problems )
062    {
063        Collection<String> activatedIds = new HashSet<>( context.getActiveProfileIds() );
064        Collection<String> deactivatedIds = new HashSet<>( context.getInactiveProfileIds() );
065
066        List<Profile> activeProfiles = new ArrayList<>( profiles.size() );
067        List<Profile> activePomProfilesByDefault = new ArrayList<>();
068        boolean activatedPomProfileNotByDefault = false;
069
070        for ( Profile profile : profiles )
071        {
072            if ( !deactivatedIds.contains( profile.getId() ) )
073            {
074                if ( activatedIds.contains( profile.getId() ) || isActive( profile, context, problems ) )
075                {
076                    activeProfiles.add( profile );
077
078                    if ( Profile.SOURCE_POM.equals( profile.getSource() ) )
079                    {
080                        activatedPomProfileNotByDefault = true;
081                    }
082                }
083                else if ( isActiveByDefault( profile ) )
084                {
085                    if ( Profile.SOURCE_POM.equals( profile.getSource() ) )
086                    {
087                        activePomProfilesByDefault.add( profile );
088                    }
089                    else
090                    {
091                        activeProfiles.add( profile );
092                    }
093                }
094
095            }
096        }
097
098        if ( !activatedPomProfileNotByDefault )
099        {
100            activeProfiles.addAll( activePomProfilesByDefault );
101        }
102
103        return activeProfiles;
104    }
105
106    private boolean isActive( Profile profile, ProfileActivationContext context, ModelProblemCollector problems )
107    {
108        boolean isActive = false;
109        for ( ProfileActivator activator : activators )
110        {
111            if ( activator.presentInConfig( profile, context, problems ) )
112            {
113                isActive = true;
114            }
115        }
116        for ( ProfileActivator activator : activators )
117        {
118            try
119            {
120                if ( activator.presentInConfig( profile, context, problems ) )
121                {
122                    isActive &=  activator.isActive( profile, context, problems );
123                }
124            }
125            catch ( RuntimeException e )
126            {
127                problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE )
128                        .setMessage( "Failed to determine activation for profile " + profile.getId() )
129                        .setLocation( profile.getLocation( "" ) )
130                        .setException( e ) );
131                return false;
132            }
133        }
134        return isActive;
135    }
136
137    private boolean isActiveByDefault( Profile profile )
138    {
139        Activation activation = profile.getActivation();
140        return activation != null && activation.isActiveByDefault();
141    }
142
143}