1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.model.interpolation;
20
21 import java.io.File;
22 import java.util.*;
23 import java.util.concurrent.Callable;
24 import java.util.concurrent.CountDownLatch;
25 import java.util.concurrent.Future;
26 import java.util.concurrent.FutureTask;
27
28 import org.apache.maven.model.InputLocation;
29 import org.apache.maven.model.InputSource;
30 import org.apache.maven.model.Model;
31 import org.apache.maven.model.building.DefaultModelBuildingRequest;
32 import org.apache.maven.model.building.ModelBuildingRequest;
33 import org.apache.maven.model.building.SimpleProblemCollector;
34
35 import static org.hamcrest.CoreMatchers.anyOf;
36 import static org.hamcrest.CoreMatchers.is;
37 import static org.junit.Assert.assertThat;
38 import static org.powermock.reflect.Whitebox.getField;
39 import static org.powermock.reflect.Whitebox.getInternalState;
40
41
42
43
44
45 public class StringSearchModelInterpolatorTest extends AbstractModelInterpolatorTest {
46
47 protected ModelInterpolator interpolator;
48
49 @Override
50 protected void setUp() throws Exception {
51 super.setUp();
52 interpolator =
53 new StringSearchModelInterpolator().setVersionPropertiesProcessor(new DefaultModelVersionProcessor());
54 }
55
56 protected ModelInterpolator createInterpolator(org.apache.maven.model.path.PathTranslator translator)
57 throws Exception {
58 return this.interpolator;
59 }
60
61 protected ModelInterpolator createInterpolator() throws Exception {
62 return this.interpolator;
63 }
64
65 public void testInterpolateStringArray() throws Exception {
66 Model model = new Model();
67
68 Properties p = new Properties();
69 p.setProperty("key", "value");
70 p.setProperty("key2", "value2");
71
72 String[] values = {"${key}", "${key2}"};
73
74 StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
75
76 ModelBuildingRequest config = createModelBuildingRequest(p);
77
78 final SimpleProblemCollector collector = new SimpleProblemCollector();
79 interpolator.interpolateObject(values, model, new File("."), config, collector);
80 assertProblemFree(collector);
81
82 assertEquals("value", values[0]);
83 assertEquals("value2", values[1]);
84 }
85
86 private ModelBuildingRequest createModelBuildingRequest(Properties p) {
87 ModelBuildingRequest config = new DefaultModelBuildingRequest();
88 config.setSystemProperties(p);
89 return config;
90 }
91
92 public void testInterpolateObjectWithStringArrayField() throws Exception {
93 Model model = new Model();
94
95 Properties p = new Properties();
96 p.setProperty("key", "value");
97 p.setProperty("key2", "value2");
98
99 String[] values = {"${key}", "${key2}"};
100
101 ObjectWithStringArrayField obj = new ObjectWithStringArrayField(values);
102
103 StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
104
105 ModelBuildingRequest config = createModelBuildingRequest(p);
106
107 final SimpleProblemCollector collector = new SimpleProblemCollector();
108 interpolator.interpolateObject(obj, model, new File("."), config, collector);
109 assertProblemFree(collector);
110
111 assertEquals("value", obj.values[0]);
112 assertEquals("value2", obj.values[1]);
113 }
114
115 public void testInterpolateObjectWithStringListField() throws Exception {
116 Model model = new Model();
117
118 Properties p = new Properties();
119 p.setProperty("key", "value");
120 p.setProperty("key2", "value2");
121
122 List<String> values = new ArrayList<>();
123 values.add("${key}");
124 values.add("${key2}");
125
126 ObjectWithListField obj = new ObjectWithListField(values);
127
128 StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
129
130 ModelBuildingRequest config = createModelBuildingRequest(p);
131
132 final SimpleProblemCollector collector = new SimpleProblemCollector();
133 interpolator.interpolateObject(obj, model, new File("."), config, collector);
134 assertProblemFree(collector);
135
136 assertEquals("value", obj.values.get(0));
137 assertEquals("value2", obj.values.get(1));
138 }
139
140 public void testInterpolateObjectWithStringListFieldAndOneLiteralValue() throws Exception {
141 Model model = new Model();
142
143 Properties p = new Properties();
144 p.setProperty("key", "value");
145 p.setProperty("key2", "value2");
146
147 List<String> values = new ArrayList<>();
148 values.add("key");
149 values.add("${key2}");
150
151 ObjectWithListField obj = new ObjectWithListField(values);
152
153 StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
154
155 ModelBuildingRequest config = createModelBuildingRequest(p);
156
157 final SimpleProblemCollector collector = new SimpleProblemCollector();
158 interpolator.interpolateObject(obj, model, new File("."), config, collector);
159 assertProblemFree(collector);
160
161 assertEquals("key", obj.values.get(0));
162 assertEquals("value2", obj.values.get(1));
163 }
164
165 public void testInterpolateObjectWithUnmodifiableStringListField() throws Exception {
166 Model model = new Model();
167
168 Properties p = new Properties();
169 p.setProperty("key", "value");
170 p.setProperty("key2", "value2");
171
172 List<String> values = Collections.unmodifiableList(Collections.singletonList("${key}"));
173
174 ObjectWithListField obj = new ObjectWithListField(values);
175
176 StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
177
178 ModelBuildingRequest config = createModelBuildingRequest(p);
179
180 final SimpleProblemCollector collector = new SimpleProblemCollector();
181 interpolator.interpolateObject(obj, model, new File("."), config, collector);
182 assertProblemFree(collector);
183
184 assertEquals("${key}", obj.values.get(0));
185 }
186
187 public void testInterpolateObjectWithStringArrayListField() throws Exception {
188 Model model = new Model();
189
190 Properties p = new Properties();
191 p.setProperty("key", "value");
192 p.setProperty("key2", "value2");
193 p.setProperty("key3", "value3");
194 p.setProperty("key4", "value4");
195
196 List<String[]> values = new ArrayList<>();
197 values.add(new String[] {"${key}", "${key2}"});
198 values.add(new String[] {"${key3}", "${key4}"});
199
200 ObjectWithListField obj = new ObjectWithListField(values);
201
202 StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
203
204 ModelBuildingRequest config = createModelBuildingRequest(p);
205
206 final SimpleProblemCollector collector = new SimpleProblemCollector();
207 interpolator.interpolateObject(obj, model, new File("."), config, collector);
208 assertProblemFree(collector);
209
210 assertEquals("value", ((String[]) obj.values.get(0))[0]);
211 assertEquals("value2", ((String[]) obj.values.get(0))[1]);
212 assertEquals("value3", ((String[]) obj.values.get(1))[0]);
213 assertEquals("value4", ((String[]) obj.values.get(1))[1]);
214 }
215
216 public void testInterpolateObjectWithStringToStringMapField() throws Exception {
217 Model model = new Model();
218
219 Properties p = new Properties();
220 p.setProperty("key", "value");
221 p.setProperty("key2", "value2");
222
223 Map<String, String> values = new HashMap<>();
224 values.put("key", "${key}");
225 values.put("key2", "${key2}");
226
227 ObjectWithMapField obj = new ObjectWithMapField(values);
228
229 StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
230
231 ModelBuildingRequest config = createModelBuildingRequest(p);
232
233 final SimpleProblemCollector collector = new SimpleProblemCollector();
234 interpolator.interpolateObject(obj, model, new File("."), config, collector);
235 assertProblemFree(collector);
236
237 assertEquals("value", obj.values.get("key"));
238 assertEquals("value2", obj.values.get("key2"));
239 }
240
241 public void testInterpolateObjectWithStringToStringMapFieldAndOneLiteralValue() throws Exception {
242 Model model = new Model();
243
244 Properties p = new Properties();
245 p.setProperty("key", "value");
246 p.setProperty("key2", "value2");
247
248 Map<String, String> values = new HashMap<>();
249 values.put("key", "val");
250 values.put("key2", "${key2}");
251
252 ObjectWithMapField obj = new ObjectWithMapField(values);
253
254 StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
255
256 ModelBuildingRequest config = createModelBuildingRequest(p);
257
258 final SimpleProblemCollector collector = new SimpleProblemCollector();
259 interpolator.interpolateObject(obj, model, new File("."), config, collector);
260 assertProblemFree(collector);
261
262 assertEquals("val", obj.values.get("key"));
263 assertEquals("value2", obj.values.get("key2"));
264 }
265
266 public void testInterpolateObjectWithUnmodifiableStringToStringMapField() throws Exception {
267 Model model = new Model();
268
269 Properties p = new Properties();
270 p.setProperty("key", "value");
271 p.setProperty("key2", "value2");
272
273 Map<String, String> values = Collections.unmodifiableMap(Collections.singletonMap("key", "${key}"));
274
275 ObjectWithMapField obj = new ObjectWithMapField(values);
276
277 StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
278
279 ModelBuildingRequest config = createModelBuildingRequest(p);
280
281 final SimpleProblemCollector collector = new SimpleProblemCollector();
282 interpolator.interpolateObject(obj, model, new File("."), config, collector);
283 assertProblemFree(collector);
284
285 assertEquals("${key}", obj.values.get("key"));
286 }
287
288 public void testInterpolateObjectWithStringToStringArrayMapField() throws Exception {
289 Model model = new Model();
290
291 Properties p = new Properties();
292 p.setProperty("key", "value");
293 p.setProperty("key2", "value2");
294 p.setProperty("key3", "value3");
295 p.setProperty("key4", "value4");
296
297 Map<String, String[]> values = new HashMap<>();
298 values.put("key", new String[] {"${key}", "${key2}"});
299 values.put("key2", new String[] {"${key3}", "${key4}"});
300
301 ObjectWithMapField obj = new ObjectWithMapField(values);
302
303 StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
304
305 ModelBuildingRequest config = createModelBuildingRequest(p);
306
307 final SimpleProblemCollector collector = new SimpleProblemCollector();
308 interpolator.interpolateObject(obj, model, new File("."), config, collector);
309 assertProblemFree(collector);
310
311 assertEquals("value", ((String[]) obj.values.get("key"))[0]);
312 assertEquals("value2", ((String[]) obj.values.get("key"))[1]);
313 assertEquals("value3", ((String[]) obj.values.get("key2"))[0]);
314 assertEquals("value4", ((String[]) obj.values.get("key2"))[1]);
315 }
316
317 public void testInterpolateObjectWithPomFile() throws Exception {
318 Model model = new Model();
319 model.setPomFile(new File(System.getProperty("user.dir"), "pom.xml"));
320 File baseDir = model.getProjectDirectory();
321
322 Properties p = new Properties();
323
324 Map<String, String> values = new HashMap<>();
325 values.put("key", "${project.basedir}" + File.separator + "target");
326
327 ObjectWithMapField obj = new ObjectWithMapField(values);
328
329 StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
330
331 ModelBuildingRequest config = createModelBuildingRequest(p);
332
333 SimpleProblemCollector collector = new SimpleProblemCollector();
334 interpolator.interpolateObject(obj, model, new File("."), config, collector);
335 assertProblemFree(collector);
336
337 assertThat(baseDir.getAbsolutePath(), is(System.getProperty("user.dir")));
338 assertThat(obj.values.size(), is(1));
339 assertThat(
340 (String) obj.values.get("key"),
341 is(anyOf(
342 is(System.getProperty("user.dir") + File.separator + "target"),
343
344 is(System.getProperty("user.dir") + File.separator + '.' + File.separator + "target"))));
345 }
346
347 public void testNotInterpolateObjectWithFile() throws Exception {
348 Model model = new Model();
349
350 File baseDir = new File(System.getProperty("user.dir"));
351
352 Properties p = new Properties();
353
354 ObjectWithNotInterpolatedFile obj = new ObjectWithNotInterpolatedFile(baseDir);
355
356 StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
357
358 ModelBuildingRequest config = createModelBuildingRequest(p);
359
360 SimpleProblemCollector collector = new SimpleProblemCollector();
361 interpolator.interpolateObject(obj, model, new File("."), config, collector);
362 assertProblemFree(collector);
363
364
365 Map<Class<?>, ?> cache = (Map<Class<?>, ?>)
366 getField(StringSearchModelInterpolator.class, "CACHED_ENTRIES").get(null);
367
368 Object objCacheItem = cache.get(Object.class);
369 Object fileCacheItem = cache.get(File.class);
370
371 assertNotNull(objCacheItem);
372 assertNotNull(fileCacheItem);
373
374 assertThat(((Object[]) getInternalState(objCacheItem, "fields")).length, is(0));
375 assertThat(((Object[]) getInternalState(fileCacheItem, "fields")).length, is(0));
376 }
377
378 public void testNotInterpolateFile() throws Exception {
379 Model model = new Model();
380
381 File baseDir = new File(System.getProperty("user.dir"));
382
383 Properties p = new Properties();
384
385 StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
386
387 ModelBuildingRequest config = createModelBuildingRequest(p);
388
389 SimpleProblemCollector collector = new SimpleProblemCollector();
390 interpolator.interpolateObject(baseDir, model, new File("."), config, collector);
391 assertProblemFree(collector);
392
393
394 Map<Class<?>, ?> cache = (Map<Class<?>, ?>)
395 getField(StringSearchModelInterpolator.class, "CACHED_ENTRIES").get(null);
396
397 Object fileCacheItem = cache.get(File.class);
398
399 assertNotNull(fileCacheItem);
400
401 assertThat(((Object[]) getInternalState(fileCacheItem, "fields")).length, is(0));
402 }
403
404 public void testConcurrentInterpolation() throws Exception {
405 final Model model = new Model();
406
407 final Properties p = new Properties();
408 p.setProperty("key", "value");
409 p.setProperty("key2", "value2");
410 p.setProperty("key3", "value3");
411 p.setProperty("key4", "value4");
412 p.setProperty("key5", "value5");
413
414 final StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
415
416 int numItems = 100;
417 final CountDownLatch countDownLatch = new CountDownLatch(1);
418
419 List<Future<SimpleProblemCollector>> futures = new ArrayList<>();
420 for (int i = 0; i < numItems; i++) {
421 Callable<SimpleProblemCollector> future = new Callable<SimpleProblemCollector>() {
422 public SimpleProblemCollector call() throws Exception {
423 final ObjectWithMixedProtection obj = getValueList();
424 final ModelBuildingRequest config = createModelBuildingRequest(p);
425
426 countDownLatch.await();
427 final SimpleProblemCollector collector = new SimpleProblemCollector();
428 interpolator.interpolateObject(obj, model, new File("."), config, collector);
429 return collector;
430 }
431 };
432 FutureTask<SimpleProblemCollector> task = new FutureTask<>(future);
433 futures.add(task);
434 new Thread(task).start();
435 }
436 countDownLatch.countDown();
437 for (Future<SimpleProblemCollector> result : futures) {
438 SimpleProblemCollector problemCollector =
439 result.get();
440 assertProblemFree(problemCollector);
441 }
442 }
443
444 private ObjectWithMixedProtection getValueList() {
445 List<String[]> values = new ArrayList<>();
446
447 values.add(new String[] {"${key}", "${key2}"});
448 values.add(new String[] {"${key3}", "${key4}"});
449 List<String> values2 = new ArrayList<>();
450 values.add(new String[] {"${key}", "${key2}"});
451 values.add(new String[] {"${key3}", "${key4}"});
452 List<String> values3 = new ArrayList<>();
453 values.add(new String[] {"${key}", "${key2}"});
454 values.add(new String[] {"${key3}", "${key4}"});
455
456 return new ObjectWithMixedProtection(values, values2, values3, "${key5}");
457 }
458
459 private static final class ObjectWithStringArrayField {
460 private final String[] values;
461
462 public ObjectWithStringArrayField(String[] values) {
463 this.values = values;
464 }
465 }
466
467 private static final class ObjectWithListField {
468 private final List<?> values;
469
470 public ObjectWithListField(List<?> values) {
471 this.values = values;
472 }
473 }
474
475 private static final class ObjectWithMapField {
476 private final Map<?, ?> values;
477
478 public ObjectWithMapField(Map<?, ?> values) {
479 this.values = values;
480 }
481 }
482
483 private static final class ObjectWithNotInterpolatedFile {
484 private final File f;
485
486 ObjectWithNotInterpolatedFile(File f) {
487 this.f = f;
488 }
489 }
490
491 @SuppressWarnings("unused")
492 private static final class ObjectWithMixedProtection {
493 private List<?> values1;
494 protected List<?> values2;
495 List<?> values3;
496 private String fooBar;
497
498 private ObjectWithMixedProtection(List<?> values1, List<?> values2, List<?> values3) {
499 this.values1 = values1;
500 this.values2 = values2;
501 this.values3 = values3;
502 }
503
504 private ObjectWithMixedProtection(List<?> values1, List<?> values2, List<?> values3, String fooBar) {
505 this.values1 = values1;
506 this.values2 = values2;
507 this.values3 = values3;
508 this.fooBar = fooBar;
509 }
510
511 public String getFooBar() {
512 return fooBar;
513 }
514 }
515
516 public void testFinalFieldsExcludedFromInterpolation() {
517 Properties props = new Properties();
518 props.setProperty("expression", "value");
519 DefaultModelBuildingRequest request = new DefaultModelBuildingRequest();
520 request.setUserProperties(props);
521
522 SimpleProblemCollector problems = new SimpleProblemCollector();
523 StringSearchModelInterpolator interpolator = new StringSearchModelInterpolator();
524 interpolator.setVersionPropertiesProcessor(new DefaultModelVersionProcessor());
525 interpolator.interpolateObject(new ClassWithFinalField(), new Model(), null, request, problems);
526
527 assertProblemFree(problems);
528 }
529
530 static class ClassWithFinalField {
531 public static final String CONSTANT = "${expression}";
532 }
533
534 public void testLocationTrackerShouldBeExcludedFromInterpolation() {
535 Properties props = new Properties();
536 props.setProperty("expression", "value");
537 DefaultModelBuildingRequest request = new DefaultModelBuildingRequest();
538 request.setUserProperties(props);
539
540 InputSource source = new InputSource();
541 source.setLocation("${expression}");
542 source.setModelId("${expression}");
543 Model model = new Model();
544 model.setLocation("", new InputLocation(1, 1, source));
545
546 SimpleProblemCollector problems = new SimpleProblemCollector();
547 StringSearchModelInterpolator interpolator = new StringSearchModelInterpolator();
548 interpolator.setVersionPropertiesProcessor(new DefaultModelVersionProcessor());
549 interpolator.interpolateObject(model, model, null, request, problems);
550
551 assertProblemFree(problems);
552 assertEquals("${expression}", source.getLocation());
553 assertEquals("${expression}", source.getModelId());
554 }
555 }