1 package org.apache.maven.plugins.enforcer;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.FileInputStream;
23 import java.io.IOException;
24 import java.util.HashMap;
25 import java.util.HashSet;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.Set;
29
30 import org.apache.maven.enforcer.rule.api.EnforcerRuleException;
31 import org.apache.maven.enforcer.rule.api.EnforcerRuleHelper;
32 import org.apache.maven.model.Dependency;
33 import org.apache.maven.model.Model;
34 import org.apache.maven.model.Profile;
35 import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
36 import org.apache.maven.project.MavenProject;
37 import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException;
38 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
39
40
41
42
43
44
45
46
47 public class BanDuplicatePomDependencyVersions
48 extends AbstractNonCacheableEnforcerRule
49 {
50 @Override
51 public void execute( EnforcerRuleHelper helper )
52 throws EnforcerRuleException
53 {
54
55 MavenProject project;
56 try
57 {
58 project = (MavenProject) helper.evaluate( "${project}" );
59 }
60 catch ( ExpressionEvaluationException eee )
61 {
62 throw new EnforcerRuleException( "Unable to retrieve the MavenProject: ", eee );
63 }
64
65
66 MavenXpp3Reader modelReader = new MavenXpp3Reader();
67
68 Model model;
69 try ( FileInputStream pomInputStream = new FileInputStream( project.getFile() ) )
70 {
71 model = modelReader.read( pomInputStream, false );
72 }
73 catch ( IOException | XmlPullParserException e )
74 {
75 throw new EnforcerRuleException( "Unable to retrieve the MavenProject: ", e );
76 }
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92 maven2Validation( helper, model );
93
94
95
96
97 }
98
99 private void maven2Validation( EnforcerRuleHelper helper, Model model )
100 throws EnforcerRuleException
101 {
102 List<Dependency> dependencies = model.getDependencies();
103 Map<String, Integer> duplicateDependencies = validateDependencies( dependencies );
104
105 int duplicates = duplicateDependencies.size();
106
107 StringBuilder summary = new StringBuilder();
108 messageBuilder( duplicateDependencies, "dependencies.dependency", summary );
109
110 if ( model.getDependencyManagement() != null )
111 {
112 List<Dependency> managementDependencies = model.getDependencyManagement().getDependencies();
113 Map<String, Integer> duplicateManagementDependencies = validateDependencies( managementDependencies );
114 duplicates += duplicateManagementDependencies.size();
115
116 messageBuilder( duplicateManagementDependencies, "dependencyManagement.dependencies.dependency", summary );
117 }
118
119 List<Profile> profiles = model.getProfiles();
120 for ( Profile profile : profiles )
121 {
122 List<Dependency> profileDependencies = profile.getDependencies();
123
124 Map<String, Integer> duplicateProfileDependencies = validateDependencies( profileDependencies );
125
126 duplicates += duplicateProfileDependencies.size();
127
128 messageBuilder( duplicateProfileDependencies, "profiles.profile[" + profile.getId()
129 + "].dependencies.dependency", summary );
130
131 if ( profile.getDependencyManagement() != null )
132 {
133 List<Dependency> profileManagementDependencies = profile.getDependencyManagement().getDependencies();
134
135 Map<String, Integer> duplicateProfileManagementDependencies =
136 validateDependencies( profileManagementDependencies );
137
138 duplicates += duplicateProfileManagementDependencies.size();
139
140 messageBuilder( duplicateProfileManagementDependencies, "profiles.profile[" + profile.getId()
141 + "].dependencyManagement.dependencies.dependency", summary );
142 }
143 }
144
145 if ( summary.length() > 0 )
146 {
147 StringBuilder message = new StringBuilder();
148 message.append( "Found " )
149 .append( duplicates )
150 .append( " duplicate dependency " );
151 message.append( duplicateDependencies.size() == 1 ? "declaration" : "declarations" )
152 .append( " in this project:" + System.lineSeparator() );
153 message.append( summary );
154 throw new EnforcerRuleException( message.toString() );
155 }
156 }
157
158 private void messageBuilder( Map<String, Integer> duplicateDependencies, String prefix, StringBuilder message )
159 {
160 if ( !duplicateDependencies.isEmpty() )
161 {
162 for ( Map.Entry<String, Integer> entry : duplicateDependencies.entrySet() )
163 {
164 message.append( " - " )
165 .append( prefix )
166 .append( '[' )
167 .append( entry.getKey() )
168 .append( "] ( " )
169 .append( entry.getValue() )
170 .append( " times )" + System.lineSeparator() );
171 }
172 }
173 }
174
175 private Map<String, Integer> validateDependencies( List<Dependency> dependencies )
176 throws EnforcerRuleException
177 {
178 Map<String, Integer> duplicateDeps = new HashMap<>();
179 Set<String> deps = new HashSet<>();
180 for ( Dependency dependency : dependencies )
181 {
182 String key = dependency.getManagementKey();
183
184 if ( deps.contains( key ) )
185 {
186 int times = 1;
187 if ( duplicateDeps.containsKey( key ) )
188 {
189 times = duplicateDeps.get( key );
190 }
191 duplicateDeps.put( key, times + 1 );
192 }
193 else
194 {
195 deps.add( key );
196 }
197 }
198 return duplicateDeps;
199 }
200
201 }