1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 package com.qulice.maven;
32
33 import com.jcabi.log.Logger;
34 import com.qulice.spi.ResourceValidator;
35 import com.qulice.spi.ValidationException;
36 import com.qulice.spi.Validator;
37 import com.qulice.spi.Violation;
38 import java.io.File;
39 import java.util.Collection;
40 import java.util.Collections;
41 import java.util.LinkedList;
42 import java.util.Locale;
43 import java.util.concurrent.Callable;
44 import java.util.concurrent.ExecutionException;
45 import java.util.concurrent.ExecutorService;
46 import java.util.concurrent.Executors;
47 import java.util.concurrent.Future;
48 import java.util.concurrent.TimeUnit;
49 import java.util.concurrent.TimeoutException;
50 import org.apache.maven.plugin.MojoFailureException;
51 import org.apache.maven.plugins.annotations.LifecyclePhase;
52 import org.apache.maven.plugins.annotations.Mojo;
53 import org.apache.maven.plugins.annotations.ResolutionScope;
54
55
56
57
58
59
60 @Mojo(name = "check", defaultPhase = LifecyclePhase.VERIFY,
61 requiresDependencyResolution = ResolutionScope.TEST,
62 threadSafe = true)
63 public final class CheckMojo extends AbstractQuliceMojo {
64
65
66
67
68 private final ExecutorService executors =
69 Executors.newFixedThreadPool(5);
70
71
72
73
74 private ValidatorsProvider provider =
75 new DefaultValidatorsProvider(this.env());
76
77 @Override
78 public void doExecute() throws MojoFailureException {
79 try {
80 this.run();
81 } catch (final ValidationException ex) {
82 Logger.info(
83 this,
84 "Read our quality policy: http://www.qulice.com/quality.html"
85 );
86 throw new MojoFailureException("Failure", ex);
87 }
88 }
89
90
91
92
93
94 public void setValidatorsProvider(final ValidatorsProvider prov) {
95 this.provider = prov;
96 }
97
98
99
100
101
102 private void run() throws ValidationException {
103 final LinkedList<Violation> results = new LinkedList<>();
104 final MavenEnvironment env = this.env();
105 final Collection<File> files = env.files("*.*");
106 if (!files.isEmpty()) {
107 final Collection<ResourceValidator> validators =
108 this.provider.externalResource();
109 final Collection<Future<Collection<Violation>>> futures =
110 this.submit(env, files, validators);
111 for (final Future<Collection<Violation>> future : futures) {
112 try {
113 results.addAll(future.get(10L, TimeUnit.MINUTES));
114 } catch (final InterruptedException ex) {
115 Thread.currentThread().interrupt();
116 throw new IllegalStateException(ex);
117 } catch (final ExecutionException | TimeoutException ex) {
118 throw new IllegalStateException(ex);
119 }
120 }
121 Collections.sort(results);
122 for (final Violation result : results) {
123 Logger.info(
124 this,
125 "%s: %s[%s]: %s (%s)",
126 result.validator(),
127 result.file().replace(
128 String.format(
129 "%s/", this.session().getExecutionRootDirectory()
130 ),
131 ""
132 ),
133 result.lines(),
134 result.message(),
135 result.name()
136 );
137 }
138 }
139 if (!results.isEmpty()) {
140 throw new ValidationException(
141 String.format("There are %d violations", results.size())
142 );
143 }
144 for (final Validator validator : this.provider.external()) {
145 Logger.info(this, "Starting %s validator", validator.name());
146 validator.validate(env);
147 Logger.info(this, "Finishing %s validator", validator.name());
148 }
149 for (final MavenValidator validator : this.provider.internal()) {
150 validator.validate(env);
151 }
152 }
153
154
155
156
157
158
159
160
161 @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops")
162 private Collection<Future<Collection<Violation>>> submit(
163 final MavenEnvironment env, final Collection<File> files,
164 final Collection<ResourceValidator> validators) {
165 final Collection<Future<Collection<Violation>>> futures =
166 new LinkedList<>();
167 for (final ResourceValidator validator : validators) {
168 futures.add(
169 this.executors.submit(
170 new ValidatorCallable(validator, env, files)
171 )
172 );
173 }
174 return futures;
175 }
176
177
178
179
180
181
182
183
184 private static Collection<File> filter(final MavenEnvironment env,
185 final Collection<File> files, final ResourceValidator validator) {
186 final Collection<File> filtered = new LinkedList<>();
187 for (final File file : files) {
188 if (
189 !env.exclude(
190 validator.name().toLowerCase(Locale.ENGLISH),
191 file.toString()
192 )
193 ) {
194 filtered.add(file);
195 }
196 }
197 return filtered;
198 }
199
200
201
202
203
204
205 private static class ValidatorCallable
206 implements Callable<Collection<Violation>> {
207
208
209
210 private final ResourceValidator validator;
211
212
213
214
215 private final MavenEnvironment env;
216
217
218
219
220 private final Collection<File> files;
221
222
223
224
225
226
227
228 ValidatorCallable(final ResourceValidator validator,
229 final MavenEnvironment env, final Collection<File> files) {
230 this.validator = validator;
231 this.env = env;
232 this.files = files;
233 }
234
235 @Override
236 public Collection<Violation> call() {
237 return this.validator.validate(
238 CheckMojo.filter(this.env, this.files, this.validator)
239 );
240 }
241 }
242 }