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.myfaces.trinidad.bean;
20  
21  import java.io.ByteArrayInputStream;
22  import java.io.ByteArrayOutputStream;
23  import java.io.IOException;
24  import java.io.ObjectInputStream;
25  import java.io.ObjectOutputStream;
26  
27  import java.util.Iterator;
28  
29  import javax.faces.el.ValueBinding;
30  
31  import org.apache.myfaces.trinidad.bean.PropertyKey;
32  import org.apache.myfaces.trinidad.context.MockRequestContext;
33  
34  import junit.framework.Test;
35  import junit.framework.TestCase;
36  import junit.framework.TestSuite;
37  
38  public class FacesBeanImplTest extends TestCase
39  {
40    public static final Test suite()
41    {
42      return new TestSuite(FacesBeanImplTest.class);
43    }
44  
45    public static void main(String[] args) throws Throwable
46    {
47      junit.textui.TestRunner.run(suite());
48    }
49  
50    public FacesBeanImplTest(
51      String testName)
52    {
53      super(testName);
54    }
55  
56  
57    private MockRequestContext _mafct;
58  
59    @Override
60    public void setUp() throws Exception
61    {
62      super.setUp();
63      _mafct = new MockRequestContext();
64    }
65  
66    @Override
67    public void tearDown() throws Exception
68    {
69      _mafct.release();
70      _mafct = null;
71      super.tearDown();
72    }
73  
74    public void testInitialValues()
75    {
76      TestBean bean = new TestBean();
77      assertNull(bean.getFirst());
78      assertNull(bean.getSecond());
79    }
80  
81    public void testSubclass()
82    {
83      SubTypeBean bean = new SubTypeBean();
84      assertNull(bean.getFirst());
85      assertNull(bean.getSecond());
86      assertNull(bean.getSub());
87      bean.setSub("sub");
88      assertEquals("sub", bean.getSub());
89    }
90  
91    public void testSetValues()
92    {
93      TestBean bean = new TestBean();
94      bean.setFirst("first");
95      bean.setSecond("second");
96      assertEquals(bean.getFirst(), "first");
97      assertEquals(bean.getSecond(), "second");
98  
99      bean.setFirst(null);
100     bean.setSecond(null);
101 
102     assertNull(bean.getFirst());
103     assertNull(bean.getSecond());
104 
105     bean.setSecond("newSecond");
106     assertEquals(bean.getSecond(), "newSecond");
107     assertEquals(bean.getProperty(TestBean.SECOND_KEY), "newSecond");
108     assertEquals(bean.getLocalProperty(TestBean.SECOND_KEY), "newSecond");
109 
110     bean.setProperty(TestBean.FIRST_KEY, "newFirst");
111     assertEquals(bean.getFirst(), "newFirst");
112   }
113 
114   public void testAliases()
115   {
116     TestBean bean = new TestBean();
117     bean.setFirstAlias("alias");
118     assertEquals("alias", bean.getFirst());
119     assertEquals("alias", bean.getFirstAlias());
120 
121     bean = new TestBean();
122     bean.setFirst("alias2");
123     assertEquals("alias2", bean.getFirst());
124     assertEquals("alias2", bean.getFirstAlias());
125   }
126 
127   public void testAnonymousKeys()
128   {
129     // Create an anonymous key
130     PropertyKey thirdKey = new PropertyKey("third");
131     TestBean bean = new TestBean();
132     bean.setFirst("first");
133     bean.setSecond("second");
134     bean.setProperty(thirdKey, "third");
135     assertEquals(bean.getFirst(), "first");
136     assertEquals(bean.getSecond(), "second");
137     assertEquals(bean.getProperty(thirdKey), "third");
138 
139     PropertyKey extraInstance = new PropertyKey("third");
140     assertEquals(bean.getProperty(thirdKey),
141                  bean.getProperty(extraInstance));
142   }
143 
144 
145   public void testBindingNotAllowed()
146   {
147     TestBean bean = new TestBean();
148     try
149     {
150       bean.setValueBinding(TestBean.CANT_BE_BOUND_KEY,
151                            new TestValueBinding());
152       fail();
153     }
154     catch (IllegalArgumentException e)
155     {
156     }
157   }
158 
159 
160 
161   public void testBindings()
162   {
163     TestBean bean = new TestBean();
164     TestValueBinding vb1 = new TestValueBinding();
165     vb1.setValue(null, "vbFirst");
166     bean.setValueBinding(TestBean.FIRST_KEY, vb1);
167 
168     assertSame(bean.getValueBinding(TestBean.FIRST_KEY), vb1);
169 
170     assertEquals("vbFirst", bean.getFirst());
171 
172     bean.setFirst("first");
173     assertEquals("first", bean.getFirst());
174 
175     bean.setFirst(null);
176     assertEquals("vbFirst", bean.getFirst());
177   }
178 
179   public void testSets()
180   {
181     TestBean bean = new TestBean();
182     assertTrue(bean.keySet().isEmpty());
183     assertTrue(bean.bindingKeySet().isEmpty());
184 
185     bean.setFirst("first");
186     bean.setSecond("second");
187 
188     assertEquals(2, bean.keySet().size());
189 
190     bean.setSecond("newSecond");
191 
192     assertEquals(2, bean.keySet().size());
193 
194     bean.setSecond(null);
195 
196     // This test is somewhat dubious...
197     assertEquals(1, bean.keySet().size());
198 
199     // Create an anonymous key
200     PropertyKey thirdKey = new PropertyKey("third");
201 
202     bean.setValueBinding(TestBean.FIRST_KEY, new TestValueBinding());
203     assertEquals(1, bean.bindingKeySet().size());
204 
205     bean.setValueBinding(TestBean.FIRST_KEY, new TestValueBinding());
206     assertEquals(1, bean.bindingKeySet().size());
207 
208     bean.setValueBinding(thirdKey, new TestValueBinding());
209     assertEquals(2, bean.bindingKeySet().size());
210 
211     assertTrue(bean.bindingKeySet().contains(thirdKey));
212     assertTrue(bean.bindingKeySet().contains(TestBean.FIRST_KEY));
213     assertTrue(!bean.bindingKeySet().contains(TestBean.SECOND_KEY));
214   }
215 
216   public void testLists()
217   {
218     TestBean bean = new TestBean();
219     Iterator<Object> iterator = bean.items();
220     assertTrue(!iterator.hasNext());
221     Integer[] array = bean.getItems();
222     assertNotNull(array);
223     assertEquals(0, array.length);
224 
225     bean.addItem(new Integer(1));
226     assertEquals(1, bean.getItems().length);
227 
228     bean.addItem(new Integer(2));
229     assertEquals(2, bean.getItems().length);
230 
231     array = bean.getItems();
232     assertEquals(array[0], new Integer(1));
233     assertEquals(array[1], new Integer(2));
234 
235     // Verify that this is a *list*, not a Set, so adding the
236     // same value twice works as expected
237     bean.addItem(new Integer(2));
238     assertEquals(3, bean.getItems().length);
239     bean.removeItem(new Integer(2));
240 
241     iterator = bean.items();
242     assertEquals(new Integer(1), iterator.next());
243     assertEquals(new Integer(2), iterator.next());
244     assertTrue(!iterator.hasNext());
245 
246     assertTrue(bean.containsEntry(TestBean.ITEMS_KEY, Number.class));
247     assertTrue(bean.containsEntry(TestBean.ITEMS_KEY, Integer.class));
248     assertTrue(!bean.containsEntry(TestBean.ITEMS_KEY, Long.class));
249 
250     bean.removeItem(new Integer(1));
251     bean.removeItem(new Integer(2));
252 
253     iterator = bean.items();
254     assertTrue(!iterator.hasNext());
255     array = bean.getItems();
256     assertNotNull(array);
257     assertEquals(0, array.length);
258 
259     // List items cannot be set, bound, or retrieved
260     try
261     {
262       bean.setProperty(TestBean.ITEMS_KEY, "Shouldn't work");
263       fail();
264     }
265     catch (IllegalArgumentException iae)
266     {
267       // expected
268     }
269 
270 
271     try
272     {
273       bean.getProperty(TestBean.ITEMS_KEY);
274       fail();
275     }
276     catch (IllegalArgumentException iae)
277     {
278       // expected
279     }
280 
281     try
282     {
283       bean.getLocalProperty(TestBean.ITEMS_KEY);
284       fail();
285     }
286     catch (IllegalArgumentException iae)
287     {
288       // expected
289     }
290 
291     try
292     {
293       bean.setValueBinding(TestBean.ITEMS_KEY, new TestValueBinding());
294       fail();
295     }
296     catch (IllegalArgumentException iae)
297     {
298       // expected
299     }
300 
301     // Meanwhile, you can't use the list APIs for non-list keys
302     try
303     {
304       bean.addEntry(TestBean.FIRST_KEY, null);
305       fail();
306     }
307     catch (IllegalArgumentException iae)
308     {
309       // expected
310     }
311 
312     try
313     {
314       bean.addEntry(TestBean.FIRST_KEY, null);
315       fail();
316     }
317     catch (IllegalArgumentException iae)
318     {
319       // expected
320     }
321 
322     try
323     {
324       bean.removeEntry(TestBean.FIRST_KEY, null);
325       fail();
326     }
327     catch (IllegalArgumentException iae)
328     {
329       // expected
330     }
331 
332     try
333     {
334       bean.getEntries(TestBean.FIRST_KEY, Object.class);
335       fail();
336     }
337     catch (IllegalArgumentException iae)
338     {
339       // expected
340     }
341 
342     try
343     {
344       bean.entries(TestBean.FIRST_KEY);
345       fail();
346     }
347     catch (IllegalArgumentException iae)
348     {
349       // expected
350     }
351   }
352 
353   public void testTypeLocked()
354   {
355     try
356     {
357       TestBean.TYPE.registerKey("ShouldntWork");
358       fail();
359     }
360     catch (IllegalStateException ise)
361     {
362     }
363   }
364 
365   public void testAddAll()
366   {
367     TestBean bean = new TestBean();
368     bean.setFirst("first");
369     TestValueBinding binding = new TestValueBinding();
370     binding.setValue(null, "FirstBinding");
371     bean.setValueBinding(TestBean.FIRST_KEY, binding);
372     bean.setSecond("second");
373     bean.setProperty(new PropertyKey("sub"), "subValue");
374     bean.addItem(new Integer(1));
375     bean.addItem(new Integer(2));
376 
377     SubTypeBean sub = new SubTypeBean();
378     sub.setSecond("third");
379     sub.addAll(bean);
380 
381     assertEquals("first", sub.getFirst());
382     assertEquals("second", sub.getSecond());
383     assertEquals("subValue", sub.getSub());
384     assertNotNull(sub.getValueBinding(TestBean.FIRST_KEY));
385     assertEquals("FirstBinding",
386                  sub.getValueBinding(TestBean.FIRST_KEY).getValue(null));
387     Integer[] items = sub.getItems();
388     assertNotNull(items);
389     assertEquals(2, items.length);
390     assertEquals(new Integer(1), items[0]);
391     assertEquals(new Integer(2), items[1]);
392 
393     TestBean andBackAgain = new TestBean();
394     andBackAgain.addAll(sub);
395     assertEquals("subValue",
396                  andBackAgain.getLocalProperty(new PropertyKey("sub")));
397   }
398 
399   public void testStateSaveAndRestore()
400   {
401     // Build a bean
402     SubTypeBean bean = new SubTypeBean();
403     TestValueBinding vb1 = new TestValueBinding();
404     vb1.setValue(null, "vbFirst");
405     bean.setValueBinding(SubTypeBean.FIRST_KEY, vb1);
406     bean.setSecond("second");
407     bean.setTransient("Won't be there");
408     bean.setSub("sub");
409     bean.addItem(new Integer(1));
410     bean.addItem(new Integer(2));
411 
412     SillyStateHolder silly = new SillyStateHolder();
413     bean.setProperty(SubTypeBean.SILLY_KEY, silly);
414 
415     assertEquals("0", silly.toString());
416 
417     // Save its state
418     Object savedState = bean.saveState(null);
419     assertNotNull(savedState);
420 
421     try
422     {
423       savedState = _copyObjectThroughSerialization(savedState);
424     }
425     catch (Exception e)
426     {
427       e.printStackTrace();
428       fail();
429     }
430 
431     // Verify that our "silly" object has had its state saved
432     assertEquals("1", silly.toString());
433 
434     // Build a new bean, and restore its state
435     SubTypeBean newBean = new SubTypeBean();
436     newBean.restoreState(null, savedState);
437 
438     // Verify it looks like the old bean
439     assertEquals("vbFirst", newBean.getFirst());
440     assertNull(newBean.getLocalProperty(SubTypeBean.FIRST_KEY));
441     assertEquals("second", newBean.getSecond());
442     assertNull(newBean.getValueBinding(SubTypeBean.SECOND_KEY));
443     assertEquals("sub", newBean.getSub());
444 
445     // Verify that our "silly" object has had its state restored
446     assertEquals("2", newBean.getProperty(SubTypeBean.SILLY_KEY).toString());
447 
448     Integer[] array = newBean.getItems();
449     assertEquals(2, array.length);
450     assertEquals(new Integer(1), array[0]);
451     assertEquals(new Integer(2), array[1]);
452 
453 
454     // Make sure the transient value is now null
455     assertNull(newBean.getTransient());
456 
457     // Make sure the value binding looks the same, but is
458     // not actually the same instance
459     ValueBinding vb = newBean.getValueBinding(SubTypeBean.FIRST_KEY);
460     assertTrue(vb instanceof TestValueBinding);
461     assertTrue(vb != vb1);
462     assertEquals(vb.getValue(null), "vbFirst");
463 
464     // Now change the value binding, and verify the original
465     // bean is unchanged
466     vb.setValue(null, "changedVB");
467     assertEquals("changedVB", newBean.getFirst());
468     assertEquals("vbFirst", bean.getFirst());
469 
470     // Now, verify that if we mark the initial state and save, that we get
471     // a non-null value
472     newBean.markInitialState();
473     assertNull(newBean.saveState(null));
474 
475     // Now, we'll set a value, so we should get a non-null state
476 
477     // Our current delta support *does not* keep track of the original value.
478     // If it does, add this test
479     // String oldFirst = newBean.getFirst();
480     newBean.setFirst("foo");
481     assertNotNull(newBean.saveState(null));
482 
483     // Our current delta support *does not* keep track of the original value.
484     // If it does, add this test
485 //    newBean.setFirst(oldFirst);
486 //    assertNull(newBean.saveState(null));
487   }
488 
489   static private Object _copyObjectThroughSerialization(Object o)
490     throws IOException, ClassNotFoundException
491   {
492     ByteArrayOutputStream bos = new ByteArrayOutputStream();
493     ObjectOutputStream oos = new ObjectOutputStream(bos);
494     oos.writeObject(o);
495     oos.close();
496 
497     byte[] byteArray = bos.toByteArray();
498     ByteArrayInputStream bis = new ByteArrayInputStream(byteArray);
499     ObjectInputStream ois = new ObjectInputStream(bis);
500 
501     return ois.readObject();
502   }
503 
504   // -= Simon Lessard =-
505   // Never read locally as of 2006-08-09
506   //private PropertyKey _thirdKey;
507 }