1
2
3
4
5 package com.qulice.spi;
6
7 import java.io.File;
8 import java.io.IOException;
9 import java.nio.charset.Charset;
10 import java.nio.charset.StandardCharsets;
11 import java.nio.file.Files;
12 import java.util.ArrayList;
13 import java.util.Arrays;
14 import java.util.Collection;
15 import java.util.Collections;
16 import java.util.HashMap;
17 import java.util.HashSet;
18 import java.util.Map;
19 import java.util.Set;
20 import org.apache.commons.io.FileUtils;
21 import org.apache.commons.io.filefilter.DirectoryFileFilter;
22 import org.apache.commons.io.filefilter.IOFileFilter;
23 import org.apache.commons.io.filefilter.WildcardFileFilter;
24
25
26
27
28
29
30 @SuppressWarnings("PMD.TooManyMethods")
31 public interface Environment {
32
33
34
35
36
37
38 File basedir();
39
40
41
42
43
44
45 File tempdir();
46
47
48
49
50
51
52 File outdir();
53
54
55
56
57
58
59
60
61
62
63
64
65
66 Collection<File> testdirs();
67
68
69
70
71
72
73
74
75 String param(String name, String value);
76
77
78
79
80
81
82 ClassLoader classloader();
83
84
85
86
87
88
89 Collection<String> classpath();
90
91
92
93
94
95
96
97
98
99
100
101 Collection<File> files(String pattern);
102
103
104
105
106
107
108
109
110 boolean exclude(String check, String name);
111
112
113
114
115
116
117
118
119
120
121 Collection<String> excludes(String checker);
122
123
124
125
126
127
128 Charset encoding();
129
130
131
132
133
134
135 final class Mock implements Environment {
136
137
138
139
140 private final File origin;
141
142
143
144
145 private final Set<String> paths;
146
147
148
149
150 private final Map<String, String> params;
151
152
153
154
155 private final Collection<File> tests;
156
157
158
159
160 private String excl;
161
162
163
164
165 public Mock() {
166 this(Environment.Mock.temporary());
167 }
168
169
170
171
172
173
174 private Mock(final File base) {
175 this(base, Environment.Mock.outputs(base));
176 }
177
178
179
180
181
182
183
184 private Mock(final File base, final Set<String> dirs) {
185 this.origin = base;
186 this.paths = dirs;
187 this.params = new HashMap<>();
188 this.tests = new ArrayList<>(0);
189 }
190
191
192
193
194
195
196
197
198 public Environment.Mock withTestdir(final String path) {
199 this.tests.add(new File(this.origin, path));
200 return this;
201 }
202
203
204
205
206
207
208
209
210 public Environment.Mock withParam(final String name,
211 final String value) {
212 this.params.put(name, value);
213 return this;
214 }
215
216
217
218
219
220
221
222
223
224 public Environment.Mock withFile(final String name,
225 final String content) throws IOException {
226 FileUtils.writeStringToFile(
227 new File(this.origin, name),
228 content,
229 StandardCharsets.UTF_8
230 );
231 return this;
232 }
233
234
235
236
237
238
239
240
241
242 public Environment.Mock withFile(final String name,
243 final byte[] bytes) throws IOException {
244 FileUtils.writeByteArrayToFile(new File(this.origin, name), bytes);
245 return this;
246 }
247
248
249
250
251
252
253
254 public Environment.Mock withExcludes(final String excludes) {
255 this.excl = excludes;
256 return this;
257 }
258
259
260
261
262
263
264 public Environment.Mock withDefaultClasspath() {
265 Collections.addAll(
266 this.paths,
267 System.getProperty("java.class.path")
268 .split(System.getProperty("path.separator"))
269 );
270 return this;
271 }
272
273 @Override
274 public File basedir() {
275 return this.origin;
276 }
277
278 @Override
279 public File tempdir() {
280 final File file = new File(this.origin, "target/tempdir");
281 if (!file.mkdirs() && !file.isDirectory()) {
282 throw new IllegalStateException(
283 String.format("cannot create tempdir at %s", file)
284 );
285 }
286 return file;
287 }
288
289 @Override
290 public File outdir() {
291 final File file = new File(this.origin, "target/classes");
292 if (!file.mkdirs() && !file.isDirectory()) {
293 throw new IllegalStateException(
294 String.format("cannot create outdir at %s", file)
295 );
296 }
297 return file;
298 }
299
300 @Override
301 public Collection<File> testdirs() {
302 final Collection<File> dirs = new ArrayList<>(this.tests);
303 dirs.add(new File(this.origin, "src/test"));
304 return dirs;
305 }
306
307 @Override
308 public String param(final String name, final String value) {
309 String val = this.params.get(name);
310 if (val == null) {
311 val = value;
312 }
313 return val;
314 }
315
316 @Override
317 public ClassLoader classloader() {
318 return Thread.currentThread().getContextClassLoader();
319 }
320
321 @Override
322 public Collection<String> classpath() {
323 return Collections.unmodifiableCollection(this.paths);
324 }
325
326 @Override
327 public Collection<File> files(final String pattern) {
328 final Collection<File> files = new ArrayList<>(0);
329 final IOFileFilter filter = WildcardFileFilter.builder().setWildcards(pattern).get();
330 if (this.basedir().exists()) {
331 for (final File found : FileUtils.listFiles(
332 this.basedir(),
333 filter,
334 DirectoryFileFilter.INSTANCE
335 )) {
336 if (!new Binary(found).yes()) {
337 files.add(found);
338 }
339 }
340 }
341 return files;
342 }
343
344 @Override
345 public boolean exclude(final String check, final String name) {
346 return false;
347 }
348
349 @Override
350 public Collection<String> excludes(final String checker) {
351 final Collection<String> exc;
352 if (this.excl == null) {
353 exc = Collections.emptyList();
354 } else {
355 exc = Arrays.asList(this.excl.split(","));
356 }
357 return exc;
358 }
359
360 @Override
361 public Charset encoding() {
362 return StandardCharsets.UTF_8;
363 }
364
365 private static File temporary() {
366 try {
367 final File temp = Files.createTempDirectory("mock-qulice").toFile();
368 FileUtils.forceDeleteOnExit(temp);
369 final File base = new File(temp, "basedir");
370 if (!base.mkdirs()) {
371 throw new IllegalStateException(
372 String.format("cannot create basedir at %s", base)
373 );
374 }
375 return base;
376 } catch (final IOException ex) {
377 throw new IllegalStateException("cannot create basedir", ex);
378 }
379 }
380
381 private static Set<String> outputs(final File base) {
382 final File out = new File(base, "target/classes");
383 if (!out.mkdirs() && !out.isDirectory()) {
384 throw new IllegalStateException(
385 String.format("cannot create classes dir at %s", out)
386 );
387 }
388 return new HashSet<>(
389 Collections.singleton(
390 out.getAbsolutePath().replace(File.separatorChar, '/')
391 )
392 );
393 }
394 }
395 }