View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.model.interpolation.reflection;
20  
21  /*
22   * Copyright The Codehaus Foundation.
23   *
24   * Licensed under the Apache License, Version 2.0 (the "License");
25   * you may not use this file except in compliance with the License.
26   * You may obtain a copy of the License at
27   *
28   *     http://www.apache.org/licenses/LICENSE-2.0
29   *
30   * Unless required by applicable law or agreed to in writing, software
31   * distributed under the License is distributed on an "AS IS" BASIS,
32   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
33   * See the License for the specific language governing permissions and
34   * limitations under the License.
35   */
36  
37  import java.util.ArrayList;
38  import java.util.HashMap;
39  import java.util.List;
40  import java.util.Map;
41  
42  import org.junit.jupiter.api.BeforeEach;
43  import org.junit.jupiter.api.Test;
44  
45  import static org.junit.jupiter.api.Assertions.assertEquals;
46  import static org.junit.jupiter.api.Assertions.assertNotNull;
47  import static org.junit.jupiter.api.Assertions.assertNull;
48  
49  /**
50   * ReflectionValueExtractorTest class.
51   */
52  public class ReflectionValueExtractorTest {
53      private Project project;
54  
55      /**
56       * <p>setUp.</p>
57       */
58      @BeforeEach
59      void setUp() {
60          Dependency dependency1 = new Dependency();
61          dependency1.setArtifactId("dep1");
62          Dependency dependency2 = new Dependency();
63          dependency2.setArtifactId("dep2");
64  
65          project = new Project();
66          project.setModelVersion("4.0.0");
67          project.setGroupId("org.apache.maven");
68          project.setArtifactId("maven-core");
69          project.setName("Maven");
70          project.setVersion("2.0-SNAPSHOT");
71          project.setScm(new Scm());
72          project.getScm().setConnection("scm-connection");
73          project.addDependency(dependency1);
74          project.addDependency(dependency2);
75          project.setBuild(new Build());
76  
77          // Build up an artifactMap
78          project.addArtifact(new Artifact("g0", "a0", "v0", "e0", "c0"));
79          project.addArtifact(new Artifact("g1", "a1", "v1", "e1", "c1"));
80          project.addArtifact(new Artifact("g2", "a2", "v2", "e2", "c2"));
81      }
82  
83      /**
84       * <p>testValueExtraction.</p>
85       *
86       * @throws Exception if any.
87       */
88      @Test
89      void testValueExtraction() throws Exception {
90          // ----------------------------------------------------------------------
91          // Top level values
92          // ----------------------------------------------------------------------
93  
94          assertEquals("4.0.0", ReflectionValueExtractor.evaluate("project.modelVersion", project));
95  
96          assertEquals("org.apache.maven", ReflectionValueExtractor.evaluate("project.groupId", project));
97  
98          assertEquals("maven-core", ReflectionValueExtractor.evaluate("project.artifactId", project));
99  
100         assertEquals("Maven", ReflectionValueExtractor.evaluate("project.name", project));
101 
102         assertEquals("2.0-SNAPSHOT", ReflectionValueExtractor.evaluate("project.version", project));
103 
104         // ----------------------------------------------------------------------
105         // SCM
106         // ----------------------------------------------------------------------
107 
108         assertEquals("scm-connection", ReflectionValueExtractor.evaluate("project.scm.connection", project));
109 
110         // ----------------------------------------------------------------------
111         // Dependencies
112         // ----------------------------------------------------------------------
113 
114         List<?> dependencies = (List) ReflectionValueExtractor.evaluate("project.dependencies", project);
115 
116         assertNotNull(dependencies);
117 
118         assertEquals(2, dependencies.size());
119 
120         // ----------------------------------------------------------------------
121         // Dependencies - using index notation
122         // ----------------------------------------------------------------------
123 
124         // List
125         Dependency dependency = (Dependency) ReflectionValueExtractor.evaluate("project.dependencies[0]", project);
126 
127         assertNotNull(dependency);
128 
129         assertEquals("dep1", dependency.getArtifactId());
130 
131         String artifactId = (String) ReflectionValueExtractor.evaluate("project.dependencies[1].artifactId", project);
132 
133         assertEquals("dep2", artifactId);
134 
135         // Array
136 
137         dependency = (Dependency) ReflectionValueExtractor.evaluate("project.dependenciesAsArray[0]", project);
138 
139         assertNotNull(dependency);
140 
141         assertEquals("dep1", dependency.getArtifactId());
142 
143         artifactId = (String) ReflectionValueExtractor.evaluate("project.dependenciesAsArray[1].artifactId", project);
144 
145         assertEquals("dep2", artifactId);
146 
147         // Map
148 
149         dependency = (Dependency) ReflectionValueExtractor.evaluate("project.dependenciesAsMap(dep1)", project);
150 
151         assertNotNull(dependency);
152 
153         assertEquals("dep1", dependency.getArtifactId());
154 
155         artifactId = (String) ReflectionValueExtractor.evaluate("project.dependenciesAsMap(dep2).artifactId", project);
156 
157         assertEquals("dep2", artifactId);
158 
159         // ----------------------------------------------------------------------
160         // Build
161         // ----------------------------------------------------------------------
162 
163         Build build = (Build) ReflectionValueExtractor.evaluate("project.build", project);
164 
165         assertNotNull(build);
166     }
167 
168     /**
169      * <p>testValueExtractorWithAInvalidExpression.</p>
170      *
171      * @throws Exception if any.
172      */
173     @Test
174     public void testValueExtractorWithAInvalidExpression() throws Exception {
175         assertNull(ReflectionValueExtractor.evaluate("project.foo", project));
176         assertNull(ReflectionValueExtractor.evaluate("project.dependencies[10]", project));
177         assertNull(ReflectionValueExtractor.evaluate("project.dependencies[0].foo", project));
178     }
179 
180     /**
181      * <p>testMappedDottedKey.</p>
182      *
183      * @throws Exception if any.
184      */
185     @Test
186     public void testMappedDottedKey() throws Exception {
187         Map<String, String> map = new HashMap<String, String>();
188         map.put("a.b", "a.b-value");
189 
190         assertEquals("a.b-value", ReflectionValueExtractor.evaluate("h.value(a.b)", new ValueHolder(map)));
191     }
192 
193     /**
194      * <p>testIndexedMapped.</p>
195      *
196      * @throws Exception if any.
197      */
198     @Test
199     public void testIndexedMapped() throws Exception {
200         Map<Object, Object> map = new HashMap<Object, Object>();
201         map.put("a", "a-value");
202         List<Object> list = new ArrayList<Object>();
203         list.add(map);
204 
205         assertEquals("a-value", ReflectionValueExtractor.evaluate("h.value[0](a)", new ValueHolder(list)));
206     }
207 
208     /**
209      * <p>testMappedIndexed.</p>
210      *
211      * @throws Exception if any.
212      */
213     @Test
214     public void testMappedIndexed() throws Exception {
215         List<Object> list = new ArrayList<Object>();
216         list.add("a-value");
217         Map<Object, Object> map = new HashMap<Object, Object>();
218         map.put("a", list);
219         assertEquals("a-value", ReflectionValueExtractor.evaluate("h.value(a)[0]", new ValueHolder(map)));
220     }
221 
222     /**
223      * <p>testMappedMissingDot.</p>
224      *
225      * @throws Exception if any.
226      */
227     @Test
228     public void testMappedMissingDot() throws Exception {
229         Map<Object, Object> map = new HashMap<Object, Object>();
230         map.put("a", new ValueHolder("a-value"));
231         assertNull(ReflectionValueExtractor.evaluate("h.value(a)value", new ValueHolder(map)));
232     }
233 
234     /**
235      * <p>testIndexedMissingDot.</p>
236      *
237      * @throws Exception if any.
238      */
239     @Test
240     public void testIndexedMissingDot() throws Exception {
241         List<Object> list = new ArrayList<Object>();
242         list.add(new ValueHolder("a-value"));
243         assertNull(ReflectionValueExtractor.evaluate("h.value[0]value", new ValueHolder(list)));
244     }
245 
246     /**
247      * <p>testDotDot.</p>
248      *
249      * @throws Exception if any.
250      */
251     @Test
252     public void testDotDot() throws Exception {
253         assertNull(ReflectionValueExtractor.evaluate("h..value", new ValueHolder("value")));
254     }
255 
256     /**
257      * <p>testBadIndexedSyntax.</p>
258      *
259      * @throws Exception if any.
260      */
261     @Test
262     public void testBadIndexedSyntax() throws Exception {
263         List<Object> list = new ArrayList<Object>();
264         list.add("a-value");
265         Object value = new ValueHolder(list);
266 
267         assertNull(ReflectionValueExtractor.evaluate("h.value[", value));
268         assertNull(ReflectionValueExtractor.evaluate("h.value[]", value));
269         assertNull(ReflectionValueExtractor.evaluate("h.value[a]", value));
270         assertNull(ReflectionValueExtractor.evaluate("h.value[0", value));
271         assertNull(ReflectionValueExtractor.evaluate("h.value[0)", value));
272         assertNull(ReflectionValueExtractor.evaluate("h.value[-1]", value));
273     }
274 
275     /**
276      * <p>testBadMappedSyntax.</p>
277      *
278      * @throws Exception if any.
279      */
280     @Test
281     public void testBadMappedSyntax() throws Exception {
282         Map<Object, Object> map = new HashMap<Object, Object>();
283         map.put("a", "a-value");
284         Object value = new ValueHolder(map);
285 
286         assertNull(ReflectionValueExtractor.evaluate("h.value(", value));
287         assertNull(ReflectionValueExtractor.evaluate("h.value()", value));
288         assertNull(ReflectionValueExtractor.evaluate("h.value(a", value));
289         assertNull(ReflectionValueExtractor.evaluate("h.value(a]", value));
290     }
291 
292     /**
293      * <p>testIllegalIndexedType.</p>
294      *
295      * @throws Exception if any.
296      */
297     @Test
298     public void testIllegalIndexedType() throws Exception {
299         try {
300             ReflectionValueExtractor.evaluate("h.value[1]", new ValueHolder("string"));
301         } catch (Exception e) {
302             // TODO assert exception message
303         }
304     }
305 
306     /**
307      * <p>testIllegalMappedType.</p>
308      *
309      * @throws Exception if any.
310      */
311     @Test
312     public void testIllegalMappedType() throws Exception {
313         try {
314             ReflectionValueExtractor.evaluate("h.value(key)", new ValueHolder("string"));
315         } catch (Exception e) {
316             // TODO assert exception message
317         }
318     }
319 
320     /**
321      * <p>testTrimRootToken.</p>
322      *
323      * @throws Exception if any.
324      */
325     @Test
326     public void testTrimRootToken() throws Exception {
327         assertNull(ReflectionValueExtractor.evaluate("project", project, true));
328     }
329 
330     /**
331      * <p>testArtifactMap.</p>
332      *
333      * @throws Exception if any.
334      */
335     @Test
336     public void testArtifactMap() throws Exception {
337         assertEquals(
338                 "g0",
339                 ((Artifact) ReflectionValueExtractor.evaluate("project.artifactMap(g0:a0:c0)", project)).getGroupId());
340         assertEquals(
341                 "a1",
342                 ((Artifact) ReflectionValueExtractor.evaluate("project.artifactMap(g1:a1:c1)", project))
343                         .getArtifactId());
344         assertEquals(
345                 "c2",
346                 ((Artifact) ReflectionValueExtractor.evaluate("project.artifactMap(g2:a2:c2)", project))
347                         .getClassifier());
348     }
349 
350     public static class Artifact {
351         private String groupId;
352 
353         private String artifactId;
354 
355         private String version;
356 
357         private String extension;
358 
359         private String classifier;
360 
361         public Artifact(String groupId, String artifactId, String version, String extension, String classifier) {
362             this.groupId = groupId;
363             this.artifactId = artifactId;
364             this.version = version;
365             this.extension = extension;
366             this.classifier = classifier;
367         }
368 
369         public String getGroupId() {
370             return groupId;
371         }
372 
373         public void setGroupId(String groupId) {
374             this.groupId = groupId;
375         }
376 
377         public String getArtifactId() {
378             return artifactId;
379         }
380 
381         public void setArtifactId(String artifactId) {
382             this.artifactId = artifactId;
383         }
384 
385         public String getVersion() {
386             return version;
387         }
388 
389         public void setVersion(String version) {
390             this.version = version;
391         }
392 
393         public String getExtension() {
394             return extension;
395         }
396 
397         public void setExtension(String extension) {
398             this.extension = extension;
399         }
400 
401         public String getClassifier() {
402             return classifier;
403         }
404 
405         public void setClassifier(String classifier) {
406             this.classifier = classifier;
407         }
408     }
409 
410     public static class Project {
411         private String modelVersion;
412 
413         private String groupId;
414 
415         private Scm scm;
416 
417         private List<Dependency> dependencies = new ArrayList<>();
418 
419         private Build build;
420 
421         private String artifactId;
422 
423         private String name;
424 
425         private String version;
426 
427         private Map<String, Artifact> artifactMap = new HashMap<>();
428         private String description;
429 
430         public void setModelVersion(String modelVersion) {
431             this.modelVersion = modelVersion;
432         }
433 
434         public void setGroupId(String groupId) {
435             this.groupId = groupId;
436         }
437 
438         public void setScm(Scm scm) {
439             this.scm = scm;
440         }
441 
442         public void addDependency(Dependency dependency) {
443             this.dependencies.add(dependency);
444         }
445 
446         public void setBuild(Build build) {
447             this.build = build;
448         }
449 
450         public void setArtifactId(String artifactId) {
451             this.artifactId = artifactId;
452         }
453 
454         public void setName(String name) {
455             this.name = name;
456         }
457 
458         public void setVersion(String version) {
459             this.version = version;
460         }
461 
462         public Scm getScm() {
463             return scm;
464         }
465 
466         public String getModelVersion() {
467             return modelVersion;
468         }
469 
470         public String getGroupId() {
471             return groupId;
472         }
473 
474         public List<Dependency> getDependencies() {
475             return dependencies;
476         }
477 
478         public Build getBuild() {
479             return build;
480         }
481 
482         public String getArtifactId() {
483             return artifactId;
484         }
485 
486         public String getName() {
487             return name;
488         }
489 
490         public String getVersion() {
491             return version;
492         }
493 
494         public Dependency[] getDependenciesAsArray() {
495             return getDependencies().toArray(new Dependency[0]);
496         }
497 
498         public Map<String, Dependency> getDependenciesAsMap() {
499             Map<String, Dependency> ret = new HashMap<>();
500             for (Dependency dep : getDependencies()) {
501                 ret.put(dep.getArtifactId(), dep);
502             }
503             return ret;
504         }
505 
506         // ${project.artifactMap(g:a:v)}
507         public void addArtifact(Artifact a) {
508             artifactMap.put(a.getGroupId() + ":" + a.getArtifactId() + ":" + a.getClassifier(), a);
509         }
510 
511         public Map<String, Artifact> getArtifactMap() {
512             return artifactMap;
513         }
514 
515         public void setDescription(String description) {
516             this.description = description;
517         }
518 
519         public String getDescription() {
520             return description;
521         }
522     }
523 
524     public static class Build {}
525 
526     public static class Dependency {
527         private String artifactId;
528 
529         public String getArtifactId() {
530             return artifactId;
531         }
532 
533         public void setArtifactId(String id) {
534             artifactId = id;
535         }
536     }
537 
538     public static class Scm {
539         private String connection;
540 
541         public void setConnection(String connection) {
542             this.connection = connection;
543         }
544 
545         public String getConnection() {
546             return connection;
547         }
548     }
549 
550     public static class ValueHolder {
551         private final Object value;
552 
553         public ValueHolder(Object value) {
554             this.value = value;
555         }
556 
557         public Object getValue() {
558             return value;
559         }
560     }
561 
562     /**
563      * <p>testRootPropertyRegression.</p>
564      *
565      * @throws Exception if any.
566      */
567     @Test
568     public void testRootPropertyRegression() throws Exception {
569         Project project = new Project();
570         project.setDescription("c:\\\\org\\apache\\test");
571         Object evalued = ReflectionValueExtractor.evaluate("description", project);
572         assertNotNull(evalued);
573     }
574 }