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.shale.clay.config;
18  
19  import java.util.Iterator;
20  import java.util.Map;
21  import java.util.TreeMap;
22  
23  import javax.faces.component.UIComponent;
24  
25  import junit.framework.Test;
26  import junit.framework.TestSuite;
27  
28  import org.apache.commons.chain.Command;
29  import org.apache.shale.clay.component.chain.AbstractCommand;
30  import org.apache.shale.clay.component.chain.ClayContext;
31  import org.apache.shale.clay.component.chain.CreateComponentCommand;
32  import org.apache.shale.clay.component.chain.PropertyValueCommand;
33  import org.apache.shale.clay.config.beans.AttributeBean;
34  import org.apache.shale.clay.config.beans.ComponentBean;
35  import org.apache.shale.clay.config.beans.ElementBean;
36  import org.apache.shale.clay.config.beans.SymbolBean;
37  
38  // tests properties and symbol evaluation
39  public class SymbolsTestCase extends AbstractTestCaseConfig {
40  
41      // Construct a new instance of this test case.
42      public SymbolsTestCase(String name) {
43          super(name);
44      }
45  
46      // Return the tests included in this test case.
47      public static Test suite() {
48  
49          return (new TestSuite(SymbolsTestCase.class));
50  
51      }
52   
53      public void testNestedSymbolReplacement() {
54          
55          
56          Map symbols = new TreeMap();
57          
58          ClayContext clayContext = new ClayContext();
59          clayContext.setFacesContext(facesContext);
60          clayContext.setSymbols(symbols);
61          
62          SymbolBean symbol = this.createSymbol("@a", "@b");
63          symbols.put(symbol.getName(), symbol);
64          
65          symbol = this.createSymbol("@b", "@c");
66          symbols.put(symbol.getName(), symbol);
67          
68          symbol = this.createSymbol("@c", "@d");
69          symbols.put(symbol.getName(), symbol);
70          
71          symbol = this.createSymbol("@d", "test");
72          symbols.put(symbol.getName(), symbol);
73          
74          AbstractCommand.realizeSymbols(clayContext);
75          
76          symbol = (SymbolBean) symbols.get("@a");
77          assertNotNull(symbol);
78          assertEquals("test", symbol.getValue());
79          
80          symbol = (SymbolBean) symbols.get("@b");
81          assertNotNull(symbol);
82          assertEquals("test", symbol.getValue());
83          
84          symbol = (SymbolBean) symbols.get("@c");
85          assertNotNull(symbol);
86          assertEquals("test", symbol.getValue());
87          
88          symbol = (SymbolBean) symbols.get("@d");
89          assertNotNull(symbol);
90          assertEquals("test", symbol.getValue());
91          
92          
93          symbols.clear();
94          
95          symbol = this.createSymbol("@a", "@b");
96          symbols.put(symbol.getName(), symbol);
97          
98          symbol = this.createSymbol("@b", "@a");
99          symbols.put(symbol.getName(), symbol);
100         
101         AbstractCommand.realizeSymbols(clayContext);
102         
103         symbol = (SymbolBean) symbols.get("@a");
104         assertNotNull(symbol);
105         assertEquals("@a", symbol.getValue());
106         
107         symbol = (SymbolBean) symbols.get("@b");
108         assertNotNull(symbol);
109         assertEquals("@a", symbol.getValue());
110         
111         
112         
113         symbols.clear();
114         
115         symbol = this.createSymbol("@foo", "@xbeanx.@xpropertyx");
116         symbols.put(symbol.getName(), symbol);
117         
118         symbol = this.createSymbol("@xbeanx", "@a");
119         symbols.put(symbol.getName(), symbol);
120         
121         symbol = this.createSymbol("@xpropertyx", "@b");
122         symbols.put(symbol.getName(), symbol);
123         
124         symbol = this.createSymbol("@a", "foo");
125         symbols.put(symbol.getName(), symbol);
126         
127         symbol = this.createSymbol("@b", "bar");
128         symbols.put(symbol.getName(), symbol);
129         
130         AbstractCommand.realizeSymbols(clayContext);
131         
132         symbol = (SymbolBean) symbols.get("@foo");
133         assertNotNull(symbol);
134         assertEquals("foo.bar", symbol.getValue());
135         
136     }
137     
138     
139     
140     public void testGenericPropertyCommand () throws Exception {
141         javax.faces.component.html.HtmlOutputText child = (javax.faces.component.html.HtmlOutputText) 
142                                 facesContext.getApplication().createComponent("javax.faces.HtmlOutputText"); 
143        assertNotNull("javax.faces.HtmlOutputText", child);
144        
145        
146        AttributeBean attr = new AttributeBean();
147        attr.setName("value");
148        attr.setBindingType(AttributeBean.BINDING_TYPE_NONE);
149        attr.setValue("10");
150        
151        ComponentBean displayElement = new ComponentBean();
152        displayElement.setJsfid("inputText");
153        displayElement.setComponentType("javax.faces.HtmlOutputText");
154        displayElement.setId("testId");
155        displayElement.addAttribute(attr);
156        
157        assertNotNull("attribute case insensitive", displayElement.getAttribute("VaLue"));
158        
159        ClayContext clayContext = new ClayContext();
160        clayContext.setFacesContext(facesContext);
161        clayContext.setChild(child);
162        clayContext.setAttribute(attr);
163        clayContext.setDisplayElement(displayElement);
164               
165        Command command = new PropertyValueCommand();
166        boolean isFinal = command.execute(clayContext);
167        assertEquals("command finished", true, isFinal);       
168        assertEquals("value = 10", child.getValue(), "10");
169 
170        
171        child = (javax.faces.component.html.HtmlOutputText) 
172                                facesContext.getApplication().createComponent("javax.faces.HtmlOutputText"); 
173        assertNotNull("javax.faces.HtmlOutputText", child);
174        clayContext.setChild(child);
175        
176        servletContext.setAttribute("goodYear", "1969");
177        attr.setBindingType(AttributeBean.BINDING_TYPE_VALUE);
178        attr.setValue("#{goodYear}");
179 
180        isFinal = command.execute(clayContext);
181        assertEquals("command finished", true, isFinal);       
182        assertEquals("value = 1969", "1969", child.getValue());
183        
184        child = (javax.faces.component.html.HtmlOutputText) 
185                              facesContext.getApplication().createComponent("javax.faces.HtmlOutputText"); 
186        assertNotNull("javax.faces.HtmlOutputText", child);
187        clayContext.setChild(child);
188        
189        servletContext.setAttribute("ping", "pong");
190        attr.setBindingType(AttributeBean.BINDING_TYPE_EARLY);
191        attr.setValue("#{ping}");
192 
193        isFinal = command.execute(clayContext);
194        assertEquals("command finished", true, isFinal);       
195        assertEquals("value = pong", child.getValue(), "pong");
196 
197 
198        child = (javax.faces.component.html.HtmlOutputText) 
199                                facesContext.getApplication().createComponent("javax.faces.HtmlOutputText"); 
200        assertNotNull("javax.faces.HtmlOutputText", child);
201        clayContext.setChild(child);
202        
203        attr.setBindingType(AttributeBean.BINDING_TYPE_NONE);
204        attr.setValue("#{forManfred}");
205 
206        isFinal = command.execute(clayContext);
207        assertEquals("command finished", true, isFinal);       
208        assertEquals("value = #{forManfred}", "#{forManfred}", child.getValue());
209 
210         
211     }
212    
213     //factory method for creating a symbol bean
214     private SymbolBean createSymbol(String name, String value) {
215         SymbolBean symbol = new SymbolBean();
216         symbol.setName(name);
217         symbol.setValue(value);
218         return symbol;
219     }   
220     
221     // test symbolic property replacement
222     public void testSymbolicProperties() throws Exception {
223            javax.faces.component.html.HtmlOutputText child = (javax.faces.component.html.HtmlOutputText) 
224                               facesContext.getApplication().createComponent("javax.faces.HtmlOutputText"); 
225            assertNotNull("javax.faces.HtmlOutputText", child);
226            
227            
228            AttributeBean attr = new AttributeBean();
229            attr.setName("value");
230            attr.setBindingType(AttributeBean.BINDING_TYPE_NONE);
231            attr.setValue("@value");  //symbolic attribute 
232                       
233            ComponentBean displayElement = new ComponentBean();
234            displayElement.setJsfid("inputText");
235            displayElement.setComponentType("javax.faces.HtmlOutputText");
236            displayElement.setId("testId");
237            displayElement.addAttribute(attr);
238            displayElement.addSymbol(createSymbol("@value", "10"));
239                       
240            ClayContext clayContext = new ClayContext();
241            clayContext.setFacesContext(facesContext);
242            clayContext.setChild(child);
243            clayContext.setAttribute(attr);
244            clayContext.setDisplayElement(displayElement);
245            clayContext.setSymbols(displayElement.getSymbols());
246            
247            Command command = new PropertyValueCommand();
248            boolean isFinal = command.execute(clayContext);
249            assertEquals("command finished", true, isFinal);       
250            assertEquals("value = 10", "10", child.getValue());
251 
252            
253            // test a symbol value of an el value
254            child = (javax.faces.component.html.HtmlOutputText) 
255                         facesContext.getApplication().createComponent("javax.faces.HtmlOutputText"); 
256            assertNotNull("javax.faces.HtmlOutputText", child);
257 
258            displayElement.addSymbol(createSymbol("@value", "#{value}"));
259            attr.setBindingType(AttributeBean.BINDING_TYPE_EARLY);
260            servletContext.setAttribute("value", "10");
261           
262            clayContext.setFacesContext(facesContext);
263            clayContext.setChild(child);
264            clayContext.setAttribute(attr);
265            clayContext.setDisplayElement(displayElement);
266            clayContext.setSymbols(displayElement.getSymbols());
267            
268            isFinal = command.execute(clayContext);
269            assertEquals("command finished", true, isFinal);       
270            assertEquals("value = 10", "10", child.getValue());
271 
272            
273            // test a symbol value with a null value symbol replacement
274            child = (javax.faces.component.html.HtmlOutputText) 
275                  facesContext.getApplication().createComponent("javax.faces.HtmlOutputText"); 
276            assertNotNull("javax.faces.HtmlOutputText", child);
277 
278            displayElement.addSymbol(createSymbol("@value", null));
279            attr.setBindingType(AttributeBean.BINDING_TYPE_EARLY);
280           
281            clayContext.setFacesContext(facesContext);
282            clayContext.setChild(child);
283            clayContext.setAttribute(attr);
284            clayContext.setDisplayElement(displayElement);
285            clayContext.setSymbols(displayElement.getSymbols());
286            
287            isFinal = command.execute(clayContext);
288            assertEquals("command finished", true, isFinal);       
289            assertEquals("value = null", null, child.getValue());
290 
291 
292            // test a symbol value with an empty String value.  
293            // this will evaluate to null since it is a symbol replacement.
294            child = (javax.faces.component.html.HtmlOutputText) 
295                      facesContext.getApplication().createComponent("javax.faces.HtmlOutputText"); 
296            assertNotNull("javax.faces.HtmlOutputText", child);
297 
298            displayElement.addSymbol(createSymbol("@value", ""));
299            attr.setBindingType(AttributeBean.BINDING_TYPE_EARLY);
300           
301            clayContext.setFacesContext(facesContext);
302            clayContext.setChild(child);
303            clayContext.setAttribute(attr);
304            clayContext.setDisplayElement(displayElement);
305            clayContext.setSymbols(displayElement.getSymbols());
306            
307            isFinal = command.execute(clayContext);
308            assertEquals("command finished", true, isFinal);       
309            assertEquals("value = null", null, child.getValue());
310 
311            //no symbol replacement for a empty string - should return
312            //an empty string.  This allows components like the selectItem
313            //to create an empty select list pick.
314            attr.setValue("");  //empty string           
315            child = (javax.faces.component.html.HtmlOutputText) 
316                         facesContext.getApplication().createComponent("javax.faces.HtmlOutputText"); 
317            assertNotNull("javax.faces.HtmlOutputText", child);
318 
319            clayContext.setFacesContext(facesContext);
320            clayContext.setChild(child);
321            clayContext.setAttribute(attr);
322            clayContext.setDisplayElement(displayElement);
323            
324            isFinal = command.execute(clayContext);
325            assertEquals("command finished", true, isFinal);       
326            assertEquals("value = \"\"", "", child.getValue());
327 
328            //Case insensitive and reoccurring replacement
329            attr.setValue("@TeSt1, @tEst1 never @test2; @test1, @teSt1 till ya @tesT3");  //test multiple symbols           
330            child = (javax.faces.component.html.HtmlOutputText) 
331                      facesContext.getApplication().createComponent("javax.faces.HtmlOutputText"); 
332            assertNotNull("javax.faces.HtmlOutputText", child);
333 
334            displayElement.addSymbol(createSymbol("@test1", "rock"));
335            displayElement.addSymbol(createSymbol("@test2", "stop"));
336            displayElement.addSymbol(createSymbol("@test3", "drop"));
337 
338            clayContext.setFacesContext(facesContext);
339            clayContext.setChild(child);
340            clayContext.setAttribute(attr);
341            clayContext.setDisplayElement(displayElement);
342            // normally done in the AssignChildrenCommand
343            clayContext.setSymbols(displayElement.getSymbols());
344            
345            isFinal = command.execute(clayContext);
346            assertEquals("command finished", true, isFinal);       
347            assertEquals("value = \"rock, rock never stop; rock, rock till ya drop\"", 
348                    "rock, rock never stop; rock, rock till ya drop", child.getValue());
349 
350     }
351 
352     //test component creation using symbols for component id's 
353     public void testCreateComponent()throws Exception {
354         
355         UIComponent parent = (UIComponent) 
356               facesContext.getApplication().createComponent("javax.faces.NamingContainer"); 
357         assertNotNull("javax.faces.NamingContainer", parent);
358         parent.setId("parent");
359         
360         ComponentBean displayElement = new ComponentBean();
361         displayElement.setJsfid("inputText");
362         displayElement.setComponentType("javax.faces.HtmlOutputText");
363         displayElement.setId("@wynn");
364         displayElement.addSymbol(createSymbol("@wynn", "test"));
365         
366         ClayContext clayContext = new ClayContext();
367         clayContext.setFacesContext(facesContext);
368         clayContext.setParent(parent);
369         clayContext.setDisplayElement(displayElement);
370         clayContext.setSymbols(displayElement.getSymbols());
371                 
372         Command command = new CreateComponentCommand();
373         boolean isFinal = command.execute(clayContext);
374         assertEquals("command finished", false, isFinal);
375         
376         UIComponent child = (UIComponent) clayContext.getChild();
377         assertNotNull("child", child);
378         
379         assertEquals("id = test", "test", child.getId());
380         
381         
382         //null component id symbol replacement
383         parent = (UIComponent) 
384              facesContext.getApplication().createComponent("javax.faces.NamingContainer"); 
385         assertNotNull("javax.faces.NamingContainer", parent);
386         parent.setId("parent");
387         
388         displayElement = new ComponentBean();
389         displayElement.setJsfid("inputText");
390         displayElement.setComponentType("javax.faces.HtmlOutputText");
391         displayElement.setId("@wynn");
392         displayElement.addSymbol(createSymbol("@wynn", null));
393         
394         clayContext = new ClayContext();
395         clayContext.setFacesContext(facesContext);
396         clayContext.setParent(parent);
397         clayContext.setDisplayElement(displayElement);
398         clayContext.setSymbols(displayElement.getSymbols());
399                 
400         command = new CreateComponentCommand();
401         try {
402             isFinal = command.execute(clayContext);
403             assertTrue("id replacement failed", false);
404         } catch (RuntimeException e) {
405             assertTrue("null component id", 
406                     e.getMessage().startsWith("The component symbol substitution failed for id \"@wynn\""));    
407         }
408         
409         //missing component id symbol replacement
410         parent = (UIComponent) 
411              facesContext.getApplication().createComponent("javax.faces.NamingContainer"); 
412         assertNotNull("javax.faces.NamingContainer", parent);
413         parent.setId("parent");
414         
415         displayElement = new ComponentBean();
416         displayElement.setJsfid("inputText");
417         displayElement.setComponentType("javax.faces.HtmlOutputText");
418         displayElement.setId("@wynn");
419         
420         clayContext = new ClayContext();
421         clayContext.setFacesContext(facesContext);
422         clayContext.setParent(parent);
423         clayContext.setDisplayElement(displayElement);
424         clayContext.setSymbols(displayElement.getSymbols());
425                 
426         command = new CreateComponentCommand();
427         try {
428             isFinal = command.execute(clayContext);
429             assertTrue("id replacement failed", false);
430         } catch (RuntimeException e) {
431             assertTrue("missing component id", 
432                     e.getMessage().startsWith("The component symbol substitution failed for id \"@wynn\""));    
433         }
434 
435         
436     }
437     
438  
439     public void testSymbolDelimiters() throws Exception {
440 
441         //create a target component
442         javax.faces.component.html.HtmlOutputText child = (javax.faces.component.html.HtmlOutputText) 
443                            facesContext.getApplication().createComponent("javax.faces.HtmlOutputText"); 
444         assertNotNull("javax.faces.HtmlOutputText", child);
445         
446         //setup some metadata
447         AttributeBean attr = new AttributeBean();
448         attr.setName("value");
449         attr.setBindingType(AttributeBean.BINDING_TYPE_NONE);
450         attr.setValue("@[a]@[ab]");  //symbolic attribute 
451                    
452         ComponentBean displayElement = new ComponentBean();
453         displayElement.setJsfid("inputText");
454         displayElement.setComponentType("javax.faces.HtmlOutputText");
455         displayElement.setId("testId");
456         displayElement.addAttribute(attr);
457         displayElement.addSymbol(createSymbol("@[ab]", "43"));
458         displayElement.addSymbol(createSymbol("@[a]", "67"));
459              
460         ClayContext clayContext = new ClayContext();
461         clayContext.setFacesContext(facesContext);
462         clayContext.setChild(child);
463         clayContext.setAttribute(attr);
464         clayContext.setDisplayElement(displayElement);
465         // normally done in the AssignChildrenCommand
466         clayContext.setSymbols(displayElement.getSymbols());
467                 
468         Command command = new PropertyValueCommand();
469         boolean isFinal = command.execute(clayContext);
470         assertEquals("command finished", true, isFinal);       
471         assertEquals("value = 6743", "6743", child.getValue());      
472 
473     
474         //create a target component
475         child = (javax.faces.component.html.HtmlOutputText) 
476                            facesContext.getApplication().createComponent("javax.faces.HtmlOutputText"); 
477         assertNotNull("javax.faces.HtmlOutputText", child);
478 
479         attr.setValue("@{a}@{ab}");  //symbolic attribute 
480         displayElement.addSymbol(createSymbol("@{ab}", "43"));
481         displayElement.addSymbol(createSymbol("@{a}", "67"));
482 
483         clayContext.setChild(child);
484 
485         isFinal = command.execute(clayContext);
486         assertEquals("command finished", true, isFinal);       
487         assertEquals("value = 6743", "6743", child.getValue());      
488 
489 
490         
491         //create a target component
492         child = (javax.faces.component.html.HtmlOutputText) 
493                            facesContext.getApplication().createComponent("javax.faces.HtmlOutputText"); 
494         assertNotNull("javax.faces.HtmlOutputText", child);
495 
496         attr.setValue("@(a)@(ab)");  //symbolic attribute 
497         displayElement.addSymbol(createSymbol("@(ab)", "43"));
498         displayElement.addSymbol(createSymbol("@(a)", "67"));
499 
500         clayContext.setChild(child);
501 
502         isFinal = command.execute(clayContext);
503         assertEquals("command finished", true, isFinal);       
504         assertEquals("value = 6743", "6743", child.getValue());      
505         
506         
507     }
508      
509     //test symbol inheritance
510     public void testSymbolInheritance() {
511 
512         //loads the default and the custom address config files
513         loadConfigFile("/org/apache/shale/clay/config/address-config.xml");
514           
515         // test vertical inheritance
516         ComponentBean bean = standardConfigBean.getElement("baseSymbolLabel");
517         assertNotNull(bean);
518         //look for a base symbol definition
519         SymbolBean symbol = (SymbolBean) bean.getSymbols().get("@mystyle");
520         assertNotNull(symbol);
521         assertEquals("@mystyle == color:blue", "color:blue", symbol.getValue());
522 
523         // symbol1Label extends baseSymbolLabel
524         bean = standardConfigBean.getElement("symbol1Label");
525         assertNotNull(bean);
526         //look for inherited symbol
527         symbol = (SymbolBean) bean.getSymbols().get("@mystyle");
528         assertNotNull(symbol);
529         assertEquals("@mystyle == color:blue", "color:blue", symbol.getValue());
530 
531         // symbol2Label extends symbol1Label
532         bean = standardConfigBean.getElement("symbol2Label");
533         assertNotNull(bean);
534         //look for an overridden symbol
535         symbol = (SymbolBean) bean.getSymbols().get("@mystyle");
536         assertNotNull(symbol);
537         assertEquals("@mystyle == color:red", "color:red", symbol.getValue());
538 
539         
540         //test nested/inner element inheritance
541         bean = standardConfigBean.getElement("symbolPanel");
542         assertNotNull(bean);
543         
544         assertEquals(bean.getChildren().size(), 2);
545         Iterator ei = bean.getChildrenIterator();
546         while (ei.hasNext()) {
547             ElementBean ebean = (ElementBean) ei.next();
548             if (ebean.getRenderId() == 1) {
549                 //look for inherited symbol
550                 symbol = (SymbolBean) ebean.getSymbols().get("@mystyle");
551                 assertNotNull(symbol);
552                 assertEquals("@mystyle == color:blue", "color:blue", symbol.getValue());                
553             } else if (ebean.getRenderId() == 2) {
554                 //look for an overridden symbol
555                 symbol = (SymbolBean) ebean.getSymbols().get("@mystyle");
556                 assertNotNull(symbol);
557                 assertEquals("@mystyle == color:red", "color:red", symbol.getValue());
558                 
559             }
560         }
561         
562                
563     }
564 
565     
566 }