View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.jexl3.internal.introspection;
18  
19  import java.io.Serializable;
20  import org.apache.commons.jexl3.JexlTestCase;
21  import org.apache.commons.jexl3.internal.Engine;
22  import org.apache.commons.jexl3.introspection.JexlPropertyGet;
23  import org.apache.commons.jexl3.introspection.JexlPropertySet;
24  
25  import java.util.ArrayList;
26  import java.util.HashMap;
27  import java.util.List;
28  import java.util.Map;
29  import org.apache.commons.jexl3.introspection.JexlMethod;
30  import org.junit.Assert;
31  import org.junit.Test;
32  
33  /**
34   * Tests for checking introspection discovery.
35   *
36   * @since 2.0
37   */
38  public class DiscoveryTest extends JexlTestCase {
39      public DiscoveryTest() {
40          super("DiscoveryTest");
41      }
42  
43      public static class Duck {
44          private String value;
45          private String eulav;
46  
47          public Duck(final String v, final String e) {
48              value = v;
49              eulav = e;
50          }
51  
52          public String get(final String prop) {
53              if ("value".equals(prop)) {
54                  return value;
55              }
56              if ("eulav".equals(prop)) {
57                  return eulav;
58              }
59              return "no such property";
60          }
61  
62          public void set(final String prop, final String v) {
63              if ("value".equals(prop)) {
64                  value = v;
65              } else if ("eulav".equals(prop)) {
66                  eulav = v;
67              }
68          }
69      }
70  
71      public static class Bean {
72          private String value;
73          private String eulav;
74          private boolean flag;
75  
76          public Bean(final String v, final String e) {
77              value = v;
78              eulav = e;
79              flag = true;
80          }
81  
82          public String getValue() {
83              return value;
84          }
85  
86          public void setValue(final String v) {
87              value = v;
88          }
89  
90          public String getEulav() {
91              return eulav;
92          }
93  
94          public void setEulav(final String v) {
95              eulav = v;
96          }
97  
98          public boolean isFlag() {
99              return flag;
100         }
101 
102         public void setFlag(final boolean f) {
103             flag = f;
104         }
105     }
106 
107     @Test
108     public void testBeanIntrospection() throws Exception {
109         final Uberspect uber = Engine.getUberspect(null, null);
110         final Bean bean = new Bean("JEXL", "LXEJ");
111 
112         final JexlPropertyGet get = uber.getPropertyGet(bean, "value");
113         final JexlPropertySet set = uber.getPropertySet(bean, "value", "foo");
114         Assert.assertTrue("bean property getter", get instanceof PropertyGetExecutor);
115         Assert.assertTrue("bean property setter", set instanceof PropertySetExecutor);
116         // introspector and uberspect should return same result
117         Assert.assertEquals(get, uber.getPropertyGet(bean, "value"));
118         Assert.assertEquals(set, uber.getPropertySet(bean, "value", "foo"));
119         // different property should return different setter/getter
120         Assert.assertNotEquals(get, uber.getPropertyGet(bean, "eulav"));
121         Assert.assertNotEquals(set, uber.getPropertySet(bean, "eulav", "foo"));
122         // setter returns argument
123         final Object bar = set.invoke(bean, "bar");
124         Assert.assertEquals("bar", bar);
125         // getter should return last value
126         Assert.assertEquals("bar", get.invoke(bean));
127         // tryExecute should succeed on same property
128         final Object quux = set.tryInvoke(bean, "value", "quux");
129         Assert.assertEquals("quux", quux);
130         Assert.assertEquals("quux", get.invoke(bean));
131         // tryExecute should fail on different property
132         Assert.assertEquals(AbstractExecutor.TRY_FAILED, set.tryInvoke(bean, "eulav", "nope"));
133 
134     }
135 
136     @Test
137     public void testDuckIntrospection() throws Exception {
138         final Uberspect uber = Engine.getUberspect(null, null);
139         final Duck duck = new Duck("JEXL", "LXEJ");
140 
141         final JexlPropertyGet get = uber.getPropertyGet(duck, "value");
142         final JexlPropertySet set = uber.getPropertySet(duck, "value", "foo");
143         Assert.assertTrue("duck property getter", get instanceof DuckGetExecutor);
144         Assert.assertTrue("duck property setter", set instanceof DuckSetExecutor);
145         // introspector and uberspect should return same result
146         Assert.assertEquals(get, uber.getPropertyGet(duck, "value"));
147         Assert.assertEquals(set, uber.getPropertySet(duck, "value", "foo"));
148         // different property should return different setter/getter
149         Assert.assertNotEquals(get, uber.getPropertyGet(duck, "eulav"));
150         Assert.assertNotEquals(set, uber.getPropertySet(duck, "eulav", "foo"));
151         // setter returns argument
152         final Object bar = set.invoke(duck, "bar");
153         Assert.assertEquals("bar", bar);
154         // getter should return last value
155         Assert.assertEquals("bar", get.invoke(duck));
156         // tryExecute should succeed on same property
157         final Object quux = set.tryInvoke(duck, "value", "quux");
158         Assert.assertEquals("quux", quux);
159         Assert.assertEquals("quux", get.invoke(duck));
160         // tryExecute should fail on different property
161         Assert.assertEquals(AbstractExecutor.TRY_FAILED, set.tryInvoke(duck, "eulav", "nope"));
162     }
163 
164     @Test
165     public void testListIntrospection() throws Exception {
166         final Uberspect uber = Engine.getUberspect(null, null);
167         final List<Object> list = new ArrayList<>();
168         list.add("LIST");
169         list.add("TSIL");
170 
171         final JexlPropertyGet get = uber.getPropertyGet(list, 1);
172         final JexlPropertySet set = uber.getPropertySet(list, 1, "foo");
173         Assert.assertTrue("list property getter", get instanceof ListGetExecutor);
174         Assert.assertTrue("list property setter", set instanceof ListSetExecutor);
175         // introspector and uberspect should return same result
176         Assert.assertEquals(get, uber.getPropertyGet(list, 1));
177         Assert.assertEquals(set, uber.getPropertySet(list, 1, "foo"));
178         // different property should return different setter/getter
179         Assert.assertNotEquals(get, uber.getPropertyGet(list, 0));
180         Assert.assertNotEquals(get, uber.getPropertySet(list, 0, "foo"));
181         // setter returns argument
182         final Object bar = set.invoke(list, "bar");
183         Assert.assertEquals("bar", bar);
184         // getter should return last value
185         Assert.assertEquals("bar", get.invoke(list));
186         // tryExecute should succeed on integer property
187         final Object quux = set.tryInvoke(list, 1, "quux");
188         Assert.assertEquals("quux", quux);
189         // getter should return last value
190         Assert.assertEquals("quux", get.invoke(list));
191         // tryExecute should fail on non-integer property class
192         Assert.assertEquals(AbstractExecutor.TRY_FAILED, set.tryInvoke(list, "eulav", "nope"));
193     }
194 
195     @Test
196     public void testMapIntrospection() throws Exception {
197         final Uberspect uber = Engine.getUberspect(null, null);
198         final Map<String, Object> map = new HashMap<>();
199         map.put("value", "MAP");
200         map.put("eulav", "PAM");
201 
202         final JexlPropertyGet get = uber.getPropertyGet(map, "value");
203         final JexlPropertySet set = uber.getPropertySet(map, "value", "foo");
204         Assert.assertTrue("map property getter", get instanceof MapGetExecutor);
205         Assert.assertTrue("map property setter", set instanceof MapSetExecutor);
206         // introspector and uberspect should return same result
207         Assert.assertEquals(get, uber.getPropertyGet(map, "value"));
208         Assert.assertEquals(set, uber.getPropertySet(map, "value", "foo"));
209         // different property should return different setter/getter
210         Assert.assertNotEquals(get, uber.getPropertyGet(map, "eulav"));
211         Assert.assertNotEquals(get, uber.getPropertySet(map, "eulav", "foo"));
212         // setter returns argument
213         final Object bar = set.invoke(map, "bar");
214         Assert.assertEquals("bar", bar);
215         // getter should return last value
216         Assert.assertEquals("bar", get.invoke(map));
217         // tryExecute should succeed on same property class
218         final Object quux = set.tryInvoke(map, "value", "quux");
219         Assert.assertEquals("quux", quux);
220         // getter should return last value
221         Assert.assertEquals("quux", get.invoke(map));
222         // tryExecute should fail on different property class
223         Assert.assertEquals(AbstractExecutor.TRY_FAILED, set.tryInvoke(map, 1, "nope"));
224     }
225 
226     public static class Bulgroz {
227         public Object list(final int x) {
228             return 0;
229         }
230         public Object list(final String x) {
231             return 1;
232         }
233         public Object list(final Object x) {
234             return 2;
235         }
236         public Object list(final int x, final Object...y) {
237             return 3;
238         }
239         public Object list(final int x, final int y) {
240             return 4;
241         }
242         public Object list(final String x, final Object...y) {
243             return 5;
244         }
245         public Object list(final String x, final String y) {
246             return 6;
247         }
248         public Object list(final Object x, final Object...y) {
249             return 7;
250         }
251         public Object list(final Object x, final Object y) {
252             return 8;
253         }
254         public Object amb(final Serializable x) {
255             return -1;
256         }
257         public Object amb(final Number x) {
258             return -2;
259         }
260     }
261 
262     @Test
263     public void testMethodIntrospection() throws Exception {
264         final Uberspect uber = new Uberspect(null, null);
265         final Bulgroz bulgroz = new Bulgroz();
266         JexlMethod jmethod;
267         Object result;
268         jmethod = uber.getMethod(bulgroz, "list", 0);
269         result = jmethod.invoke(bulgroz, 0);
270         Assert.assertEquals(0, result);
271         jmethod = uber.getMethod(bulgroz, "list", "1");
272         result = jmethod.invoke(bulgroz, "1");
273         Assert.assertEquals(1, result);
274         jmethod = uber.getMethod(bulgroz, "list", bulgroz);
275         result = jmethod.invoke(bulgroz, bulgroz);
276         Assert.assertEquals(2, result);
277         jmethod = uber.getMethod(bulgroz, "list", 1, bulgroz);
278         result = jmethod.invoke(bulgroz, 1, bulgroz);
279         Assert.assertEquals(3, result);
280         jmethod = uber.getMethod(bulgroz, "list", 1, bulgroz, bulgroz);
281         result = jmethod.invoke(bulgroz, 1, bulgroz, bulgroz);
282         Assert.assertEquals(3, result);
283         jmethod = uber.getMethod(bulgroz, "list", 1, 2);
284         result = jmethod.invoke(bulgroz, 1, 2);
285         Assert.assertEquals(4, result);
286         jmethod = uber.getMethod(bulgroz, "list", "1", bulgroz);
287         result = jmethod.invoke(bulgroz, "1", bulgroz);
288         Assert.assertEquals(5, result);
289         jmethod = uber.getMethod(bulgroz, "list", "1", "2");
290         result = jmethod.invoke(bulgroz, "1", "2");
291         Assert.assertEquals(6, result);
292         jmethod = uber.getMethod(bulgroz, "list", bulgroz, bulgroz);
293         result = jmethod.invoke(bulgroz, bulgroz, bulgroz);
294         Assert.assertEquals(8, result);
295         jmethod = uber.getMethod(bulgroz, "list", bulgroz, 1, bulgroz);
296         result = jmethod.invoke(bulgroz, bulgroz, 1, bulgroz);
297         Assert.assertEquals(7, result);
298         jmethod = uber.getMethod(bulgroz, "list", bulgroz, 1, "1");
299         result = jmethod.invoke(bulgroz, bulgroz, 1, "1");
300         Assert.assertEquals(7, result);
301         jmethod = uber.getMethod(bulgroz, "list", (Object) null);
302         result = jmethod.invoke(bulgroz,  (Object) null);
303         Assert.assertEquals(2, result);
304         jmethod = uber.getMethod(bulgroz, "list", bulgroz, (Object) null);
305         result = jmethod.invoke(bulgroz, bulgroz, (Object) null);
306         Assert.assertEquals(8, result);
307         jmethod = uber.getMethod(bulgroz, "list", null, "1");
308         result = jmethod.invoke(bulgroz, null, "1");
309         Assert.assertEquals(8, result);
310         jmethod = uber.getMethod(bulgroz, "list", bulgroz, null, null);
311         result = jmethod.invoke(bulgroz, bulgroz, null, null);
312         Assert.assertEquals(7, result);
313 
314         jmethod = uber.getMethod(bulgroz, "amb", 3d);
315         Assert.assertNotNull(null, jmethod);
316     }
317 }