1   package org.apache.maven.project.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.Build;
23  import org.apache.maven.model.Model;
24  
25  import java.util.HashMap;
26  import java.util.Properties;
27  
28  import junit.framework.TestCase;
29  
30  public class ModelInterpolationEdgeCases
31      extends TestCase
32  {
33  
34      public void testMultiExpressionRecursion()
35          throws Throwable
36      {
37          Test test = new Test()
38          {
39  
40              void run()
41              {
42                  Model model = new Model();
43                  Build build = new Build();
44  
45                  model.setBuild( build );
46  
47                  build.setDirectory( "${project.build.sourceDirectory}" );
48                  build.setSourceDirectory( "${project.build.testSourceDirectory}/../main" );
49                  build.setTestSourceDirectory( "${project.build.directory}/test" );
50  
51                  try
52                  {
53                      interpolate( model );
54  
55                      System.out.println( "Should fail." );
56  
57                      failureMessage = "should fail with expression cycle in build paths.";
58  //                    fail("should fail with expression cycle in build paths.");
59                  }
60                  catch ( ModelInterpolationException e )
61                  {
62                      // expected
63                  }
64                  catch ( Throwable e )
65                  {
66                      error = e;
67  //                    throw e;
68                  }
69              }
70          };
71  
72  
73          run( test );
74      }
75  
76      public void testMultiPrefixRecursion_Synonyms()
77          throws Throwable
78      {
79          Test test = new Test()
80          {
81  
82              void run()
83              {
84                  Model model = new Model();
85                  Build build = new Build();
86  
87                  model.setBuild( build );
88  
89                  build.setDirectory( "${project.build.directory}" );
90                  build.setSourceDirectory( "${pom.build.sourceDirectory}" );
91                  build.setTestSourceDirectory( "${build.testSourceDirectory}" );
92  
93                  try
94                  {
95                      interpolate( model );
96  
97                      System.out.println( "Should fail." );
98  
99                      failureMessage = "should fail with expression synonym recursion.";
100                 }
101                 catch ( ModelInterpolationException e )
102                 {
103                     // expected
104                 }
105                 catch ( Throwable e )
106                 {
107                     error = e;
108                 }
109             }
110         };
111 
112         run( test );
113     }
114 
115     public void testMultiPrefixSeparation_EnvarPropertyDifference()
116         throws Throwable
117     {
118         Test test = new Test()
119         {
120 
121             void run()
122             {
123                 Model model = new Model();
124 
125                 Properties properties = new Properties();
126 
127                 properties.setProperty( "ENVAR", "pomValue" );
128                 properties.setProperty( "prop", "${env.ENVAR}" );
129                 properties.setProperty( "prop2", "${pom.ENVAR}" );
130 
131                 model.setProperties( properties );
132 
133                 try
134                 {
135                     Model result = interpolate( model );
136 
137                     Properties resultProps = result.getProperties();
138                     assertFalse( "Values should not match!", resultProps.getProperty( "prop" ).equals( resultProps.getProperty( "prop2" ) ) );
139                 }
140                 catch ( ModelInterpolationException e )
141                 {
142                     error = e;
143                 }
144                 catch ( Throwable e )
145                 {
146                     error = e;
147                 }
148             }
149         };
150 
151         run( test );
152     }
153 
154     private void run( Test test )
155         throws Throwable
156     {
157         Thread t = new Thread( new TestRunnable( test ) );
158         t.setDaemon( true );
159 
160         t.start();
161 
162         try
163         {
164             t.join( 5000 );
165         }
166         catch ( InterruptedException e )
167         {
168         }
169 
170         if ( t.isAlive() )
171         {
172             StackTraceElement element = new Throwable().getStackTrace()[1];
173 
174             fail( "Test: "
175                   + element.getMethodName()
176                   + " failed to execute in 5 seconds. Looks like it's caught in an infinite loop of some kind." );
177         }
178         else
179         {
180             test.checkFailure();
181         }
182     }
183 
184     private Model interpolate( Model model )
185         throws Throwable
186     {
187         RegexBasedModelInterpolator interpolator = new RegexBasedModelInterpolator();
188         interpolator.initialize();
189 
190         return interpolator.interpolate( model, new HashMap(), true );
191     }
192 
193     private static final class TestRunnable
194         implements Runnable
195     {
196         private Test test;
197 
198         TestRunnable( Test test )
199         {
200             this.test = test;
201         }
202 
203         public void run()
204         {
205             test.run();
206         }
207 
208     }
209 
210     private static abstract class Test
211     {
212         String failureMessage;
213 
214         Throwable error;
215 
216         abstract void run();
217 
218         void checkFailure()
219             throws Throwable
220         {
221             if ( error != null )
222             {
223                 throw error;
224             }
225             else if ( failureMessage != null )
226             {
227                 fail( failureMessage );
228             }
229         }
230 
231     }
232 
233 }