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.jxpath.ri.model.dynamic;
18  
19  import java.util.ArrayList;
20  import java.util.HashMap;
21  import java.util.List;
22  import java.util.Map;
23  
24  import org.apache.commons.jxpath.JXPathContext;
25  import org.apache.commons.jxpath.JXPathTestCase;
26  import org.apache.commons.jxpath.TestBean;
27  
28  /**
29   * TODO more iterator testing with maps
30   *
31   * @author Dmitri Plotnikov
32   * @version $Revision: 652845 $ $Date: 2008-05-02 19:46:46 +0200 (Fr, 02 Mai 2008) $
33   */
34  
35  public class DynamicPropertiesModelTest extends JXPathTestCase {
36      private JXPathContext context;
37  
38      public void setUp() {
39          if (context == null) {
40              context = JXPathContext.newContext(new TestBean());
41              context.setFactory(new TestDynamicPropertyFactory());
42          }
43      }
44  
45      public void testAxisChild() {
46          assertXPathValue(context, "map/Key1", "Value 1");
47  
48          assertXPathPointer(context, "map/Key1", "/map[@name='Key1']");
49  
50          assertXPathValue(context, "map/Key2/name", "Name 6");
51  
52          assertXPathPointer(context, "map/Key2/name", "/map[@name='Key2']/name");
53      }
54  
55      public void testAxisDescendant() {
56          assertXPathValue(context, "//Key1", "Value 1");
57      }
58  
59      /**
60       * Testing the pseudo-attribute "name" that dynamic property
61       * objects appear to have.
62       */
63      public void testAttributeName() {
64          assertXPathValue(context, "map[@name = 'Key1']", "Value 1");
65  
66          assertXPathPointer(
67              context,
68              "map[@name = 'Key1']",
69              "/map[@name='Key1']");
70  
71          assertXPathPointerLenient(
72              context,
73              "map[@name = 'Key"'"'1']",
74              "/map[@name='Key"'"'1']");
75  
76          assertXPathValue(context, "/.[@name='map']/Key2/name", "Name 6");
77  
78          assertXPathPointer(
79              context,
80              "/.[@name='map']/Key2/name",
81              "/map[@name='Key2']/name");
82  
83          // Bean in a map
84          assertXPathValue(context, "/map[@name='Key2'][@name='name']", "Name 6");
85  
86          assertXPathPointer(
87              context,
88              "/map[@name='Key2'][@name='name']",
89              "/map[@name='Key2']/name");
90  
91          // Map in a bean in a map
92          assertXPathValue(
93              context,
94              "/.[@name='map'][@name='Key2'][@name='name']",
95              "Name 6");
96  
97          assertXPathPointer(
98              context,
99              "/.[@name='map'][@name='Key2'][@name='name']",
100             "/map[@name='Key2']/name");
101                         
102         ((Map)context.getValue("map")).put("Key:3", "value3");
103         
104         assertXPathValueAndPointer(
105             context,
106             "/map[@name='Key:3']",
107             "value3",
108             "/map[@name='Key:3']");
109 
110         assertXPathValueAndPointer(
111             context,
112             "/map[@name='Key:4:5']",
113             null,
114             "/map[@name='Key:4:5']");
115     }
116 
117     public void testSetPrimitiveValue() {
118         assertXPathSetValue(context, "map/Key1", new Integer(6));
119     }
120 
121     public void testSetCollection() {
122         // See if we can assign a whole collection        
123         context.setValue(
124             "map/Key1",
125             new Integer[] { new Integer(7), new Integer(8)});
126 
127         // And then an element in that collection
128         assertXPathSetValue(context, "map/Key1[1]", new Integer(9));
129     }
130 
131     /**
132      * The key does not exist, but the assignment should succeed anyway,
133      * because you should always be able to store anything in a Map.
134      */
135     public void testSetNewKey() {
136         // Using a "simple" path
137         assertXPathSetValue(context, "map/Key4", new Integer(7));
138         
139         // Using a "non-simple" path
140         assertXPathPointerLenient(context, "//map/Key5", "/map/Key5");
141         
142         assertXPathSetValue(context, "//map/Key5", new Integer(8));
143     }
144 
145     public void testCreatePath() {
146         TestBean bean = (TestBean) context.getContextBean();
147         bean.setMap(null);
148 
149         // Calls factory.createObject(..., testBean, "map"), then
150         // sets the value
151         assertXPathCreatePath(
152             context,
153             "/map[@name='TestKey1']",
154             "",
155             "/map[@name='TestKey1']");
156     }
157 
158     public void testCreatePathAndSetValue() {
159         TestBean bean = (TestBean) context.getContextBean();
160         bean.setMap(null);
161 
162         // Calls factory.createObject(..., testBean, "map"), then
163         // sets the value
164         assertXPathCreatePathAndSetValue(
165             context,
166             "/map[@name='TestKey1']",
167             "Test",
168             "/map[@name='TestKey1']");
169     }
170 
171     public void testCreatePathCreateBean() {
172         TestBean bean = (TestBean) context.getContextBean();
173         bean.setMap(null);
174 
175         // Calls factory.createObject(..., testBean, "map"), then
176         // then factory.createObject(..., map, "TestKey2"), then
177         // sets the value
178         assertXPathCreatePath(
179             context,
180             "/map[@name='TestKey2']/int",
181             new Integer(1),
182             "/map[@name='TestKey2']/int");
183     }
184 
185     public void testCreatePathAndSetValueCreateBean() {
186         TestBean bean = (TestBean) context.getContextBean();
187         bean.setMap(null);
188 
189         // Calls factory.createObject(..., testBean, "map"), then
190         // then factory.createObject(..., map, "TestKey2"), then
191         // sets the value
192         assertXPathCreatePathAndSetValue(
193             context,
194             "/map[@name='TestKey2']/int",
195             new Integer(4),
196             "/map[@name='TestKey2']/int");
197     }
198 
199     public void testCreatePathCollectionElement() {
200         TestBean bean = (TestBean) context.getContextBean();
201         bean.setMap(null);
202 
203         assertXPathCreatePath(
204             context,
205             "/map/TestKey3[2]",
206             null,
207             "/map[@name='TestKey3'][2]");
208 
209         // Should be the same as the one before
210         assertXPathCreatePath(
211             context,
212             "/map[@name='TestKey3'][3]",
213             null,
214             "/map[@name='TestKey3'][3]");
215     }
216 
217     public void testCreatePathAndSetValueCollectionElement() {
218         TestBean bean = (TestBean) context.getContextBean();
219         bean.setMap(null);
220 
221         assertXPathCreatePathAndSetValue(
222             context,
223             "/map/TestKey3[2]",
224             "Test1",
225             "/map[@name='TestKey3'][2]");
226 
227         // Should be the same as the one before
228         assertXPathCreatePathAndSetValue(
229             context,
230             "/map[@name='TestKey3'][3]",
231             "Test2",
232             "/map[@name='TestKey3'][3]");
233     }
234 
235     public void testCreatePathNewCollectionElement() {
236         TestBean bean = (TestBean) context.getContextBean();
237         bean.setMap(null);
238 
239         // Create an element of a dynamic map element, which is a collection
240         assertXPathCreatePath(
241             context,
242             "/map/TestKey4[1]/int",
243             new Integer(1),
244             "/map[@name='TestKey4'][1]/int");
245 
246         bean.getMap().remove("TestKey4");
247 
248         // Should be the same as the one before
249         assertXPathCreatePath(
250             context,
251             "/map/TestKey4[1]/int",
252             new Integer(1),
253             "/map[@name='TestKey4'][1]/int");
254     }
255 
256     public void testCreatePathAndSetValueNewCollectionElement() {
257         TestBean bean = (TestBean) context.getContextBean();
258         bean.setMap(null);
259 
260         // Create an element of a dynamic map element, which is a collection
261         assertXPathCreatePathAndSetValue(
262             context,
263             "/map/TestKey4[1]/int",
264             new Integer(2),
265             "/map[@name='TestKey4'][1]/int");
266 
267         bean.getMap().remove("TestKey4");
268 
269         // Should be the same as the one before
270         assertXPathCreatePathAndSetValue(
271             context,
272             "/map/TestKey4[1]/int",
273             new Integer(3),
274             "/map[@name='TestKey4'][1]/int");
275     }
276 
277     public void testRemovePath() {
278         TestBean bean = (TestBean) context.getContextBean();
279         bean.getMap().put("TestKey1", "test");
280 
281         // Remove dynamic property
282         context.removePath("map[@name = 'TestKey1']");
283         assertEquals(
284             "Remove dynamic property value",
285             null,
286             context.getValue("map[@name = 'TestKey1']"));
287     }
288 
289     public void testRemovePathArrayElement() {
290         TestBean bean = (TestBean) context.getContextBean();
291 
292         bean.getMap().put("TestKey2", new String[] { "temp1", "temp2" });
293         context.removePath("map[@name = 'TestKey2'][1]");
294         assertEquals(
295             "Remove dynamic property collection element",
296             "temp2",
297             context.getValue("map[@name = 'TestKey2'][1]"));
298     }
299     
300     public void testCollectionOfMaps() {
301         TestBean bean = (TestBean) context.getContextBean();
302         List list = new ArrayList();
303 
304         bean.getMap().put("stuff", list);        
305 
306         Map m = new HashMap();
307         m.put("fruit", "apple");
308         list.add(m);
309 
310         m = new HashMap();
311         m.put("berry", "watermelon");
312         list.add(m);
313 
314         m = new HashMap();
315         m.put("fruit", "banana");
316         list.add(m);
317 
318         assertXPathValueIterator(
319             context,
320             "/map/stuff/fruit",
321             list("apple", "banana"));
322 
323         assertXPathValueIterator(
324             context,
325             "/map/stuff[@name='fruit']",
326             list("apple", "banana"));        
327     }
328 
329     public void testMapOfMaps() {
330         TestBean bean = (TestBean) context.getContextBean();
331 
332         Map fruit = new HashMap();
333         fruit.put("apple", "green");
334         fruit.put("orange", "red");
335         
336         Map meat = new HashMap();
337         meat.put("pork", "pig");
338         meat.put("beef", "cow");
339         
340         bean.getMap().put("fruit", fruit);        
341         bean.getMap().put("meat", meat);        
342                 
343         assertXPathPointer(
344             context,
345             "//beef",
346             "/map[@name='meat'][@name='beef']");
347         
348         assertXPathPointer(
349             context,
350             "map//apple",
351             "/map[@name='fruit'][@name='apple']");
352 
353         // Ambiguous search - will return nothing
354         assertXPathPointerLenient(context, "map//banana", "null()");
355         
356         // Unambiguous, even though the particular key is missing 
357         assertXPathPointerLenient(
358             context,
359             "//fruit/pear",
360             "/map[@name='fruit']/pear");
361     }
362 }