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 java.io.StringReader;
28  import java.util.ArrayList;
29  import java.util.HashMap;
30  import java.util.List;
31  import java.util.Map;
32  
33  import org.codehaus.plexus.interpolation.Interpolator;
34  import org.codehaus.plexus.interpolation.MapBasedValueSource;
35  import org.codehaus.plexus.interpolation.PrefixAwareRecursionInterceptor;
36  import org.codehaus.plexus.interpolation.RecursionInterceptor;
37  import org.codehaus.plexus.interpolation.StringSearchInterpolator;
38  import org.junit.jupiter.api.Test;
39  
40  import static org.junit.jupiter.api.Assertions.assertEquals;
41  
42  /**
43   * InterpolatorFilterReaderTest, heavily based on InterpolationFilterReaderTest. Heh, even the test strings remained the
44   * same!
45   *
46   * @author cstamas
47   *
48   */
49  public class MultiDelimiterInterpolatorFilterReaderTest {
50      /*
51       * Added and commented by jdcasey@03-Feb-2005 because it is a bug in the InterpolationFilterReader.
52       * kenneyw@15-04-2005 fixed the bug.
53       */
54      @Test
55      public void testShouldNotInterpolateExpressionAtEndOfDataWithInvalidEndToken() throws Exception {
56          Map m = new HashMap();
57          m.put("test", "TestValue");
58  
59          String testStr = "This is a ${test";
60  
61          assertEquals("This is a ${test", interpolate(testStr, m));
62      }
63  
64      /*
65       * kenneyw@14-04-2005 Added test to check above fix.
66       */
67      @Test
68      public void testShouldNotInterpolateExpressionWithMissingEndToken() throws Exception {
69          Map m = new HashMap();
70          m.put("test", "TestValue");
71  
72          String testStr = "This is a ${test, really";
73  
74          assertEquals("This is a ${test, really", interpolate(testStr, m));
75      }
76  
77      @Test
78      public void testShouldNotInterpolateWithMalformedStartToken() throws Exception {
79          Map m = new HashMap();
80          m.put("test", "testValue");
81  
82          String foo = "This is a $!test} again";
83  
84          assertEquals("This is a $!test} again", interpolate(foo, m));
85      }
86  
87      @Test
88      public void testShouldNotInterpolateWithMalformedEndToken() throws Exception {
89          Map m = new HashMap();
90          m.put("test", "testValue");
91  
92          String foo = "This is a ${test!} again";
93  
94          assertEquals("This is a ${test!} again", interpolate(foo, m));
95      }
96  
97      @Test
98      public void testDefaultInterpolationWithNonInterpolatedValueAtEnd() throws Exception {
99          Map m = new HashMap();
100         m.put("name", "jason");
101         m.put("noun", "asshole");
102 
103         String foo = "${name} is an ${noun}. ${not.interpolated}";
104 
105         assertEquals("jason is an asshole. ${not.interpolated}", interpolate(foo, m));
106     }
107 
108     @Test
109     public void testDefaultInterpolationWithInterpolatedValueAtEnd() throws Exception {
110         Map m = new HashMap();
111         m.put("name", "jason");
112         m.put("noun", "asshole");
113 
114         String foo = "${name} is an ${noun}";
115 
116         assertEquals("jason is an asshole", interpolate(foo, m));
117     }
118 
119     @Test
120     public void testInterpolationWithInterpolatedValueAtEndWithCustomToken() throws Exception {
121         Map m = new HashMap();
122         m.put("name", "jason");
123         m.put("noun", "asshole");
124 
125         String foo = "@{name} is an @{noun}";
126 
127         assertEquals("jason is an asshole", interpolate(foo, m, "@{", "}"));
128     }
129 
130     @Test
131     public void testInterpolationWithInterpolatedValueAtEndWithCustomTokenAndCustomString() throws Exception {
132         Map m = new HashMap();
133         m.put("name", "jason");
134         m.put("noun", "asshole");
135 
136         String foo = "@name@ is an @noun@";
137 
138         assertEquals("jason is an asshole", interpolate(foo, m, "@", "@"));
139     }
140 
141     @Test
142     public void testEscape() throws Exception {
143         Map m = new HashMap();
144         m.put("name", "jason");
145         m.put("noun", "asshole");
146 
147         String foo = "${name} is an \\${noun}";
148 
149         assertEquals("jason is an ${noun}", interpolate(foo, m, "\\"));
150     }
151 
152     @Test
153     public void testEscapeAtStart() throws Exception {
154         Map m = new HashMap();
155         m.put("name", "jason");
156         m.put("noun", "asshole");
157 
158         String foo = "\\${name} is an \\${noun}";
159 
160         assertEquals("${name} is an ${noun}", interpolate(foo, m, "\\"));
161     }
162 
163     @Test
164     public void testEscapeOnlyAtStart() throws Exception {
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         String result = interpolate(foo, m, "@", "@");
172         assertEquals("@name@ is an asshole", result);
173     }
174 
175     @Test
176     public void testEscapeOnlyAtStartDefaultToken() throws Exception {
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     @Test
188     public void testShouldDetectRecursiveExpressionPassingThroughTwoPrefixes() throws Exception {
189         List prefixes = new ArrayList();
190 
191         prefixes.add("prefix1");
192         prefixes.add("prefix2");
193 
194         RecursionInterceptor ri = new PrefixAwareRecursionInterceptor(prefixes, false);
195 
196         Map context = new HashMap();
197         context.put("name", "${prefix2.name}");
198 
199         String input = "${prefix1.name}";
200 
201         StringSearchInterpolator interpolator = new StringSearchInterpolator();
202 
203         interpolator.addValueSource(new MapBasedValueSource(context));
204 
205         MultiDelimiterInterpolatorFilterReader r =
206                 new MultiDelimiterInterpolatorFilterReader(new StringReader(input), interpolator, ri);
207         r.setInterpolateWithPrefixPattern(false);
208         r.setEscapeString("\\");
209         StringBuilder buf = new StringBuilder();
210         int read = -1;
211         char[] cbuf = new char[1024];
212         while ((read = r.read(cbuf)) > -1) {
213             buf.append(cbuf, 0, read);
214         }
215 
216         assertEquals(input, buf.toString());
217     }
218 
219     @Test
220     public void testShouldDetectRecursiveExpressionWithPrefixAndWithout() throws Exception {
221         List prefixes = new ArrayList();
222 
223         prefixes.add("prefix1");
224 
225         RecursionInterceptor ri = new PrefixAwareRecursionInterceptor(prefixes, false);
226 
227         Map context = new HashMap();
228         context.put("name", "${prefix1.name}");
229 
230         String input = "${name}";
231 
232         StringSearchInterpolator interpolator = new StringSearchInterpolator();
233 
234         interpolator.addValueSource(new MapBasedValueSource(context));
235 
236         MultiDelimiterInterpolatorFilterReader r =
237                 new MultiDelimiterInterpolatorFilterReader(new StringReader(input), interpolator, ri);
238         r.setInterpolateWithPrefixPattern(false);
239         r.setEscapeString("\\");
240         StringBuilder buf = new StringBuilder();
241         int read = -1;
242         char[] cbuf = new char[1024];
243         while ((read = r.read(cbuf)) > -1) {
244             buf.append(cbuf, 0, read);
245         }
246 
247         assertEquals("${prefix1.name}", buf.toString());
248     }
249 
250     @Test
251     public void testInterpolationWithMultipleTokenTypes() throws Exception {
252         Map m = new HashMap();
253         m.put("name", "jason");
254         m.put("otherName", "@name@");
255 
256         String foo = "${otherName}";
257 
258         assertEquals("jason", interpolateMulti(foo, m, new String[] {"${*}", "@*@"}));
259     }
260 
261     @Test
262     public void testInterpolationWithMultipleTokenTypes_ReversedOrdering() throws Exception {
263         Map m = new HashMap();
264         m.put("name", "jason");
265         m.put("otherName", "${name}");
266 
267         String foo = "@otherName@";
268 
269         assertEquals("jason", interpolateMulti(foo, m, new String[] {"${*}", "@*@"}));
270     }
271 
272     // ----------------------------------------------------------------------
273     //
274     // ----------------------------------------------------------------------
275 
276     private String interpolate(String input, Map context) throws Exception {
277         return interpolate(input, context, null);
278     }
279 
280     private String interpolate(String input, Map context, String escapeStr) throws Exception {
281         Interpolator interpolator = new StringSearchInterpolator();
282 
283         interpolator.addValueSource(new MapBasedValueSource(context));
284 
285         MultiDelimiterInterpolatorFilterReader r =
286                 new MultiDelimiterInterpolatorFilterReader(new StringReader(input), interpolator);
287         r.setInterpolateWithPrefixPattern(false);
288         if (escapeStr != null) {
289             r.setEscapeString(escapeStr);
290         }
291         StringBuilder buf = new StringBuilder();
292         int read = -1;
293         char[] cbuf = new char[1024];
294         while ((read = r.read(cbuf)) > -1) {
295             buf.append(cbuf, 0, read);
296         }
297 
298         return buf.toString();
299     }
300 
301     private String interpolate(String input, Map context, String beginToken, String endToken) throws Exception {
302         StringSearchInterpolator interpolator = new StringSearchInterpolator(beginToken, endToken);
303 
304         interpolator.addValueSource(new MapBasedValueSource(context));
305 
306         MultiDelimiterInterpolatorFilterReader r =
307                 new MultiDelimiterInterpolatorFilterReader(new StringReader(input), interpolator);
308         r.addDelimiterSpec(beginToken + "*" + endToken);
309 
310         r.setInterpolateWithPrefixPattern(false);
311         r.setEscapeString("\\");
312         StringBuilder buf = new StringBuilder();
313         int read = -1;
314         char[] cbuf = new char[1024];
315         while ((read = r.read(cbuf)) > -1) {
316             buf.append(cbuf, 0, read);
317         }
318 
319         return buf.toString();
320     }
321 
322     private String interpolateMulti(String input, Map context, String[] specs) throws Exception {
323         MultiDelimiterStringSearchInterpolator interp = new MultiDelimiterStringSearchInterpolator();
324         interp.addValueSource(new MapBasedValueSource(context));
325 
326         MultiDelimiterInterpolatorFilterReader r =
327                 new MultiDelimiterInterpolatorFilterReader(new StringReader(input), interp);
328 
329         for (String spec : specs) {
330             interp.addDelimiterSpec(spec);
331             r.addDelimiterSpec(spec);
332         }
333 
334         r.setInterpolateWithPrefixPattern(false);
335         r.setEscapeString("\\");
336         StringBuilder buf = new StringBuilder();
337         int read = -1;
338         char[] cbuf = new char[1024];
339         while ((read = r.read(cbuf)) > -1) {
340             buf.append(cbuf, 0, read);
341         }
342 
343         return buf.toString();
344     }
345 }