View Javadoc

1   package org.apache.maven.plugins.help;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.execution.MavenSession;
23  import org.apache.maven.model.Profile;
24  import org.apache.maven.plugin.MojoExecutionException;
25  import org.apache.maven.plugin.MojoFailureException;
26  import org.apache.maven.plugins.annotations.Component;
27  import org.apache.maven.plugins.annotations.Mojo;
28  import org.apache.maven.plugins.annotations.Parameter;
29  import org.apache.maven.profiles.DefaultMavenProfilesBuilder;
30  import org.apache.maven.profiles.DefaultProfileManager;
31  import org.apache.maven.profiles.ProfileManager;
32  import org.apache.maven.profiles.ProfilesConversionUtils;
33  import org.apache.maven.profiles.ProfilesRoot;
34  import org.apache.maven.profiles.activation.ProfileActivationException;
35  import org.apache.maven.project.MavenProject;
36  import org.apache.maven.settings.Settings;
37  import org.apache.maven.settings.SettingsUtils;
38  import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
39  
40  import java.io.File;
41  import java.io.IOException;
42  import java.util.List;
43  import java.util.Map;
44  
45  /**
46   * Displays a list of available profiles under the current project.
47   * <br/>
48   * <b>Note</b>: it will list <b>all</b> profiles for a project. If a
49   * profile comes up with a status <b>inactive</b> then there might be a need to
50   * set profile activation switches/property.
51   *
52   * @author <a href="mailto:rahul.thakur.xdev@gmail.com">Rahul Thakur</a>
53   * @version $Id: AllProfilesMojo.java 1446806 2013-02-15 23:07:28Z rfscholte $
54   * @since 2.1
55   */
56  @Mojo( name = "all-profiles", requiresProject = false )
57  public class AllProfilesMojo
58      extends AbstractHelpMojo
59  {
60      // ----------------------------------------------------------------------
61      // Mojo parameters
62      // ----------------------------------------------------------------------
63  
64      /**
65       * This is the list of projects currently slated to be built by Maven.
66       */
67      @Parameter( defaultValue = "${reactorProjects}", required = true, readonly = true )
68      private List<MavenProject> projects;
69  
70      /**
71       * The current build session instance. This is used for plugin manager API calls.
72       */
73      @Component
74      private MavenSession session;
75  
76      // ----------------------------------------------------------------------
77      // Public methods
78      // ----------------------------------------------------------------------
79  
80      /** {@inheritDoc} */
81      public void execute()
82          throws MojoExecutionException, MojoFailureException
83      {
84          StringBuilder descriptionBuffer = new StringBuilder();
85  
86          for ( MavenProject project : projects )
87          {
88              descriptionBuffer.append( "Listing Profiles for Project: " ).append( project.getId() ).append( "\n" );
89  
90              DefaultProfileManager pm =
91                  new DefaultProfileManager( session.getContainer(), session.getExecutionProperties() );
92  
93              // Obtain Profiles from external profiles.xml
94              try
95              {
96                  loadProjectExternalProfiles( pm, project.getBasedir() );
97              }
98              catch ( ProfileActivationException e )
99              {
100                 throw new MojoExecutionException( "Error obtaining external Profiles:" + e.getMessage(), e );
101             }
102 
103             // Attempt to obtain settings profiles
104             loadSettingsProfiles( pm, session.getSettings() );
105 
106             // Attempt to obtain profiles from pom.xml
107             loadProjectPomProfiles( pm, project );
108 
109             // now display
110             if ( null == pm.getExplicitlyActivatedIds() || pm.getExplicitlyActivatedIds().size() == 0 )
111             {
112                 if ( getLog().isWarnEnabled() )
113                 {
114                     getLog().warn( "No profiles detected!" );
115                 }
116             }
117             else
118             {
119                 // This feels more like a hack to filter out inactive profiles, there is no 'direct'
120                 // way to query activation status on a Profile instance.
121                 @SuppressWarnings( "unchecked" )
122                 Map<String, Profile> allProfilesByIds = pm.getProfilesById();
123 
124                 // active Profiles will be a subset of *all* profiles
125                 @SuppressWarnings( "unchecked" )
126                 List<Profile> activeProfiles = project.getActiveProfiles();
127                 for ( Profile activeProfile : activeProfiles )
128                 {
129                     // we already have the active profiles for the project, so remove them from the list of all
130                     // profiles.
131                     allProfilesByIds.remove( activeProfile.getId() );
132                 }
133 
134                 // display active profiles
135                 for ( Profile p : activeProfiles )
136                 {
137                     descriptionBuffer.append( "  Profile Id: " ).append( p.getId() );
138                     descriptionBuffer.append( " (Active: true , Source: " ).append( p.getSource() ).append( ")\n" );
139                 }
140 
141                 // display inactive profiles
142                 for ( Profile p : allProfilesByIds.values() )
143                 {
144                     descriptionBuffer.append( "  Profile Id: " ).append( p.getId() );
145                     descriptionBuffer.append( " (Active: false , Source: " ).append( p.getSource() ).append( ")\n" );
146                 }
147             }
148         }
149 
150         if ( output != null )
151         {
152             try
153             {
154                 writeFile( output, descriptionBuffer );
155             }
156             catch ( IOException e )
157             {
158                 throw new MojoExecutionException( "Cannot write profiles description to output: " + output, e );
159             }
160 
161             if ( getLog().isInfoEnabled() )
162             {
163                 getLog().info( "Wrote descriptions to: " + output );
164             }
165         }
166         else
167         {
168             if ( getLog().isInfoEnabled() )
169             {
170                 getLog().info( descriptionBuffer.toString() );
171             }
172         }
173     }
174 
175     // ----------------------------------------------------------------------
176     // Private methods
177     // ----------------------------------------------------------------------
178 
179     /**
180      * Loads up external Profiles using <code>profiles.xml</code> (if any) located in the current
181      * project's <code>${basedir}</code>.
182      *
183      * @param profileManager ProfileManager instance to use to load profiles from external Profiles.
184      * @param projectDir location of the current project, could be null.
185      * @throws ProfileActivationException, if there was an error loading profiles.
186      */
187     private void loadProjectExternalProfiles( ProfileManager profileManager, File projectDir )
188         throws ProfileActivationException
189     {
190         if ( projectDir == null )
191         {
192             return;
193         }
194 
195         if ( getLog().isDebugEnabled() )
196         {
197             getLog().debug( "Attempting to read profiles from external profiles.xml..." );
198         }
199 
200         try
201         {
202             DefaultMavenProfilesBuilder profilesBuilder = new DefaultMavenProfilesBuilder();
203             ProfilesRoot root = profilesBuilder.buildProfiles( projectDir );
204             if ( root != null )
205             {
206                 List<org.apache.maven.profiles.Profile> profiles = root.getProfiles(); 
207                 for ( org.apache.maven.profiles.Profile rawProfile : profiles )
208                 {
209                     Profile converted = ProfilesConversionUtils.convertFromProfileXmlProfile( rawProfile );
210                     profileManager.addProfile( converted );
211                     profileManager.explicitlyActivate( converted.getId() );
212                 }
213             }
214             else if ( getLog().isDebugEnabled() )
215             {
216                 getLog().debug( "ProfilesRoot was found to be NULL" );
217             }
218         }
219         catch ( IOException e )
220         {
221             throw new ProfileActivationException( "Cannot read profiles.xml resource from directory: "
222                 + projectDir, e );
223         }
224         catch ( XmlPullParserException e )
225         {
226             throw new ProfileActivationException( "Cannot parse profiles.xml resource from directory: "
227                 + projectDir, e );
228         }
229     }
230 
231     /**
232      * Load profiles from <code>pom.xml</code>.
233      *
234      * @param profilesManager not null
235      * @param project could be null
236      */
237     private void loadProjectPomProfiles( ProfileManager profilesManager, MavenProject project )
238     {
239         if ( project == null )
240         {
241             // shouldn't happen as this mojo requires a project
242             if ( getLog().isDebugEnabled() )
243             {
244                 getLog().debug( "No pom.xml found to read Profiles from." );
245             }
246 
247             return;
248         }
249 
250         if ( getLog().isDebugEnabled() )
251         {
252             getLog().debug( "Attempting to read profiles from pom.xml..." );
253         }
254 
255         // Attempt to obtain the list of profiles from pom.xml
256         List<Profile> profiles = project.getModel().getProfiles();
257         for ( Profile profile : profiles )
258         {
259             profilesManager.addProfile( profile );
260             profilesManager.explicitlyActivate( profile.getId() );
261         }
262 
263         MavenProject parent = project.getParent();
264         while ( parent != null )
265         {
266             List<Profile> profiles2 = parent.getModel().getProfiles();
267             for ( Profile profile : profiles2 )
268             {
269                 profilesManager.addProfile( profile );
270                 profilesManager.explicitlyActivate( profile.getId() );
271             }
272 
273             parent = parent.getParent();
274         }
275     }
276 
277     /**
278      * Load profiles from <code>settings.xml</code>.
279      *
280      * @param profileManager not null
281      * @param settings could be null
282      */
283     private void loadSettingsProfiles( ProfileManager profileManager, Settings settings )
284     {
285         if ( settings == null )
286         {
287             if ( getLog().isDebugEnabled() )
288             {
289                 getLog().debug( "No settings.xml detected." );
290             }
291 
292             return;
293         }
294 
295         if ( getLog().isDebugEnabled() )
296         {
297             getLog().debug( "Attempting to read profiles from settings.xml..." );
298         }
299 
300         List<org.apache.maven.settings.Profile> profiles = settings.getProfiles();
301         for ( org.apache.maven.settings.Profile rawProfile : profiles )
302         {
303             Profile profile = SettingsUtils.convertFromSettingsProfile( rawProfile );
304             profileManager.addProfile( profile );
305             profileManager.explicitlyActivate( profile.getId() );
306         }
307     }
308 }