1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.enforcer.rules.dependency;
20
21 import java.util.Collections;
22 import java.util.List;
23 import java.util.Objects;
24
25 import org.apache.commons.lang3.StringUtils;
26 import org.apache.maven.artifact.Artifact;
27 import org.apache.maven.enforcer.rule.api.EnforcerRuleException;
28 import org.apache.maven.enforcer.rules.AbstractStandardEnforcerRule;
29 import org.apache.maven.enforcer.rules.utils.ArtifactUtils;
30 import org.apache.maven.execution.MavenSession;
31 import org.eclipse.aether.graph.DependencyNode;
32
33
34
35
36
37
38 abstract class BannedDependenciesBase extends AbstractStandardEnforcerRule {
39
40
41
42
43
44
45
46
47
48
49
50 private List<String> excludes = null;
51
52
53
54
55
56
57
58
59
60
61
62
63
64 private List<String> includes = null;
65
66
67 private boolean searchTransitive = true;
68
69 private final MavenSession session;
70
71 private final ResolverUtil resolverUtil;
72
73 BannedDependenciesBase(MavenSession session, ResolverUtil resolverUtil) {
74 this.session = Objects.requireNonNull(session);
75 this.resolverUtil = Objects.requireNonNull(resolverUtil);
76 }
77
78 protected MavenSession getSession() {
79 return session;
80 }
81
82 @Override
83 public void execute() throws EnforcerRuleException {
84
85 if (!searchTransitive) {
86 String result = session.getCurrentProject().getDependencyArtifacts().stream()
87 .filter(a -> !validate(a))
88 .collect(
89 StringBuilder::new,
90 (messageBuilder, node) -> messageBuilder
91 .append(System.lineSeparator())
92 .append(node.getId())
93 .append(" <--- ")
94 .append(getErrorMessage()),
95 (m1, m2) -> m1.append(m2.toString()))
96 .toString();
97 if (!result.isEmpty()) {
98 String message = "";
99 if (getMessage() != null) {
100 message = getMessage() + System.lineSeparator();
101 }
102 throw new EnforcerRuleException(message + result);
103 }
104 } else {
105 StringBuilder messageBuilder = new StringBuilder();
106 DependencyNode rootNode = resolverUtil.resolveTransitiveDependenciesVerbose(Collections.emptyList());
107 if (!validate(rootNode, 0, messageBuilder)) {
108 String message = "";
109 if (getMessage() != null) {
110 message = getMessage() + System.lineSeparator();
111 }
112 throw new EnforcerRuleException(message + messageBuilder);
113 }
114 }
115 }
116
117 protected boolean validate(DependencyNode node, int level, StringBuilder messageBuilder) {
118 boolean rootFailed = level > 0 && !validate(ArtifactUtils.toArtifact(node));
119 StringBuilder childMessageBuilder = new StringBuilder();
120 if (rootFailed
121 || !node.getChildren().stream()
122 .map(childNode -> validate(childNode, level + 1, childMessageBuilder))
123 .reduce(true, Boolean::logicalAnd)) {
124 messageBuilder
125 .append(StringUtils.repeat(" ", level))
126 .append(ArtifactUtils.toArtifact(node).getId());
127 if (rootFailed) {
128 messageBuilder.append(" <--- ").append(getErrorMessage());
129 }
130 messageBuilder.append(System.lineSeparator()).append(childMessageBuilder);
131 return false;
132 }
133 return true;
134 }
135
136 protected abstract String getErrorMessage();
137
138
139
140
141
142
143
144
145 protected abstract boolean validate(Artifact dependency);
146
147
148
149
150
151
152 public void setSearchTransitive(boolean theSearchTransitive) {
153 this.searchTransitive = theSearchTransitive;
154 }
155
156
157
158
159
160
161 public List<String> getExcludes() {
162 return this.excludes;
163 }
164
165
166
167
168
169
170
171
172
173
174
175 public void setExcludes(List<String> theExcludes) {
176 this.excludes = theExcludes;
177 }
178
179
180
181
182
183
184 public List<String> getIncludes() {
185 return this.includes;
186 }
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201 public void setIncludes(List<String> theIncludes) {
202 this.includes = theIncludes;
203 }
204
205 public boolean isSearchTransitive() {
206 return searchTransitive;
207 }
208 }