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.model.Model;
23  import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
24  import org.apache.maven.plugin.MojoExecution;
25  import org.apache.maven.plugin.MojoExecution.Source;
26  import org.apache.maven.plugin.MojoExecutionException;
27  import org.apache.maven.plugins.annotations.Mojo;
28  import org.apache.maven.plugins.annotations.Parameter;
29  import org.apache.maven.project.MavenProject;
30  import org.codehaus.plexus.util.StringUtils;
31  import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter;
32  import org.codehaus.plexus.util.xml.XMLWriter;
33  import org.codehaus.plexus.util.xml.XmlWriterUtil;
34  
35  import java.io.IOException;
36  import java.io.StringWriter;
37  import java.util.List;
38  import java.util.Properties;
39  
40  /**
41   * Displays the effective POM as an XML for this build, with the active profiles factored in, or a specified artifact.
42   *
43   * @version $Id$
44   * @since 2.0
45   */
46  @Mojo( name = "effective-pom", aggregator = true )
47  public class EffectivePomMojo
48      extends AbstractEffectiveMojo
49  {
50      // ----------------------------------------------------------------------
51      // Mojo parameters
52      // ----------------------------------------------------------------------
53  
54      /**
55       * The Maven project.
56       *
57       * @since 2.0.2
58       */
59      @Parameter( defaultValue = "${project}", readonly = true, required = true )
60      private MavenProject project;
61  
62      /**
63       * The projects in the current build. The effective-POM for
64       * each of these projects will written.
65       */
66      @Parameter( defaultValue = "${reactorProjects}", required = true, readonly = true )
67      private List<MavenProject> projects;
68  
69      /**
70       * This mojo execution, used to determine if it was launched from the lifecycle or the command-line.
71       */
72      @Parameter( defaultValue = "${mojo}", required = true, readonly = true )
73      private MojoExecution mojoExecution;
74  
75      /**
76       * The artifact for which to display the effective POM.
77       * <br>
78       * <b>Note</b>: Should respect the Maven format, i.e. <code>groupId:artifactId[:version]</code>. The
79       * latest version of the artifact will be used when no version is specified.
80       *
81       * @since 3.0.0
82       */
83      @Parameter( property = "artifact" )
84      private String artifact;
85  
86      // ----------------------------------------------------------------------
87      // Public methods
88      // ----------------------------------------------------------------------
89  
90      /** {@inheritDoc} */
91      public void execute()
92          throws MojoExecutionException
93      {
94          if ( StringUtils.isNotEmpty( artifact ) )
95          {
96              project = getMavenProject( artifact );
97          }
98  
99          StringWriter w = new StringWriter();
100         String encoding = output != null ? project.getModel().getModelEncoding()
101                                 : System.getProperty( "file.encoding" );
102         XMLWriter writer =
103             new PrettyPrintXMLWriter( w, StringUtils.repeat( " ", XmlWriterUtil.DEFAULT_INDENTATION_SIZE ),
104                                       encoding, null );
105 
106         writeHeader( writer );
107 
108         if ( shouldWriteAllEffectivePOMsInReactor() )
109         {
110             // outer root element
111             writer.startElement( "projects" );
112             for ( MavenProject subProject : projects )
113             {
114                 writeEffectivePom( subProject, writer );
115             }
116             writer.endElement();
117         }
118         else
119         {
120             writeEffectivePom( project, writer );
121         }
122 
123         String effectivePom = prettyFormat( w.toString(), encoding, false );
124 
125         if ( output != null )
126         {
127             try
128             {
129                 writeXmlFile( output, effectivePom );
130             }
131             catch ( IOException e )
132             {
133                 throw new MojoExecutionException( "Cannot write effective-POM to output: " + output, e );
134             }
135 
136             getLog().info( "Effective-POM written to: " + output );
137         }
138         else
139         {
140             StringBuilder message = new StringBuilder();
141 
142             message.append( LS );
143             message.append( "Effective POMs, after inheritance, interpolation, and profiles are applied:" );
144             message.append( LS ).append( LS );
145             message.append( effectivePom );
146             message.append( LS );
147 
148             getLog().info( message.toString() );
149         }
150     }
151 
152     /**
153      * Determines if all effective POMs of all the projects in the reactor should be written. When this goal is started
154      * on the command-line, it is always the case. However, when it is bound to a phase in the lifecycle, it is only the
155      * case when the current project being built is the head project in the reactor.
156      *
157      * @return <code>true</code> if all effective POMs should be written, <code>false</code> otherwise.
158      */
159     private boolean shouldWriteAllEffectivePOMsInReactor()
160     {
161         Source source = mojoExecution.getSource();
162         // [MNG-5550] For Maven < 3.2.1, the source is null, instead of LIFECYCLE: only rely on comparisons with CLI
163         return projects.size() > 1
164             && ( source == Source.CLI || source != Source.CLI && projects.get( 0 ).equals( project ) );
165     }
166 
167     // ----------------------------------------------------------------------
168     // Private methods
169     // ----------------------------------------------------------------------
170 
171     /**
172      * Method for writing the effective pom informations of the current build.
173      *
174      * @param project the project of the current build, not null.
175      * @param writer the XML writer , not null, not null.
176      * @throws MojoExecutionException if any
177      */
178     private static void writeEffectivePom( MavenProject project, XMLWriter writer )
179         throws MojoExecutionException
180     {
181         Model pom = project.getModel();
182         cleanModel( pom );
183 
184         StringWriter sWriter = new StringWriter();
185         MavenXpp3Writer pomWriter = new MavenXpp3Writer();
186         try
187         {
188             pomWriter.write( sWriter, pom );
189         }
190         catch ( IOException e )
191         {
192             throw new MojoExecutionException( "Cannot serialize POM to XML.", e );
193         }
194 
195         // This removes the XML declaration written by MavenXpp3Writer
196         String effectivePom = prettyFormat( sWriter.toString(), null, true );
197 
198         writeComment( writer, "Effective POM for project \'" + project.getId() + "\'" );
199 
200         writer.writeMarkup( effectivePom );
201     }
202 
203     /**
204      * Apply some logic to clean the model before writing it.
205      *
206      * @param pom not null
207      */
208     private static void cleanModel( Model pom )
209     {
210         Properties properties = new SortedProperties();
211         properties.putAll( pom.getProperties() );
212         pom.setProperties( properties );
213     }
214 }