001 package org.apache.maven.model.interpolation;
002
003 /*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements. See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership. The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License. You may obtain a copy of the License at
011 *
012 * http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied. See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022 import org.apache.maven.model.InputLocation;
023 import org.apache.maven.model.InputSource;
024 import org.apache.maven.model.Model;
025 import org.apache.maven.model.building.DefaultModelBuildingRequest;
026 import org.apache.maven.model.building.ModelBuildingRequest;
027 import org.apache.maven.model.building.SimpleProblemCollector;
028
029 import java.io.File;
030 import java.util.*;
031 import java.util.concurrent.Callable;
032 import java.util.concurrent.CountDownLatch;
033 import java.util.concurrent.Future;
034 import java.util.concurrent.FutureTask;
035
036 /**
037 * @author jdcasey
038 * @author Benjamin Bentmann
039 */
040 public class StringSearchModelInterpolatorTest
041 extends AbstractModelInterpolatorTest
042 {
043
044 protected ModelInterpolator interpolator;
045
046 @Override
047 protected void setUp()
048 throws Exception
049 {
050 super.setUp();
051 interpolator = lookup( ModelInterpolator.class );
052 }
053
054
055 protected ModelInterpolator createInterpolator( org.apache.maven.model.path.PathTranslator translator )
056 throws Exception
057 {
058 return this.interpolator;
059 }
060
061 protected ModelInterpolator createInterpolator()
062 throws Exception
063 {
064 return this.interpolator;
065 }
066
067 public void testInterpolateStringArray()
068 throws Exception
069 {
070 Model model = new Model();
071
072 Properties p = new Properties();
073 p.setProperty( "key", "value" );
074 p.setProperty( "key2", "value2" );
075
076 String[] values = { "${key}", "${key2}" };
077
078 StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
079
080 ModelBuildingRequest config = createModelBuildingRequest(p);
081
082 final SimpleProblemCollector collector = new SimpleProblemCollector();
083 interpolator.interpolateObject( values, model, new File( "." ), config, collector );
084 assertProblemFree( collector );
085
086 assertEquals( "value", values[0] );
087 assertEquals( "value2", values[1] );
088 }
089
090 private ModelBuildingRequest createModelBuildingRequest( Properties p )
091 {
092 ModelBuildingRequest config = new DefaultModelBuildingRequest();
093 config.setSystemProperties( p );
094 return config;
095 }
096
097 public void testInterpolateObjectWithStringArrayField()
098 throws Exception
099 {
100 Model model = new Model();
101
102 Properties p = new Properties();
103 p.setProperty( "key", "value" );
104 p.setProperty( "key2", "value2" );
105
106 String[] values = { "${key}", "${key2}" };
107
108 ObjectWithStringArrayField obj = new ObjectWithStringArrayField( values );
109
110 StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
111
112 ModelBuildingRequest config = createModelBuildingRequest( p );
113
114 final SimpleProblemCollector collector = new SimpleProblemCollector();
115 interpolator.interpolateObject( obj, model, new File( "." ), config, collector );
116 assertProblemFree( collector );
117
118 assertEquals( "value", obj.values[0] );
119 assertEquals( "value2", obj.values[1] );
120 }
121
122 public void testInterpolateObjectWithStringListField()
123 throws Exception
124 {
125 Model model = new Model();
126
127 Properties p = new Properties();
128 p.setProperty( "key", "value" );
129 p.setProperty( "key2", "value2" );
130
131 List<String> values = new ArrayList<String>();
132 values.add( "${key}" );
133 values.add( "${key2}" );
134
135 ObjectWithListField obj = new ObjectWithListField( values );
136
137 StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
138
139 ModelBuildingRequest config = createModelBuildingRequest( p );
140
141 final SimpleProblemCollector collector = new SimpleProblemCollector();
142 interpolator.interpolateObject( obj, model, new File( "." ), config, collector );
143 assertProblemFree( collector );
144
145 assertEquals( "value", obj.values.get( 0 ) );
146 assertEquals( "value2", obj.values.get( 1 ) );
147 }
148
149 public void testInterpolateObjectWithStringListFieldAndOneLiteralValue()
150 throws Exception
151 {
152 Model model = new Model();
153
154 Properties p = new Properties();
155 p.setProperty( "key", "value" );
156 p.setProperty( "key2", "value2" );
157
158 List<String> values = new ArrayList<String>();
159 values.add( "key" );
160 values.add( "${key2}" );
161
162 ObjectWithListField obj = new ObjectWithListField( values );
163
164 StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
165
166 ModelBuildingRequest config = createModelBuildingRequest( p );
167
168 final SimpleProblemCollector collector = new SimpleProblemCollector();
169 interpolator.interpolateObject( obj, model, new File( "." ), config, collector );
170 assertProblemFree( collector );
171
172 assertEquals( "key", obj.values.get( 0 ) );
173 assertEquals( "value2", obj.values.get( 1 ) );
174 }
175
176 public void testInterpolateObjectWithUnmodifiableStringListField()
177 throws Exception
178 {
179 Model model = new Model();
180
181 Properties p = new Properties();
182 p.setProperty( "key", "value" );
183 p.setProperty( "key2", "value2" );
184
185 List<String> values = Collections.unmodifiableList( Collections.singletonList( "${key}" ) );
186
187 ObjectWithListField obj = new ObjectWithListField( values );
188
189 StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
190
191 ModelBuildingRequest config = createModelBuildingRequest( p );
192
193 final SimpleProblemCollector collector = new SimpleProblemCollector();
194 interpolator.interpolateObject( obj, model, new File( "." ), config, collector );
195 assertProblemFree( collector );
196
197 assertEquals( "${key}", obj.values.get( 0 ) );
198 }
199
200 public void testInterpolateObjectWithStringArrayListField()
201 throws Exception
202 {
203 Model model = new Model();
204
205 Properties p = new Properties();
206 p.setProperty( "key", "value" );
207 p.setProperty( "key2", "value2" );
208 p.setProperty( "key3", "value3" );
209 p.setProperty( "key4", "value4" );
210
211 List<String[]> values = new ArrayList<String[]>();
212 values.add( new String[] { "${key}", "${key2}" } );
213 values.add( new String[] { "${key3}", "${key4}" } );
214
215 ObjectWithListField obj = new ObjectWithListField( values );
216
217 StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
218
219 ModelBuildingRequest config = createModelBuildingRequest( p );
220
221 final SimpleProblemCollector collector = new SimpleProblemCollector();
222 interpolator.interpolateObject( obj, model, new File( "." ), config, collector );
223 assertProblemFree( collector );
224
225 assertEquals( "value", ( (String[]) obj.values.get( 0 ) )[0] );
226 assertEquals( "value2", ( (String[]) obj.values.get( 0 ) )[1] );
227 assertEquals( "value3", ( (String[]) obj.values.get( 1 ) )[0] );
228 assertEquals( "value4", ( (String[]) obj.values.get( 1 ) )[1] );
229 }
230
231 public void testInterpolateObjectWithStringToStringMapField()
232 throws Exception
233 {
234 Model model = new Model();
235
236 Properties p = new Properties();
237 p.setProperty( "key", "value" );
238 p.setProperty( "key2", "value2" );
239
240 Map<String, String> values = new HashMap<String, String>();
241 values.put( "key", "${key}" );
242 values.put( "key2", "${key2}" );
243
244 ObjectWithMapField obj = new ObjectWithMapField( values );
245
246 StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
247
248 ModelBuildingRequest config = createModelBuildingRequest( p );
249
250 final SimpleProblemCollector collector = new SimpleProblemCollector();
251 interpolator.interpolateObject( obj, model, new File( "." ), config, collector );
252 assertProblemFree( collector );
253
254 assertEquals( "value", obj.values.get( "key" ) );
255 assertEquals( "value2", obj.values.get( "key2" ) );
256 }
257
258 public void testInterpolateObjectWithStringToStringMapFieldAndOneLiteralValue()
259 throws Exception
260 {
261 Model model = new Model();
262
263 Properties p = new Properties();
264 p.setProperty( "key", "value" );
265 p.setProperty( "key2", "value2" );
266
267 Map<String, String> values = new HashMap<String, String>();
268 values.put( "key", "val" );
269 values.put( "key2", "${key2}" );
270
271 ObjectWithMapField obj = new ObjectWithMapField( values );
272
273 StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
274
275 ModelBuildingRequest config = createModelBuildingRequest( p );
276
277 final SimpleProblemCollector collector = new SimpleProblemCollector();
278 interpolator.interpolateObject( obj, model, new File( "." ), config, collector );
279 assertProblemFree( collector );
280
281 assertEquals( "val", obj.values.get( "key" ) );
282 assertEquals( "value2", obj.values.get( "key2" ) );
283 }
284
285 public void testInterpolateObjectWithUnmodifiableStringToStringMapField()
286 throws Exception
287 {
288 Model model = new Model();
289
290 Properties p = new Properties();
291 p.setProperty( "key", "value" );
292 p.setProperty( "key2", "value2" );
293
294 Map<String, String> values = Collections.unmodifiableMap( Collections.singletonMap( "key", "${key}" ) );
295
296 ObjectWithMapField obj = new ObjectWithMapField( values );
297
298 StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
299
300 ModelBuildingRequest config = createModelBuildingRequest( p );
301
302 final SimpleProblemCollector collector = new SimpleProblemCollector();
303 interpolator.interpolateObject( obj, model, new File( "." ), config, collector );
304 assertProblemFree( collector );
305
306 assertEquals( "${key}", obj.values.get( "key" ) );
307 }
308
309 public void testInterpolateObjectWithStringToStringArrayMapField()
310 throws Exception
311 {
312 Model model = new Model();
313
314 Properties p = new Properties();
315 p.setProperty( "key", "value" );
316 p.setProperty( "key2", "value2" );
317 p.setProperty( "key3", "value3" );
318 p.setProperty( "key4", "value4" );
319
320 Map<String, String[]> values = new HashMap<String, String[]>();
321 values.put( "key", new String[] { "${key}", "${key2}" } );
322 values.put( "key2", new String[] { "${key3}", "${key4}" } );
323
324 ObjectWithMapField obj = new ObjectWithMapField( values );
325
326 StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
327
328 ModelBuildingRequest config = createModelBuildingRequest( p );
329
330 final SimpleProblemCollector collector = new SimpleProblemCollector();
331 interpolator.interpolateObject( obj, model, new File( "." ), config, collector );
332 assertProblemFree( collector );
333
334 assertEquals( "value", ( (String[]) obj.values.get( "key" ) )[0] );
335 assertEquals( "value2", ( (String[]) obj.values.get( "key" ) )[1] );
336 assertEquals( "value3", ( (String[]) obj.values.get( "key2" ) )[0] );
337 assertEquals( "value4", ( (String[]) obj.values.get( "key2" ) )[1] );
338 }
339
340
341 public void testConcurrentInterpolation()
342 throws Exception
343 {
344 final Model model = new Model();
345
346 final Properties p = new Properties();
347 p.setProperty( "key", "value" );
348 p.setProperty( "key2", "value2" );
349 p.setProperty( "key3", "value3" );
350 p.setProperty( "key4", "value4" );
351 p.setProperty( "key5", "value5" );
352
353 final StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
354
355
356 int numItems = 100;
357 final CountDownLatch countDownLatch = new CountDownLatch(1);
358
359 List<Future<SimpleProblemCollector>> futures = new ArrayList<Future<SimpleProblemCollector>>();
360 for ( int i = 0; i < numItems; i++ )
361 {
362 Callable<SimpleProblemCollector> future = new Callable<SimpleProblemCollector>()
363 {
364 public SimpleProblemCollector call()
365 throws Exception
366 {
367 final ObjectWithMixedProtection obj = getValueList();
368 final ModelBuildingRequest config = createModelBuildingRequest( p );
369
370 countDownLatch.await();
371 final SimpleProblemCollector collector = new SimpleProblemCollector();
372 interpolator.interpolateObject( obj, model, new File( "." ), config, collector );
373 return collector;
374 }
375 };
376 FutureTask<SimpleProblemCollector> task = new FutureTask<SimpleProblemCollector>( future );
377 futures.add( task );
378 new Thread( task ).start();
379 }
380 countDownLatch.countDown(); // Start all the threads
381 for ( Future<SimpleProblemCollector> result : futures )
382 {
383 SimpleProblemCollector problemCollector = result.get(); // ArrayIndexOutOfBoundsException are typical indication of threading issues
384 assertProblemFree( problemCollector );
385 }
386 }
387
388 private ObjectWithMixedProtection getValueList()
389 {
390 List<String[]> values = new ArrayList<String[]>();
391
392 values.add( new String[] { "${key}", "${key2}" } );
393 values.add( new String[] { "${key3}", "${key4}" } );
394 List<String> values2 = new ArrayList<String>();
395 values.add( new String[] { "${key}", "${key2}" } );
396 values.add( new String[] { "${key3}", "${key4}" } );
397 List<String> values3 = new ArrayList<String>();
398 values.add( new String[] { "${key}", "${key2}" } );
399 values.add( new String[] { "${key3}", "${key4}" } );
400
401 return new ObjectWithMixedProtection( values, values2, values3, "${key5}" );
402 }
403
404
405 private static final class ObjectWithStringArrayField
406 {
407 private final String[] values;
408
409 public ObjectWithStringArrayField( String[] values )
410 {
411 this.values = values;
412 }
413 }
414
415 private static final class ObjectWithListField
416 {
417 private final List<?> values;
418
419 public ObjectWithListField( List<?> values )
420 {
421 this.values = values;
422 }
423 }
424
425 private static final class ObjectWithMapField
426 {
427 private final Map<?, ?> values;
428
429 public ObjectWithMapField( Map<?, ?> values )
430 {
431 this.values = values;
432 }
433 }
434
435 @SuppressWarnings( "unused" )
436 private static final class ObjectWithMixedProtection
437 {
438 private List<?> values1;
439 protected List<?> values2;
440 List<?> values3;
441 private String fooBar;
442
443 private ObjectWithMixedProtection( List<?> values1, List<?> values2, List<?> values3 )
444 {
445 this.values1 = values1;
446 this.values2 = values2;
447 this.values3 = values3;
448 }
449
450 private ObjectWithMixedProtection( List<?> values1, List<?> values2, List<?> values3, String fooBar )
451 {
452 this.values1 = values1;
453 this.values2 = values2;
454 this.values3 = values3;
455 this.fooBar = fooBar;
456 }
457
458 public String getFooBar()
459 {
460 return fooBar;
461 }
462 }
463
464 public void testFinalFieldsExcludedFromInterpolation()
465 {
466 Properties props = new Properties();
467 props.setProperty( "expression", "value" );
468 DefaultModelBuildingRequest request = new DefaultModelBuildingRequest();
469 request.setUserProperties( props );
470
471 SimpleProblemCollector problems = new SimpleProblemCollector();
472 StringSearchModelInterpolator interpolator = new StringSearchModelInterpolator();
473 interpolator.interpolateObject( new ClassWithFinalField(), new Model(), null, request, problems );
474
475 assertProblemFree( problems );
476 }
477
478 static class ClassWithFinalField
479 {
480 public static final String CONSTANT = "${expression}";
481 }
482
483 public void testLocationTrackerShouldBeExcludedFromInterpolation()
484 {
485 Properties props = new Properties();
486 props.setProperty( "expression", "value" );
487 DefaultModelBuildingRequest request = new DefaultModelBuildingRequest();
488 request.setUserProperties( props );
489
490 InputSource source = new InputSource();
491 source.setLocation( "${expression}" );
492 source.setModelId( "${expression}" );
493 Model model = new Model();
494 model.setLocation( "", new InputLocation( 1, 1, source ) );
495
496 SimpleProblemCollector problems = new SimpleProblemCollector();
497 StringSearchModelInterpolator interpolator = new StringSearchModelInterpolator();
498 interpolator.interpolateObject( model, model, null, request, problems );
499
500 assertProblemFree( problems );
501 assertEquals( "${expression}", source.getLocation() );
502 assertEquals( "${expression}", source.getModelId() );
503 }
504
505 }