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