View Javadoc
1   package org.codehaus.plexus.interpolation.multi;
2   
3   /*
4    * The MIT License
5    *
6    * Copyright (c) 2004, The Codehaus
7    *
8    * Permission is hereby granted, free of charge, to any person obtaining a copy of
9    * this software and associated documentation files (the "Software"), to deal in
10   * the Software without restriction, including without limitation the rights to
11   * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12   * of the Software, and to permit persons to whom the Software is furnished to do
13   * so, subject to the following conditions:
14   *
15   * The above copyright notice and this permission notice shall be included in all
16   * copies or substantial portions of the Software.
17   *
18   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24   * SOFTWARE.
25   */
26  
27  import org.codehaus.plexus.interpolation.Interpolator;
28  import org.codehaus.plexus.interpolation.MapBasedValueSource;
29  import org.codehaus.plexus.interpolation.PrefixAwareRecursionInterceptor;
30  import org.codehaus.plexus.interpolation.RecursionInterceptor;
31  import org.codehaus.plexus.interpolation.StringSearchInterpolator;
32  
33  import java.io.StringReader;
34  import java.util.ArrayList;
35  import java.util.HashMap;
36  import java.util.List;
37  import java.util.Map;
38  
39  import junit.framework.TestCase;
40  
41  /**
42   * InterpolatorFilterReaderTest, heavily based on InterpolationFilterReaderTest. Heh, even the test strings remained the
43   * same!
44   * 
45   * @author cstamas
46   * 
47   */
48  public class MultiDelimiterInterpolatorFilterReaderTest
49      extends TestCase
50  {
51      /*
52       * Added and commented by jdcasey@03-Feb-2005 because it is a bug in the InterpolationFilterReader.
53       * kenneyw@15-04-2005 fixed the bug.
54       */
55      public void testShouldNotInterpolateExpressionAtEndOfDataWithInvalidEndToken()
56          throws Exception
57      {
58          Map m = new HashMap();
59          m.put( "test", "TestValue" );
60  
61          String testStr = "This is a ${test";
62  
63          assertEquals( "This is a ${test", interpolate( testStr, m ) );
64      }
65  
66      /*
67       * kenneyw@14-04-2005 Added test to check above fix.
68       */
69      public void testShouldNotInterpolateExpressionWithMissingEndToken()
70          throws Exception
71      {
72          Map m = new HashMap();
73          m.put( "test", "TestValue" );
74  
75          String testStr = "This is a ${test, really";
76  
77          assertEquals( "This is a ${test, really", interpolate( testStr, m ) );
78      }
79  
80      public void testShouldNotInterpolateWithMalformedStartToken()
81          throws Exception
82      {
83          Map m = new HashMap();
84          m.put( "test", "testValue" );
85  
86          String foo = "This is a $!test} again";
87  
88          assertEquals( "This is a $!test} again", interpolate( foo, m ) );
89      }
90  
91      public void testShouldNotInterpolateWithMalformedEndToken()
92          throws Exception
93      {
94          Map m = new HashMap();
95          m.put( "test", "testValue" );
96  
97          String foo = "This is a ${test!} again";
98  
99          assertEquals( "This is a ${test!} again", interpolate( foo, m ) );
100     }
101 
102     public void testDefaultInterpolationWithNonInterpolatedValueAtEnd()
103         throws Exception
104     {
105         Map m = new HashMap();
106         m.put( "name", "jason" );
107         m.put( "noun", "asshole" );
108 
109         String foo = "${name} is an ${noun}. ${not.interpolated}";
110 
111         assertEquals( "jason is an asshole. ${not.interpolated}", interpolate( foo, m ) );
112     }
113 
114     public void testDefaultInterpolationWithInterpolatedValueAtEnd()
115         throws Exception
116     {
117         Map m = new HashMap();
118         m.put( "name", "jason" );
119         m.put( "noun", "asshole" );
120 
121         String foo = "${name} is an ${noun}";
122 
123         assertEquals( "jason is an asshole", interpolate( foo, m ) );
124     }
125 
126     public void testInterpolationWithInterpolatedValueAtEndWithCustomToken()
127         throws Exception
128     {
129         Map m = new HashMap();
130         m.put( "name", "jason" );
131         m.put( "noun", "asshole" );
132 
133         String foo = "@{name} is an @{noun}";
134 
135         assertEquals( "jason is an asshole", interpolate( foo, m, "@{", "}" ) );
136     }
137 
138     public void testInterpolationWithInterpolatedValueAtEndWithCustomTokenAndCustomString()
139         throws Exception
140     {
141         Map m = new HashMap();
142         m.put( "name", "jason" );
143         m.put( "noun", "asshole" );
144 
145         String foo = "@name@ is an @noun@";
146 
147         assertEquals( "jason is an asshole", interpolate( foo, m, "@", "@" ) );
148     }
149 
150     public void testEscape()
151         throws Exception
152     {
153         Map m = new HashMap();
154         m.put( "name", "jason" );
155         m.put( "noun", "asshole" );
156 
157         String foo = "${name} is an \\${noun}";
158 
159         assertEquals( "jason is an ${noun}", interpolate( foo, m, "\\" ) );
160     }
161 
162     public void testEscapeAtStart()
163         throws Exception
164     {
165         Map m = new HashMap();
166         m.put( "name", "jason" );
167         m.put( "noun", "asshole" );
168 
169         String foo = "\\${name} is an \\${noun}";
170 
171         assertEquals( "${name} is an ${noun}", interpolate( foo, m, "\\" ) );
172     }
173 
174     public void testEscapeOnlyAtStart()
175         throws Exception
176     {
177         Map m = new HashMap();
178         m.put( "name", "jason" );
179         m.put( "noun", "asshole" );
180 
181         String foo = "\\@name@ is an @noun@";
182 
183         String result = interpolate( foo, m, "@", "@" );
184         assertEquals( "@name@ is an asshole", result );
185     }
186 
187     public void testEscapeOnlyAtStartDefaultToken()
188         throws Exception
189     {
190         Map m = new HashMap();
191         m.put( "name", "jason" );
192         m.put( "noun", "asshole" );
193 
194         String foo = "\\${name} is an ${noun}";
195 
196         String result = interpolate( foo, m, "${", "}" );
197         assertEquals( "${name} is an asshole", result );
198     }
199 
200     public void testShouldDetectRecursiveExpressionPassingThroughTwoPrefixes()
201         throws Exception
202     {
203         List prefixes = new ArrayList();
204 
205         prefixes.add( "prefix1" );
206         prefixes.add( "prefix2" );
207 
208         RecursionInterceptor ri = new PrefixAwareRecursionInterceptor( prefixes, false );
209 
210         Map context = new HashMap();
211         context.put( "name", "${prefix2.name}" );
212 
213         String input = "${prefix1.name}";
214 
215         StringSearchInterpolator interpolator = new StringSearchInterpolator();
216 
217         interpolator.addValueSource( new MapBasedValueSource( context ) );
218 
219         MultiDelimiterInterpolatorFilterReader r = new MultiDelimiterInterpolatorFilterReader( new StringReader( input ),
220                                                                                                interpolator, ri );
221         r.setInterpolateWithPrefixPattern( false );
222         r.setEscapeString( "\\" );
223         StringBuilder buf = new StringBuilder();
224         int read = -1;
225         char[] cbuf = new char[1024];
226         while ( ( read = r.read( cbuf ) ) > -1 )
227         {
228             buf.append( cbuf, 0, read );
229         }
230 
231         assertEquals( input, buf.toString() );
232     }
233 
234     public void testShouldDetectRecursiveExpressionWithPrefixAndWithout()
235         throws Exception
236     {
237         List prefixes = new ArrayList();
238 
239         prefixes.add( "prefix1" );
240 
241         RecursionInterceptor ri = new PrefixAwareRecursionInterceptor( prefixes, false );
242 
243         Map context = new HashMap();
244         context.put( "name", "${prefix1.name}" );
245 
246         String input = "${name}";
247 
248         StringSearchInterpolator interpolator = new StringSearchInterpolator();
249 
250         interpolator.addValueSource( new MapBasedValueSource( context ) );
251 
252         MultiDelimiterInterpolatorFilterReader r = new MultiDelimiterInterpolatorFilterReader( new StringReader( input ),
253                                                                                                interpolator, ri );
254         r.setInterpolateWithPrefixPattern( false );
255         r.setEscapeString( "\\" );
256         StringBuilder buf = new StringBuilder();
257         int read = -1;
258         char[] cbuf = new char[1024];
259         while ( ( read = r.read( cbuf ) ) > -1 )
260         {
261             buf.append( cbuf, 0, read );
262         }
263 
264         assertEquals( "${prefix1.name}", buf.toString() );
265     }
266 
267     public void testInterpolationWithMultipleTokenTypes()
268         throws Exception
269     {
270         Map m = new HashMap();
271         m.put( "name", "jason" );
272         m.put( "otherName", "@name@" );
273 
274         String foo = "${otherName}";
275 
276         assertEquals( "jason", interpolateMulti( foo, m, new String[] { "${*}", "@*@" } ) );
277     }
278 
279     public void testInterpolationWithMultipleTokenTypes_ReversedOrdering()
280         throws Exception
281     {
282         Map m = new HashMap();
283         m.put( "name", "jason" );
284         m.put( "otherName", "${name}" );
285 
286         String foo = "@otherName@";
287 
288         assertEquals( "jason", interpolateMulti( foo, m, new String[] { "${*}", "@*@" } ) );
289     }
290 
291     // ----------------------------------------------------------------------
292     //
293     // ----------------------------------------------------------------------
294 
295     private String interpolate( String input, Map context )
296         throws Exception
297     {
298         return interpolate( input, context, null );
299     }
300 
301     private String interpolate( String input, Map context, String escapeStr )
302         throws Exception
303     {
304         Interpolator interpolator = new StringSearchInterpolator();
305 
306         interpolator.addValueSource( new MapBasedValueSource( context ) );
307 
308         MultiDelimiterInterpolatorFilterReader r = new MultiDelimiterInterpolatorFilterReader( new StringReader( input ), interpolator );
309         r.setInterpolateWithPrefixPattern( false );
310         if ( escapeStr != null )
311         {
312             r.setEscapeString( escapeStr );
313         }
314         StringBuilder buf = new StringBuilder();
315         int read = -1;
316         char[] cbuf = new char[1024];
317         while ( ( read = r.read( cbuf ) ) > -1 )
318         {
319             buf.append( cbuf, 0, read );
320         }
321 
322         return buf.toString();
323     }
324 
325     private String interpolate( String input, Map context, String beginToken, String endToken )
326         throws Exception
327     {
328         StringSearchInterpolator interpolator = new StringSearchInterpolator( beginToken, endToken );
329 
330         interpolator.addValueSource( new MapBasedValueSource( context ) );
331 
332         MultiDelimiterInterpolatorFilterReader r = new MultiDelimiterInterpolatorFilterReader( new StringReader( input ), interpolator );
333         r.addDelimiterSpec( beginToken + "*" + endToken );
334 
335         r.setInterpolateWithPrefixPattern( false );
336         r.setEscapeString( "\\" );
337         StringBuilder buf = new StringBuilder();
338         int read = -1;
339         char[] cbuf = new char[1024];
340         while ( ( read = r.read( cbuf ) ) > -1 )
341         {
342             buf.append( cbuf, 0, read );
343         }
344 
345         return buf.toString();
346     }
347 
348     private String interpolateMulti( String input, Map context, String[] specs )
349         throws Exception
350     {
351         MultiDelimiterStringSearchInterpolator interp = new MultiDelimiterStringSearchInterpolator();
352         interp.addValueSource( new MapBasedValueSource( context ) );
353 
354         MultiDelimiterInterpolatorFilterReader r = new MultiDelimiterInterpolatorFilterReader( new StringReader( input ), interp );
355 
356         for ( String spec : specs )
357         {
358             interp.addDelimiterSpec( spec );
359             r.addDelimiterSpec( spec );
360         }
361 
362         r.setInterpolateWithPrefixPattern( false );
363         r.setEscapeString( "\\" );
364         StringBuilder buf = new StringBuilder();
365         int read = -1;
366         char[] cbuf = new char[1024];
367         while ( ( read = r.read( cbuf ) ) > -1 )
368         {
369             buf.append( cbuf, 0, read );
370         }
371 
372         return buf.toString();
373     }
374 
375 }