1
2
3
4
5 package com.qulice.maven;
6
7 import com.google.common.base.Function;
8 import com.google.common.base.Predicate;
9 import com.google.common.base.Predicates;
10 import com.google.common.collect.Collections2;
11 import com.google.common.collect.Iterables;
12 import com.jcabi.log.Logger;
13 import java.io.File;
14 import java.net.MalformedURLException;
15 import java.net.URI;
16 import java.net.URL;
17 import java.net.URLClassLoader;
18 import java.nio.charset.Charset;
19 import java.security.PrivilegedAction;
20 import java.util.Collection;
21 import java.util.LinkedList;
22 import java.util.List;
23 import java.util.Properties;
24 import javax.annotation.Nullable;
25 import org.apache.commons.io.FileUtils;
26 import org.apache.commons.io.FilenameUtils;
27 import org.apache.commons.io.filefilter.DirectoryFileFilter;
28 import org.apache.commons.io.filefilter.IOFileFilter;
29 import org.apache.commons.io.filefilter.WildcardFileFilter;
30 import org.apache.maven.artifact.Artifact;
31 import org.apache.maven.artifact.DependencyResolutionRequiredException;
32 import org.apache.maven.project.MavenProject;
33 import org.codehaus.plexus.context.Context;
34
35
36
37
38
39
40
41 @SuppressWarnings("PMD.TooManyMethods")
42 public final class DefaultMavenEnvironment implements MavenEnvironment {
43
44
45
46
47 private MavenProject iproject;
48
49
50
51
52 private Context icontext;
53
54
55
56
57 private final Properties iproperties = new Properties();
58
59
60
61
62 private MojoExecutor exectr;
63
64
65
66
67 private final Collection<String> exc = new LinkedList<>();
68
69
70
71
72 private final Collection<String> assertion = new LinkedList<>();
73
74
75
76
77 private String charset = "UTF-8";
78
79 @Override
80 public String param(final String name, final String value) {
81 String ret = this.iproperties.getProperty(name);
82 if (ret == null) {
83 ret = value;
84 }
85 return ret;
86 }
87
88 @Override
89 public File basedir() {
90 return this.iproject.getBasedir();
91 }
92
93 @Override
94 public File tempdir() {
95 return new File(this.iproject.getBuild().getOutputDirectory());
96 }
97
98 @Override
99 public File outdir() {
100 return new File(this.iproject.getBuild().getOutputDirectory());
101 }
102
103 @Override
104 @SuppressWarnings({"PMD.AvoidInstantiatingObjectsInLoops", "deprecation"})
105 public Collection<String> classpath() {
106 final Collection<String> paths = new LinkedList<>();
107 final String blank = "%20";
108 final String whitespace = " ";
109 try {
110 for (final String name
111 : this.iproject.getRuntimeClasspathElements()) {
112 paths.add(
113 name.replace(
114 File.separatorChar, '/'
115 ).replaceAll(whitespace, blank)
116 );
117 }
118 for (final Artifact artifact
119 : this.iproject.getDependencyArtifacts()) {
120 if (artifact.getFile() != null) {
121 paths.add(
122 artifact.getFile().getAbsolutePath()
123 .replace(File.separatorChar, '/')
124 .replaceAll(whitespace, blank)
125 );
126 }
127 }
128 } catch (final DependencyResolutionRequiredException ex) {
129 throw new IllegalStateException("Failed to read classpath", ex);
130 }
131 return paths;
132 }
133
134 @Override
135 public ClassLoader classloader() {
136 final List<URL> urls = new LinkedList<>();
137 for (final String path : this.classpath()) {
138 try {
139 urls.add(
140 URI.create(String.format("file:///%s", path)).toURL()
141 );
142 } catch (final MalformedURLException ex) {
143 throw new IllegalStateException("Failed to build URL", ex);
144 }
145 }
146 final URLClassLoader loader =
147 new DefaultMavenEnvironment.PrivilegedClassLoader(urls).run();
148 for (final URL url : loader.getURLs()) {
149 Logger.debug(this, "Classpath: %s", url);
150 }
151 return loader;
152 }
153
154 @Override
155 public MavenProject project() {
156 return this.iproject;
157 }
158
159 @Override
160 public Properties properties() {
161 return this.iproperties;
162 }
163
164 @Override
165 public Context context() {
166 return this.icontext;
167 }
168
169 @Override
170 public Properties config() {
171 return this.iproperties;
172 }
173
174 @Override
175 public MojoExecutor executor() {
176 return this.exectr;
177 }
178
179 @Override
180 public Collection<String> asserts() {
181 return this.assertion;
182 }
183
184 @Override
185 @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops")
186 public Collection<File> files(final String pattern) {
187 final Collection<File> files = new LinkedList<>();
188 final IOFileFilter filter = WildcardFileFilter.builder().setWildcards(pattern).get();
189 final String[] dirs = {
190 "src",
191 };
192 for (final String dir : dirs) {
193 final File sources = new File(this.basedir(), dir);
194 if (sources.exists()) {
195 files.addAll(
196 FileUtils.listFiles(
197 sources,
198 filter,
199 DirectoryFileFilter.INSTANCE
200 )
201 );
202 }
203 }
204 return files;
205 }
206
207 @Override
208 public boolean exclude(final String check, final String name) {
209 return Iterables.any(
210 this.excludes(check),
211 new DefaultMavenEnvironment.PathPredicate(name)
212 );
213 }
214
215 @Override
216 public Collection<String> excludes(final String checker) {
217 final Collection<String> excludes = Collections2.transform(
218 this.exc,
219 new DefaultMavenEnvironment.CheckerExcludes(checker)
220 );
221 return Collections2.filter(excludes, Predicates.notNull());
222 }
223
224
225
226
227
228 public void setProject(final MavenProject proj) {
229 this.iproject = proj;
230 }
231
232
233
234
235
236 public void setContext(final Context ctx) {
237 this.icontext = ctx;
238 }
239
240
241
242
243
244 public void setMojoExecutor(final MojoExecutor exec) {
245 this.exectr = exec;
246 }
247
248
249
250
251
252
253 public void setProperty(final String name, final String value) {
254 this.iproperties.setProperty(name, value);
255 }
256
257
258
259
260
261 public void setExcludes(final Collection<String> exprs) {
262 this.exc.clear();
263 this.exc.addAll(exprs);
264 }
265
266
267
268
269
270 public void setAssertion(final Collection<String> ass) {
271 this.assertion.clear();
272 this.assertion.addAll(ass);
273 }
274
275 public void setEncoding(final String encoding) {
276 this.charset = encoding;
277 }
278
279 @Override
280 public Charset encoding() {
281 if (this.charset == null || this.charset.isEmpty()) {
282 this.charset = "UTF-8";
283 }
284 return Charset.forName(this.charset);
285 }
286
287
288
289
290
291
292 private static final class PrivilegedClassLoader implements
293 PrivilegedAction<URLClassLoader> {
294
295
296
297 private final List<URL> urls;
298
299
300
301
302
303 private PrivilegedClassLoader(final List<URL> urls) {
304 this.urls = urls;
305 }
306
307 @Override
308 public URLClassLoader run() {
309 return new URLClassLoader(
310 this.urls.toArray(new URL[this.urls.size()]),
311 Thread.currentThread().getContextClassLoader()
312 );
313 }
314 }
315
316
317
318
319
320
321 private static class PathPredicate implements Predicate<String> {
322
323
324
325 private final String name;
326
327
328
329
330
331 PathPredicate(final String name) {
332 this.name = name;
333 }
334
335 @Override
336 public boolean apply(@Nullable final String input) {
337 return input != null
338 && FilenameUtils.normalize(this.name, true).matches(input);
339 }
340 }
341
342
343
344
345
346
347
348
349 private static class CheckerExcludes implements Function<String, String> {
350
351
352
353
354 private final String checker;
355
356
357
358
359
360 CheckerExcludes(final String checker) {
361 this.checker = checker;
362 }
363
364 @Nullable
365 @Override
366 public String apply(@Nullable final String input) {
367 String result = null;
368 if (input != null) {
369 final String[] exclude = input.split(":", 2);
370 if (this.checker.equals(exclude[0]) && exclude.length > 1) {
371 result = exclude[1];
372 }
373 }
374 return result;
375 }
376 }
377 }