001package 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 022import org.apache.maven.model.InputLocation; 023import org.apache.maven.model.InputSource; 024import org.apache.maven.model.Model; 025import org.apache.maven.model.building.DefaultModelBuildingRequest; 026import org.apache.maven.model.building.ModelBuildingRequest; 027import org.apache.maven.model.building.SimpleProblemCollector; 028 029import java.io.File; 030import java.util.*; 031import java.util.concurrent.Callable; 032import java.util.concurrent.CountDownLatch; 033import java.util.concurrent.Future; 034import java.util.concurrent.FutureTask; 035 036/** 037 * @author jdcasey 038 * @author Benjamin Bentmann 039 */ 040public 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}