1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.configuration;
19
20 import java.io.File;
21 import java.io.FileWriter;
22 import java.io.IOException;
23 import java.io.PrintWriter;
24 import java.util.ArrayList;
25 import java.util.Iterator;
26 import java.util.List;
27 import java.util.NoSuchElementException;
28 import java.util.Collection;
29
30 import org.apache.commons.configuration.event.ConfigurationEvent;
31 import org.apache.commons.configuration.event.ConfigurationListener;
32 import org.apache.commons.configuration.reloading.FileAlwaysReloadingStrategy;
33
34 import junit.framework.TestCase;
35
36 /***
37 * Test loading multiple configurations.
38 *
39 * @version $Id: TestCompositeConfiguration.java 541932 2007-05-26 19:30:54Z oheger $
40 */
41 public class TestCompositeConfiguration extends TestCase
42 {
43 /*** Constant for a test property to be checked.*/
44 private static final String TEST_PROPERTY = "test.source.property";
45
46 protected PropertiesConfiguration conf1;
47 protected PropertiesConfiguration conf2;
48 protected XMLConfiguration xmlConf;
49 protected CompositeConfiguration cc;
50
51 /***
52 * The File that we test with
53 */
54 private String testProperties = new File("conf/test.properties").getAbsolutePath();
55 private String testProperties2 = new File("conf/test2.properties").getAbsolutePath();
56 private String testPropertiesXML = new File("conf/test.xml").getAbsolutePath();
57
58 protected void setUp() throws Exception
59 {
60 cc = new CompositeConfiguration();
61 conf1 = new PropertiesConfiguration(testProperties);
62 conf2 = new PropertiesConfiguration(testProperties2);
63 xmlConf = new XMLConfiguration(new File(testPropertiesXML));
64
65 cc.setThrowExceptionOnMissing(true);
66 }
67
68 public void testThrowExceptionOnMissing()
69 {
70 assertTrue("Throw Exception Property is not set!", cc.isThrowExceptionOnMissing());
71 }
72
73 public void testAddRemoveConfigurations() throws Exception
74 {
75 cc.addConfiguration(conf1);
76 assertEquals("Number of configurations", 2, cc.getNumberOfConfigurations());
77 cc.addConfiguration(conf1);
78 assertEquals("Number of configurations", 2, cc.getNumberOfConfigurations());
79 cc.addConfiguration(conf2);
80 assertEquals("Number of configurations", 3, cc.getNumberOfConfigurations());
81 cc.removeConfiguration(conf1);
82 assertEquals("Number of configurations", 2, cc.getNumberOfConfigurations());
83 cc.clear();
84 assertEquals("Number of configurations", 1, cc.getNumberOfConfigurations());
85 }
86
87 public void testGetPropertyWIncludes() throws Exception
88 {
89 cc.addConfiguration(conf1);
90 cc.addConfiguration(conf2);
91 List l = cc.getList("packages");
92 assertTrue(l.contains("packagea"));
93 }
94
95 public void testGetProperty() throws Exception
96 {
97 cc.addConfiguration(conf1);
98 cc.addConfiguration(conf2);
99 assertEquals("Make sure we get the property from conf1 first", "test.properties", cc.getString("propertyInOrder"));
100 cc.clear();
101
102 cc.addConfiguration(conf2);
103 cc.addConfiguration(conf1);
104 assertEquals("Make sure we get the property from conf2 first", "test2.properties", cc.getString("propertyInOrder"));
105 }
106
107 public void testCantRemoveMemoryConfig() throws Exception
108 {
109 cc.clear();
110 assertEquals(1, cc.getNumberOfConfigurations());
111
112 Configuration internal = cc.getConfiguration(0);
113 cc.removeConfiguration(internal);
114
115 assertEquals(1, cc.getNumberOfConfigurations());
116 }
117
118 public void testGetPropertyMissing() throws Exception
119 {
120 cc.addConfiguration(conf1);
121 cc.addConfiguration(conf2);
122 try
123 {
124 assertNull(cc.getString("bogus.property"));
125 fail("Should have thrown a NoSuchElementException");
126 }
127 catch (NoSuchElementException nsee)
128 {
129 assertTrue(nsee.getMessage().indexOf("bogus.property") > -1);
130 }
131
132 assertTrue("Should be false", !cc.getBoolean("test.missing.boolean", false));
133 assertTrue("Should be true", cc.getBoolean("test.missing.boolean.true", true));
134 }
135
136 /***
137 * Tests <code>List</code> parsing.
138 */
139 public void testMultipleTypesOfConfigs() throws Exception
140 {
141 cc.addConfiguration(conf1);
142 cc.addConfiguration(xmlConf);
143 assertEquals("Make sure we get the property from conf1 first", 1, cc.getInt("test.short"));
144 cc.clear();
145
146 cc.addConfiguration(xmlConf);
147 cc.addConfiguration(conf1);
148 assertEquals("Make sure we get the property from xml", 8, cc.getInt("test.short"));
149 }
150
151 /***
152 * Tests <code>List</code> parsing.
153 */
154 public void testPropertyExistsInOnlyOneConfig() throws Exception
155 {
156 cc.addConfiguration(conf1);
157 cc.addConfiguration(xmlConf);
158 assertEquals("value", cc.getString("element"));
159 }
160
161 /***
162 * Tests getting a default when the key doesn't exist
163 */
164 public void testDefaultValueWhenKeyMissing() throws Exception
165 {
166 cc.addConfiguration(conf1);
167 cc.addConfiguration(xmlConf);
168 assertEquals("default", cc.getString("bogus", "default"));
169 assertTrue(1.4 == cc.getDouble("bogus", 1.4));
170 assertTrue(1.4 == cc.getDouble("bogus", 1.4));
171 }
172
173 /***
174 * Tests <code>List</code> parsing.
175 */
176 public void testGettingConfiguration() throws Exception
177 {
178 cc.addConfiguration(conf1);
179 cc.addConfiguration(xmlConf);
180 assertEquals(PropertiesConfiguration.class, cc.getConfiguration(0).getClass());
181 assertEquals(XMLConfiguration.class, cc.getConfiguration(1).getClass());
182 }
183
184 /***
185 * Tests setting values. These are set in memory mode only!
186 */
187 public void testClearingProperty() throws Exception
188 {
189 cc.addConfiguration(conf1);
190 cc.addConfiguration(xmlConf);
191 cc.clearProperty("test.short");
192 assertTrue("Make sure test.short is gone!", !cc.containsKey("test.short"));
193 }
194
195 /***
196 * Tests adding values. Make sure they _DON'T_ override any other properties but add to the
197 * existing properties and keep sequence
198 */
199 public void testAddingProperty() throws Exception
200 {
201 cc.addConfiguration(conf1);
202 cc.addConfiguration(xmlConf);
203
204 String[] values = cc.getStringArray("test.short");
205
206 assertEquals("Number of values before add is wrong!", 1, values.length);
207 assertEquals("First Value before add is wrong", "1", values[0]);
208
209 cc.addProperty("test.short", "88");
210
211 values = cc.getStringArray("test.short");
212
213 assertEquals("Number of values is wrong!", 2, values.length);
214 assertEquals("First Value is wrong", "1", values[0]);
215 assertEquals("Third Value is wrong", "88", values[1]);
216 }
217
218 /***
219 * Tests setting values. These are set in memory mode only!
220 */
221 public void testSettingMissingProperty() throws Exception
222 {
223 cc.addConfiguration(conf1);
224 cc.addConfiguration(xmlConf);
225 cc.setProperty("my.new.property", "supernew");
226 assertEquals("supernew", cc.getString("my.new.property"));
227 }
228
229 /***
230 * Tests retrieving subsets of configurations
231 */
232 public void testGettingSubset() throws Exception
233 {
234 cc.addConfiguration(conf1);
235 cc.addConfiguration(xmlConf);
236
237 Configuration subset = cc.subset("test");
238 assertNotNull(subset);
239 assertFalse("Shouldn't be empty", subset.isEmpty());
240 assertEquals("Make sure the initial loaded configs subset overrides any later add configs subset", "1", subset.getString("short"));
241
242 cc.setProperty("test.short", "43");
243 subset = cc.subset("test");
244 assertEquals("Make sure the initial loaded configs subset overrides any later add configs subset", "43", subset.getString("short"));
245 }
246
247 /***
248 * Tests subsets and still can resolve elements
249 */
250 public void testSubsetCanResolve() throws Exception
251 {
252 cc = new CompositeConfiguration();
253 final BaseConfiguration config = new BaseConfiguration();
254 config.addProperty("subset.tempfile", "${java.io.tmpdir}/file.tmp");
255 cc.addConfiguration(config);
256 cc.addConfiguration(ConfigurationConverter.getConfiguration(System.getProperties()));
257
258 Configuration subset = cc.subset("subset");
259 assertEquals(System.getProperty("java.io.tmpdir") + "/file.tmp", subset.getString("tempfile"));
260 }
261
262 /***
263 * Tests <code>List</code> parsing.
264 */
265 public void testList() throws Exception
266 {
267 cc.addConfiguration(conf1);
268 cc.addConfiguration(xmlConf);
269
270 List packages = cc.getList("packages");
271
272 assertEquals(3, packages.size());
273
274 List defaultList = new ArrayList();
275 defaultList.add("1");
276 defaultList.add("2");
277
278 packages = cc.getList("packages.which.dont.exist", defaultList);
279
280 assertEquals(2, packages.size());
281
282 }
283
284 /***
285 * Tests <code>String</code> array parsing.
286 */
287 public void testStringArray() throws Exception
288 {
289 cc.addConfiguration(conf1);
290 cc.addConfiguration(xmlConf);
291
292 String[] packages = cc.getStringArray("packages");
293
294 assertEquals(3, packages.length);
295
296 packages = cc.getStringArray("packages.which.dont.exist");
297
298 assertEquals(0, packages.length);
299 }
300
301 public void testGetList()
302 {
303 Configuration conf1 = new BaseConfiguration();
304 conf1.addProperty("array", "value1");
305 conf1.addProperty("array", "value2");
306
307 Configuration conf2 = new BaseConfiguration();
308 conf2.addProperty("array", "value3");
309 conf2.addProperty("array", "value4");
310
311 cc.addConfiguration(conf1);
312 cc.addConfiguration(conf2);
313
314
315 List list = cc.getList("array");
316 assertNotNull("null list", list);
317 assertEquals("list size", 2, list.size());
318 assertTrue("'value1' not found in the list", list.contains("value1"));
319 assertTrue("'value2' not found in the list", list.contains("value2"));
320
321
322 cc.addProperty("array", "value5");
323
324
325 list = cc.getList("array");
326 assertNotNull("null list", list);
327 assertEquals("list size", 3, list.size());
328 assertTrue("'value1' not found in the list", list.contains("value1"));
329 assertTrue("'value2' not found in the list", list.contains("value2"));
330 assertTrue("'value5' not found in the list", list.contains("value5"));
331 }
332
333 /***
334 * Tests <code>getKeys</code> preserves the order
335 */
336 public void testGetKeysPreservesOrder() throws Exception
337 {
338 cc.addConfiguration(conf1);
339 List orderedList = new ArrayList();
340 for (Iterator keys = conf1.getKeys(); keys.hasNext();)
341 {
342 orderedList.add(keys.next());
343 }
344 List iteratedList = new ArrayList();
345 for (Iterator keys = cc.getKeys(); keys.hasNext();)
346 {
347 iteratedList.add(keys.next());
348 }
349 assertEquals(orderedList.size(), iteratedList.size());
350 for (int i = 0; i < orderedList.size(); i++)
351 {
352 assertEquals(orderedList.get(i), iteratedList.get(i));
353 }
354 }
355
356 /***
357 * Tests <code>getKeys(String key)</code> preserves the order
358 */
359 public void testGetKeys2PreservesOrder() throws Exception
360 {
361 cc.addConfiguration(conf1);
362 List orderedList = new ArrayList();
363 for (Iterator keys = conf1.getKeys("test"); keys.hasNext();)
364 {
365 orderedList.add(keys.next());
366 }
367 List iteratedList = new ArrayList();
368 for (Iterator keys = cc.getKeys("test"); keys.hasNext();)
369 {
370 iteratedList.add(keys.next());
371 }
372 assertEquals(orderedList.size(), iteratedList.size());
373 for (int i = 0; i < orderedList.size(); i++)
374 {
375 assertEquals(orderedList.get(i), iteratedList.get(i));
376 }
377 }
378
379 public void testGetStringWithDefaults()
380 {
381 BaseConfiguration defaults = new BaseConfiguration();
382 defaults.addProperty("default", "default string");
383
384 CompositeConfiguration c = new CompositeConfiguration(defaults);
385 c.setThrowExceptionOnMissing(cc.isThrowExceptionOnMissing());
386 c.addProperty("string", "test string");
387
388 assertEquals("test string", c.getString("string"));
389 try
390 {
391 c.getString("XXX");
392 fail("Should throw NoSuchElementException exception");
393 }
394 catch (NoSuchElementException e)
395 {
396
397 }
398 catch (Exception e)
399 {
400 fail("Should throw NoSuchElementException exception, not " + e);
401 }
402
403
404 assertEquals("test string", c.getString("string", "some default value"));
405 assertEquals("default string", c.getString("default"));
406 assertEquals("default string", c.getString("default", "some default value"));
407 assertEquals("some default value", c.getString("XXX", "some default value"));
408 }
409
410 public void testCheckingInMemoryConfiguration() throws Exception
411 {
412 String TEST_KEY = "testKey";
413 Configuration defaults = new PropertiesConfiguration();
414 defaults.setProperty(TEST_KEY, "testValue");
415 Configuration testConfiguration = new CompositeConfiguration(defaults);
416 assertTrue(testConfiguration.containsKey(TEST_KEY));
417 assertFalse(testConfiguration.isEmpty());
418 boolean foundTestKey = false;
419 Iterator i = testConfiguration.getKeys();
420
421
422
423 for (; i.hasNext();)
424 {
425 String key = (String) i.next();
426 if (key.equals(TEST_KEY))
427 {
428 foundTestKey = true;
429 }
430 }
431 assertTrue(foundTestKey);
432 testConfiguration.clearProperty(TEST_KEY);
433 assertFalse(testConfiguration.containsKey(TEST_KEY));
434 }
435
436 public void testStringArrayInterpolation()
437 {
438 CompositeConfiguration config = new CompositeConfiguration();
439 config.addProperty("base", "foo");
440 config.addProperty("list", "${base}.bar1");
441 config.addProperty("list", "${base}.bar2");
442 config.addProperty("list", "${base}.bar3");
443
444 String[] array = config.getStringArray("list");
445 assertEquals("size", 3, array.length);
446 assertEquals("1st element", "foo.bar1", array[0]);
447 assertEquals("2nd element", "foo.bar2", array[1]);
448 assertEquals("3rd element", "foo.bar3", array[2]);
449 }
450
451 /***
452 * Tests whether global interpolation works with lists.
453 */
454 public void testListInterpolation()
455 {
456 PropertiesConfiguration c1 = new PropertiesConfiguration();
457 c1.addProperty("c1.value", "test1");
458 c1.addProperty("c1.value", "${c2.value}");
459 cc.addConfiguration(c1);
460 PropertiesConfiguration c2 = new PropertiesConfiguration();
461 c2.addProperty("c2.value", "test2");
462 cc.addConfiguration(c2);
463 List lst = cc.getList("c1.value");
464 assertEquals("Wrong list size", 2, lst.size());
465 assertEquals("Wrong first element", "test1", lst.get(0));
466 assertEquals("Wrong second element", "test2", lst.get(1));
467 }
468
469 /***
470 * Tests interpolation in combination with reloading.
471 */
472 public void testInterpolationWithReload() throws IOException,
473 ConfigurationException
474 {
475 File testFile = new File("target/testConfig.properties");
476 final String propFirst = "first.name";
477 final String propFull = "full.name";
478
479 try
480 {
481 writeTestConfig(testFile, propFirst, "John");
482 PropertiesConfiguration c1 = new PropertiesConfiguration(testFile);
483 c1.setReloadingStrategy(new FileAlwaysReloadingStrategy());
484 PropertiesConfiguration c2 = new PropertiesConfiguration();
485 c2.addProperty(propFull, "${" + propFirst + "} Doe");
486 CompositeConfiguration cc = new CompositeConfiguration();
487 cc.addConfiguration(c1);
488 cc.addConfiguration(c2);
489 assertEquals("Wrong name", "John Doe", cc.getString(propFull));
490
491 writeTestConfig(testFile, propFirst, "Jane");
492 assertEquals("First name not changed", "Jane", c1
493 .getString(propFirst));
494 assertEquals("First name not changed in composite", "Jane", cc
495 .getString(propFirst));
496 assertEquals("Full name not changed", "Jane Doe", cc
497 .getString(propFull));
498 }
499 finally
500 {
501 if (testFile.exists())
502 {
503 testFile.delete();
504 }
505 }
506 }
507
508 /***
509 * Writes a test properties file containing a single property definition.
510 *
511 * @param f the file to write
512 * @param prop the property name
513 * @param value the property value
514 * @throws IOException if an error occurs
515 */
516 private void writeTestConfig(File f, String prop, String value)
517 throws IOException
518 {
519 PrintWriter out = new PrintWriter(new FileWriter(f));
520 out.print(prop);
521 out.print("=");
522 out.println(value);
523 out.close();
524 }
525
526 public void testInstanciateWithCollection()
527 {
528 Collection configs = new ArrayList();
529 configs.add(xmlConf);
530 configs.add(conf1);
531 configs.add(conf2);
532
533 CompositeConfiguration config = new CompositeConfiguration(configs);
534 assertEquals("Number of configurations", 4, config.getNumberOfConfigurations());
535 assertTrue("The in memory configuration is not empty", config.getInMemoryConfiguration().isEmpty());
536 }
537
538 public void testClone()
539 {
540 CompositeConfiguration cc2 = (CompositeConfiguration) cc.clone();
541 assertEquals("Wrong number of contained configurations", cc
542 .getNumberOfConfigurations(), cc2.getNumberOfConfigurations());
543
544 StrictConfigurationComparator comp = new StrictConfigurationComparator();
545 for (int i = 0; i < cc.getNumberOfConfigurations(); i++)
546 {
547 assertEquals("Wrong configuration class at " + i, cc
548 .getConfiguration(i).getClass(), cc2.getConfiguration(i)
549 .getClass());
550 assertNotSame("Configuration was not cloned", cc
551 .getConfiguration(i), cc2.getConfiguration(i));
552 assertTrue("Configurations at " + i + " not equal", comp.compare(cc
553 .getConfiguration(i), cc2.getConfiguration(i)));
554 }
555
556 assertTrue("Configurations are not equal", comp.compare(cc, cc2));
557 }
558
559 /***
560 * Tests cloning if one of the contained configurations does not support
561 * this operation. This should cause an exception.
562 */
563 public void testCloneNotSupported()
564 {
565 cc.addConfiguration(new NonCloneableConfiguration());
566 try
567 {
568 cc.clone();
569 fail("Could clone non cloneable configuration!");
570 }
571 catch (ConfigurationRuntimeException crex)
572 {
573
574 }
575 }
576
577 /***
578 * Ensures that event listeners are not cloned.
579 */
580 public void testCloneEventListener()
581 {
582 cc.addConfigurationListener(new TestEventListenerImpl());
583 CompositeConfiguration cc2 = (CompositeConfiguration) cc.clone();
584 assertTrue("Listeners have been cloned", cc2
585 .getConfigurationListeners().isEmpty());
586 }
587
588 /***
589 * Tests whether add property events are triggered.
590 */
591 public void testEventAddProperty()
592 {
593 TestEventListenerImpl l = new TestEventListenerImpl();
594 cc.addConfigurationListener(l);
595 cc.addProperty("test", "value");
596 assertEquals("No add events received", 2, l.eventCount);
597 }
598
599 /***
600 * Tests whether set property events are triggered.
601 */
602 public void testEventSetProperty()
603 {
604 TestEventListenerImpl l = new TestEventListenerImpl();
605 cc.addConfigurationListener(l);
606 cc.setProperty("test", "value");
607 assertEquals("No set events received", 2, l.eventCount);
608 }
609
610 /***
611 * Tests whether clear property events are triggered.
612 */
613 public void testEventClearProperty()
614 {
615 cc.addConfiguration(conf1);
616 assertTrue("Wrong value for property", cc
617 .getBoolean("configuration.loaded"));
618 TestEventListenerImpl l = new TestEventListenerImpl();
619 cc.addConfigurationListener(l);
620 cc.clearProperty("configuration.loaded");
621 assertFalse("Key still present", cc.containsKey("configuration.loaded"));
622 assertEquals("No clear events received", 2, l.eventCount);
623 }
624
625 /***
626 * Tests chaning the list delimiter character.
627 */
628 public void testSetListDelimiter()
629 {
630 cc.setListDelimiter('/');
631 checkSetListDelimiter();
632 }
633
634 /***
635 * Tests whether the correct list delimiter is set after a clear operation.
636 */
637 public void testSetListDelimiterAfterClear()
638 {
639 cc.setListDelimiter('/');
640 cc.clear();
641 checkSetListDelimiter();
642 }
643
644 /***
645 * Helper method for testing whether the list delimiter is correctly
646 * handled.
647 */
648 private void checkSetListDelimiter()
649 {
650 cc.addProperty("test.list", "a/b/c");
651 cc.addProperty("test.property", "a,b,c");
652 assertEquals("Wrong number of list elements", 3, cc
653 .getList("test.list").size());
654 assertEquals("Wrong value of property", "a,b,c", cc
655 .getString("test.property"));
656 }
657
658 /***
659 * Tests whether list splitting can be disabled.
660 */
661 public void testSetDelimiterParsingDisabled()
662 {
663 cc.setDelimiterParsingDisabled(true);
664 checkSetListDelimiterParsingDisabled();
665 }
666
667 /***
668 * Tests whether the list parsing flag is correctly handled after a clear()
669 * operation.
670 */
671 public void testSetDelimiterParsingDisabledAfterClear()
672 {
673 cc.setDelimiterParsingDisabled(true);
674 cc.clear();
675 checkSetListDelimiterParsingDisabled();
676 }
677
678 /***
679 * Helper method for checking whether the list parsing flag is correctly
680 * handled.
681 */
682 private void checkSetListDelimiterParsingDisabled()
683 {
684 cc.addProperty("test.property", "a,b,c");
685 assertEquals("Wrong value of property", "a,b,c", cc
686 .getString("test.property"));
687 }
688
689 /***
690 * Prepares a test of the getSource() method.
691 */
692 private void setUpSourceTest()
693 {
694 cc.addConfiguration(conf1);
695 cc.addConfiguration(conf2);
696 }
697
698 /***
699 * Tests the getSource() method if the property is defined in a single child
700 * configuration.
701 */
702 public void testGetSourceSingle()
703 {
704 setUpSourceTest();
705 conf1.addProperty(TEST_PROPERTY, Boolean.TRUE);
706 assertSame("Wrong source configuration", conf1, cc
707 .getSource(TEST_PROPERTY));
708 }
709
710 /***
711 * Tests the getSource() method for an unknown property key.
712 */
713 public void testGetSourceUnknown()
714 {
715 setUpSourceTest();
716 assertNull("Wrong source for unknown key", cc.getSource(TEST_PROPERTY));
717 }
718
719 /***
720 * Tests the getSource() method for a property contained in the in memory
721 * configuration.
722 */
723 public void testGetSourceInMemory()
724 {
725 setUpSourceTest();
726 cc.addProperty(TEST_PROPERTY, Boolean.TRUE);
727 assertSame("Source not found in in-memory config", cc
728 .getInMemoryConfiguration(), cc.getSource(TEST_PROPERTY));
729 }
730
731 /***
732 * Tests the getSource() method if the property is defined by multiple child
733 * configurations. In this case an exception should be thrown.
734 */
735 public void testGetSourceMultiple()
736 {
737 setUpSourceTest();
738 conf1.addProperty(TEST_PROPERTY, Boolean.TRUE);
739 cc.addProperty(TEST_PROPERTY, "a value");
740 try
741 {
742 cc.getSource(TEST_PROPERTY);
743 fail("Property in multiple configurations did not cause an error!");
744 }
745 catch (IllegalArgumentException iex)
746 {
747
748 }
749 }
750
751 /***
752 * Tests the getSource() method for a null key. This should cause an
753 * exception.
754 */
755 public void testGetSourceNull()
756 {
757 try
758 {
759 cc.getSource(null);
760 fail("Could pass null key to getSource()!");
761 }
762 catch (IllegalArgumentException iex)
763 {
764
765 }
766 }
767
768 /***
769 * A test configuration event listener that counts the number of received
770 * events. Used for testing the event facilities.
771 */
772 static class TestEventListenerImpl implements ConfigurationListener
773 {
774 /*** The number of received events.*/
775 int eventCount;
776
777 public void configurationChanged(ConfigurationEvent event)
778 {
779 eventCount++;
780 }
781 }
782 }