View Javadoc
1   package org.apache.maven.model.interpolation;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.model.InputLocation;
23  import org.apache.maven.model.InputSource;
24  import org.apache.maven.model.Model;
25  import org.apache.maven.model.building.DefaultModelBuildingRequest;
26  import org.apache.maven.model.building.ModelBuildingRequest;
27  import org.apache.maven.model.building.SimpleProblemCollector;
28  
29  import java.io.File;
30  import java.util.*;
31  import java.util.concurrent.Callable;
32  import java.util.concurrent.CountDownLatch;
33  import java.util.concurrent.Future;
34  import java.util.concurrent.FutureTask;
35  
36  /**
37   * @author jdcasey
38   * @author Benjamin Bentmann
39   */
40  public class StringSearchModelInterpolatorTest
41      extends AbstractModelInterpolatorTest
42  {
43  
44      protected ModelInterpolator interpolator;
45  
46      @Override
47      protected void setUp()
48          throws Exception
49      {
50          super.setUp();
51          interpolator = lookup( ModelInterpolator.class );
52      }
53  
54  
55      protected ModelInterpolator createInterpolator( org.apache.maven.model.path.PathTranslator translator )
56          throws Exception
57      {
58          return this.interpolator;
59      }
60  
61      protected ModelInterpolator createInterpolator()
62          throws Exception
63      {
64          return this.interpolator;
65      }
66  
67      public void testInterpolateStringArray()
68          throws Exception
69      {
70          Model model = new Model();
71  
72          Properties p = new Properties();
73          p.setProperty( "key", "value" );
74          p.setProperty( "key2", "value2" );
75  
76          String[] values = { "${key}", "${key2}" };
77  
78          StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
79  
80          ModelBuildingRequest config = createModelBuildingRequest(p);
81  
82          final SimpleProblemCollector collector = new SimpleProblemCollector();
83          interpolator.interpolateObject( values, model, new File( "." ), config, collector );
84          assertProblemFree( collector );
85  
86          assertEquals( "value", values[0] );
87          assertEquals( "value2", values[1] );
88      }
89  
90      private ModelBuildingRequest createModelBuildingRequest( Properties p )
91      {
92          ModelBuildingRequest config = new DefaultModelBuildingRequest();
93          config.setSystemProperties( p );
94          return config;
95      }
96  
97      public void testInterpolateObjectWithStringArrayField()
98          throws Exception
99      {
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 }