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