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<ProfileActivator>();
049
050    public DefaultProfileSelector addProfileActivator( ProfileActivator profileActivator )
051    {
052        if ( profileActivator != null )
053        {
054            activators.add( profileActivator );
055        }
056        return this;
057    }
058
059    public List<Profile> getActiveProfiles( Collection<Profile> profiles, ProfileActivationContext context,
060                                            ModelProblemCollector problems )
061    {
062        Collection<String> activatedIds = new HashSet<String>( context.getActiveProfileIds() );
063        Collection<String> deactivatedIds = new HashSet<String>( context.getInactiveProfileIds() );
064
065        List<Profile> activeProfiles = new ArrayList<Profile>( profiles.size() );
066        List<Profile> activePomProfilesByDefault = new ArrayList<Profile>();
067        boolean activatedPomProfileNotByDefault = false;
068
069        for ( Profile profile : profiles )
070        {
071            if ( !deactivatedIds.contains( profile.getId() ) )
072            {
073                if ( activatedIds.contains( profile.getId() ) || isActive( profile, context, problems ) )
074                {
075                    activeProfiles.add( profile );
076
077                    if ( Profile.SOURCE_POM.equals( profile.getSource() ) )
078                    {
079                        activatedPomProfileNotByDefault = true;
080                    }
081                }
082                else if ( isActiveByDefault( profile ) )
083                {
084                    if ( Profile.SOURCE_POM.equals( profile.getSource() ) )
085                    {
086                        activePomProfilesByDefault.add( profile );
087                    }
088                    else
089                    {
090                        activeProfiles.add( profile );
091                    }
092                }
093
094            }
095        }
096
097        if ( !activatedPomProfileNotByDefault )
098        {
099            activeProfiles.addAll( activePomProfilesByDefault );
100        }
101
102        return activeProfiles;
103    }
104
105    private boolean isActive( Profile profile, ProfileActivationContext context, ModelProblemCollector problems )
106    {
107        boolean isActive = false;
108        for ( ProfileActivator activator : activators )
109        {
110            if ( activator.presentInConfig( profile, context, problems ) )
111            {
112                isActive = true;
113            }
114        }
115        for ( ProfileActivator activator : activators )
116        {
117            try
118            {
119                if ( activator.presentInConfig( profile, context, problems ) )
120                {
121                    isActive &=  activator.isActive( profile, context, problems );
122                }
123            }
124            catch ( RuntimeException e )
125            {
126                problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE )
127                        .setMessage( "Failed to determine activation for profile " + profile.getId() )
128                        .setLocation( profile.getLocation( "" ) )
129                        .setException( e ) );
130                return false;
131            }
132        }
133        return isActive;
134    }
135
136    private boolean isActiveByDefault( Profile profile )
137    {
138        Activation activation = profile.getActivation();
139        return activation != null && activation.isActiveByDefault();
140    }
141
142}