View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.model.profile;
20  
21  import java.util.ArrayList;
22  import java.util.Collection;
23  import java.util.Collections;
24  import java.util.HashSet;
25  import java.util.List;
26  import javax.inject.Inject;
27  import javax.inject.Named;
28  import javax.inject.Singleton;
29  import org.apache.maven.model.Activation;
30  import org.apache.maven.model.Profile;
31  import org.apache.maven.model.building.ModelProblem.Severity;
32  import org.apache.maven.model.building.ModelProblem.Version;
33  import org.apache.maven.model.building.ModelProblemCollector;
34  import org.apache.maven.model.building.ModelProblemCollectorRequest;
35  import org.apache.maven.model.profile.activation.ProfileActivator;
36  
37  /**
38   * Calculates the active profiles among a given collection of profiles.
39   *
40   * @author Benjamin Bentmann
41   */
42  @Named
43  @Singleton
44  public class DefaultProfileSelector implements ProfileSelector {
45  
46      private final List<ProfileActivator> activators;
47  
48      public DefaultProfileSelector() {
49          this.activators = Collections.emptyList();
50      }
51  
52      @Inject
53      public DefaultProfileSelector(List<ProfileActivator> activators) {
54          this.activators = new ArrayList<>(activators);
55      }
56  
57      public DefaultProfileSelector addProfileActivator(ProfileActivator profileActivator) {
58          if (profileActivator != null) {
59              activators.add(profileActivator);
60          }
61          return this;
62      }
63  
64      @Override
65      public List<Profile> getActiveProfiles(
66              Collection<Profile> profiles, ProfileActivationContext context, ModelProblemCollector problems) {
67          Collection<String> activatedIds = new HashSet<>(context.getActiveProfileIds());
68          Collection<String> deactivatedIds = new HashSet<>(context.getInactiveProfileIds());
69  
70          List<Profile> activeProfiles = new ArrayList<>(profiles.size());
71          List<Profile> activePomProfilesByDefault = new ArrayList<>();
72          boolean activatedPomProfileNotByDefault = false;
73  
74          for (Profile profile : profiles) {
75              if (!deactivatedIds.contains(profile.getId())) {
76                  if (activatedIds.contains(profile.getId()) || isActive(profile, context, problems)) {
77                      activeProfiles.add(profile);
78  
79                      if (Profile.SOURCE_POM.equals(profile.getSource())) {
80                          activatedPomProfileNotByDefault = true;
81                      }
82                  } else if (isActiveByDefault(profile)) {
83                      if (Profile.SOURCE_POM.equals(profile.getSource())) {
84                          activePomProfilesByDefault.add(profile);
85                      } else {
86                          activeProfiles.add(profile);
87                      }
88                  }
89              }
90          }
91  
92          if (!activatedPomProfileNotByDefault) {
93              activeProfiles.addAll(activePomProfilesByDefault);
94          }
95  
96          return activeProfiles;
97      }
98  
99      private boolean isActive(Profile profile, ProfileActivationContext context, ModelProblemCollector problems) {
100         boolean isActive = false;
101         for (ProfileActivator activator : activators) {
102             if (activator.presentInConfig(profile, context, problems)) {
103                 isActive = true;
104                 try {
105                     if (!activator.isActive(profile, context, problems)) {
106                         return false;
107                     }
108                 } catch (RuntimeException e) {
109                     problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE)
110                             .setMessage("Failed to determine activation for profile " + profile.getId())
111                             .setLocation(profile.getLocation(""))
112                             .setException(e));
113                     return false;
114                 }
115             }
116         }
117         return isActive;
118     }
119 
120     private boolean isActiveByDefault(Profile profile) {
121         Activation activation = profile.getActivation();
122         return activation != null && activation.isActiveByDefault();
123     }
124 }