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.configuration.event;
18  
19  import java.util.Collection;
20  
21  import junit.framework.TestCase;
22  
23  /***
24   * Test class for EventSource.
25   *
26   * @version $Id: TestEventSource.java 439648 2006-09-02 20:42:10Z oheger $
27   */
28  public class TestEventSource extends TestCase
29  {
30      /*** Constant for the event type used for testing. */
31      static final int TEST_TYPE = 42;
32  
33      /*** Constant for the event property name. */
34      static final String TEST_PROPNAME = "test.property.name";
35  
36      /*** Constant for the event property value. */
37      static final Object TEST_PROPVALUE = "a test property value";
38  
39      /*** The object under test. */
40      CountingEventSource source;
41  
42      protected void setUp() throws Exception
43      {
44          super.setUp();
45          source = new CountingEventSource();
46      }
47  
48      /***
49       * Tests a newly created source object.
50       */
51      public void testInit()
52      {
53          assertTrue("Listeners list is not empty", source
54                  .getConfigurationListeners().isEmpty());
55          assertFalse("Removing listener", source
56                  .removeConfigurationListener(new TestListener()));
57          assertFalse("Detail events are enabled", source.isDetailEvents());
58      }
59  
60      /***
61       * Tests registering a new listener.
62       */
63      public void testAddConfigurationListener()
64      {
65          TestListener l = new TestListener();
66          source.addConfigurationListener(l);
67          Collection listeners = source.getConfigurationListeners();
68          assertEquals("Wrong number of listeners", 1, listeners.size());
69          assertTrue("Listener not in list", listeners.contains(l));
70      }
71  
72      /***
73       * Tests adding an undefined configuration listener. This should cause an
74       * exception.
75       */
76      public void testAddNullConfigurationListener()
77      {
78          try
79          {
80              source.addConfigurationListener(null);
81              fail("Could add null listener!");
82          }
83          catch (IllegalArgumentException iex)
84          {
85              // ok
86          }
87      }
88  
89      /***
90       * Tests removing a listener.
91       */
92      public void testRemoveConfigurationListener()
93      {
94          TestListener l = new TestListener();
95          assertFalse("Listener can be removed?", source
96                  .removeConfigurationListener(l));
97          source.addConfigurationListener(l);
98          source.addConfigurationListener(new TestListener());
99          assertFalse("Unknown listener can be removed", source
100                 .removeConfigurationListener(new TestListener()));
101         assertTrue("Could not remove listener", source
102                 .removeConfigurationListener(l));
103         assertFalse("Listener still in list", source
104                 .getConfigurationListeners().contains(l));
105     }
106 
107     /***
108      * Tests if a null listener can be removed. This should be a no-op.
109      */
110     public void testRemoveNullConfigurationListener()
111     {
112         source.addConfigurationListener(new TestListener());
113         assertFalse("Null listener can be removed", source
114                 .removeConfigurationListener(null));
115         assertEquals("Listener list was modified", 1, source
116                 .getConfigurationListeners().size());
117     }
118 
119     /***
120      * Tests whether the listeners list is read only.
121      */
122     public void testGetConfigurationListenersUpdate()
123     {
124         source.addConfigurationListener(new TestListener());
125         Collection list = source.getConfigurationListeners();
126         try
127         {
128             list.add("test");
129             fail("Could manipulate list!");
130         }
131         catch (Exception ex)
132         {
133             // ok
134         }
135     }
136 
137     /***
138      * Tests enabling and disabling the detail events flag.
139      */
140     public void testSetDetailEvents()
141     {
142         source.setDetailEvents(true);
143         assertTrue("Detail events are disabled", source.isDetailEvents());
144         source.setDetailEvents(true);
145         source.setDetailEvents(false);
146         assertTrue("Detail events are disabled again", source.isDetailEvents());
147         source.setDetailEvents(false);
148         assertFalse("Detail events are still enabled", source.isDetailEvents());
149     }
150 
151     /***
152      * Tests delivering an event to a listener.
153      */
154     public void testFireEvent()
155     {
156         TestListener l = new TestListener();
157         source.addConfigurationListener(l);
158         source.fireEvent(TEST_TYPE, TEST_PROPNAME, TEST_PROPVALUE, true);
159         assertEquals("Not 1 event created", 1, source.eventCount);
160         assertEquals("Listener not called once", 1, l.numberOfCalls);
161         assertEquals("Wrong event type", TEST_TYPE, l.lastEvent.getType());
162         assertEquals("Wrong property name", TEST_PROPNAME, l.lastEvent
163                 .getPropertyName());
164         assertEquals("Wrong property value", TEST_PROPVALUE, l.lastEvent
165                 .getPropertyValue());
166         assertTrue("Wrong before event flag", l.lastEvent.isBeforeUpdate());
167     }
168 
169     /***
170      * Tests firering an event if there are no listeners.
171      */
172     public void testFireEventNoListeners()
173     {
174         source.fireEvent(TEST_TYPE, TEST_PROPNAME, TEST_PROPVALUE, false);
175         assertEquals("An event object was created", 0, source.eventCount);
176     }
177 
178     /***
179      * Tests generating a detail event if detail events are not allowed.
180      */
181     public void testFireEventNoDetails()
182     {
183         TestListener l = new TestListener();
184         source.addConfigurationListener(l);
185         source.setDetailEvents(false);
186         source.fireEvent(TEST_TYPE, TEST_PROPNAME, TEST_PROPVALUE, false);
187         assertEquals("Event object was created", 0, source.eventCount);
188         assertEquals("Listener was called", 0, l.numberOfCalls);
189     }
190 
191     /***
192      * Tests whether an event listener can deregister itself in reaction of a
193      * delivered event.
194      */
195     public void testRemoveListenerInFireEvent()
196     {
197         ConfigurationListener lstRemove = new ConfigurationListener()
198         {
199             public void configurationChanged(ConfigurationEvent event)
200             {
201                 source.removeConfigurationListener(this);
202             }
203         };
204 
205         source.addConfigurationListener(lstRemove);
206         TestListener l = new TestListener();
207         source.addConfigurationListener(l);
208         source.fireEvent(TEST_TYPE, TEST_PROPNAME, TEST_PROPVALUE, false);
209         assertEquals("Listener was not called", 1, l.numberOfCalls);
210         assertEquals("Listener was not removed", 1, source
211                 .getConfigurationListeners().size());
212     }
213 
214     /***
215      * A test event listener implementation.
216      */
217     static class TestListener implements ConfigurationListener
218     {
219         ConfigurationEvent lastEvent;
220 
221         int numberOfCalls;
222 
223         public void configurationChanged(ConfigurationEvent event)
224         {
225             lastEvent = event;
226             numberOfCalls++;
227         }
228     }
229 
230     /***
231      * A specialized event source implementation that counts the number of
232      * created event objects. It is used to test whether the
233      * <code>fireEvent()</code> methods only creates event objects if
234      * necessary.
235      */
236     static class CountingEventSource extends EventSource
237     {
238         int eventCount;
239 
240         protected ConfigurationEvent createEvent(int type, String propName,
241                 Object propValue, boolean before)
242         {
243             eventCount++;
244             return super.createEvent(type, propName, propValue, before);
245         }
246     }
247 }