View Javadoc

1   package org.apache.maven.plugin.dependency.analyze;
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.commons.collections.CollectionUtils;
23  import org.apache.maven.model.Dependency;
24  import org.apache.maven.model.Model;
25  import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
26  import org.apache.maven.plugin.AbstractMojo;
27  import org.apache.maven.plugin.MojoExecutionException;
28  import org.apache.maven.plugin.MojoFailureException;
29  import org.apache.maven.plugins.annotations.Component;
30  import org.apache.maven.plugins.annotations.Mojo;
31  import org.apache.maven.plugins.annotations.Parameter;
32  import org.apache.maven.project.MavenProject;
33  import org.codehaus.plexus.util.IOUtil;
34  import org.codehaus.plexus.util.ReaderFactory;
35  
36  import java.io.Reader;
37  import java.util.ArrayList;
38  import java.util.HashSet;
39  import java.util.Iterator;
40  import java.util.List;
41  import java.util.Set;
42  
43  /**
44   * Analyzes the <code>&lt;dependencies/&gt;</code> and <code>&lt;dependencyManagement/&gt;</code> tags in the
45   * <code>pom.xml</code> and determines the duplicate declared dependencies.
46   *
47   * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
48   * @version $Id: AnalyzeDuplicateMojo.html 861760 2013-05-12 17:31:26Z hboutemy $
49   */
50  @Mojo( name = "analyze-duplicate", aggregator = false, threadSafe = true )
51  public class AnalyzeDuplicateMojo
52      extends AbstractMojo
53  {
54      /**
55       * Skip plugin execution completely.
56       *
57       * @since 2.7
58       */
59      @Parameter( property = "mdep.analyze.skip", defaultValue = "false" )
60      private boolean skip;
61  
62      /**
63       * The Maven project to analyze.
64       */
65      @Component
66      private MavenProject project;
67  
68      /**
69       * {@inheritDoc}
70       */
71      public void execute()
72          throws MojoExecutionException, MojoFailureException
73      {
74          if ( isSkip() )
75          {
76              getLog().info( "Skipping plugin execution" );
77              return;
78          }
79  
80          MavenXpp3Reader pomReader = new MavenXpp3Reader();
81          Model model = null;
82          Reader reader = null;
83          try
84          {
85              reader = ReaderFactory.newXmlReader( project.getFile() );
86              model = pomReader.read( reader );
87          }
88          catch ( Exception e )
89          {
90              throw new MojoExecutionException( "IOException: " + e.getMessage(), e );
91          }
92          finally
93          {
94              IOUtil.close( reader );
95          }
96  
97          Set<String> duplicateDependencies = new HashSet<String>();
98          if ( model.getDependencies() != null )
99          {
100             duplicateDependencies = findDuplicateDependencies( model.getDependencies() );
101         }
102 
103         Set<String> duplicateDependenciesManagement = new HashSet<String>();
104         if ( model.getDependencyManagement() != null && model.getDependencyManagement().getDependencies() != null )
105         {
106             duplicateDependenciesManagement =
107                 findDuplicateDependencies( model.getDependencyManagement().getDependencies() );
108         }
109 
110         if ( getLog().isInfoEnabled() )
111         {
112             StringBuilder sb = new StringBuilder();
113 
114             if ( !duplicateDependencies.isEmpty() )
115             {
116                 sb.append( "List of duplicate dependencies defined in <dependencies/> in your pom.xml:\n" );
117                 for ( Iterator<String> it = duplicateDependencies.iterator(); it.hasNext(); )
118                 {
119                     String dup = it.next();
120 
121                     sb.append( "\to " + dup );
122                     if ( it.hasNext() )
123                     {
124                         sb.append( "\n" );
125                     }
126                 }
127             }
128 
129             if ( !duplicateDependenciesManagement.isEmpty() )
130             {
131                 if ( sb.length() > 0 )
132                 {
133                     sb.append( "\n" );
134                 }
135                 sb.append(
136                     "List of duplicate dependencies defined in <dependencyManagement/> in " + "your pom.xml:\n" );
137                 for ( Iterator<String> it = duplicateDependenciesManagement.iterator(); it.hasNext(); )
138                 {
139                     String dup = it.next();
140 
141                     sb.append( "\to " + dup );
142                     if ( it.hasNext() )
143                     {
144                         sb.append( "\n" );
145                     }
146                 }
147             }
148 
149             if ( sb.length() > 0 )
150             {
151                 getLog().info( sb.toString() );
152             }
153             else
154             {
155                 getLog().info( "No duplicate dependencies found in <dependencies/> or in <dependencyManagement/>" );
156             }
157         }
158     }
159 
160     private Set<String> findDuplicateDependencies( List<Dependency> modelDependencies )
161     {
162         List<String> modelDependencies2 = new ArrayList<String>();
163         for ( Dependency dep : modelDependencies )
164         {
165             modelDependencies2.add( dep.getManagementKey() );
166         }
167 
168         return new HashSet<String>(
169             CollectionUtils.disjunction( modelDependencies2, new HashSet<String>( modelDependencies2 ) ) );
170     }
171 
172     public boolean isSkip()
173     {
174         return skip;
175     }
176 
177     public void setSkip( boolean skip )
178     {
179         this.skip = skip;
180     }
181 }