1 package org.apache.maven.plugin.dependency.analyze;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
45
46
47
48
49
50 @Mojo( name = "analyze-duplicate", aggregator = false, threadSafe = true )
51 public class AnalyzeDuplicateMojo
52 extends AbstractMojo
53 {
54
55
56
57
58
59 @Parameter( property = "mdep.analyze.skip", defaultValue = "false" )
60 private boolean skip;
61
62
63
64
65 @Component
66 private MavenProject project;
67
68
69
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 }