001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.commons.configuration.event;
018    
019    import java.io.IOException;
020    import java.net.URL;
021    
022    import org.apache.commons.configuration.AbstractFileConfiguration;
023    import org.apache.commons.configuration.ConfigurationException;
024    import org.apache.commons.configuration.FileConfiguration;
025    import org.apache.commons.configuration.reloading.ReloadingStrategy;
026    import org.junit.Test;
027    
028    /**
029     * A base test class that can be used for testing file-based configurations.
030     * This class tests reload events, too.
031     *
032     * @version $Id: AbstractTestFileConfigurationEvents.java 1225648 2011-12-29 20:55:07Z oheger $
033     */
034    public abstract class AbstractTestFileConfigurationEvents extends
035            AbstractTestConfigurationEvents
036    {
037        /**
038         * Initializes the file configuration for the tests.
039         *
040         * @throws ConfigurationException if an error occurs
041         */
042        protected void setUpFileConfiguration() throws ConfigurationException,
043                IOException
044        {
045            FileConfiguration fc = (FileConfiguration) config;
046            fc.setReloadingStrategy(new AlwaysReloadingStrategy());
047            fc.setURL(getSourceURL());
048    
049            // deregister event listener before load because load will cause
050            // other events being generated
051            config.removeConfigurationListener(l);
052            fc.load();
053            config.addConfigurationListener(l);
054        }
055    
056        /**
057         * Returns the URL of the file to be loaded. Must be implemented in concrete
058         * test classes.
059         *
060         * @return the URL of the file-based configuration
061         * @throws IOException if an error occurs
062         */
063        protected abstract URL getSourceURL() throws IOException;
064    
065        /**
066         * Tests events generated by the reload() method.
067         */
068        @Test
069        public void testReloadEvent() throws ConfigurationException, IOException
070        {
071            setUpFileConfiguration();
072            config.isEmpty(); // This should cause a reload
073            l.checkEvent(AbstractFileConfiguration.EVENT_RELOAD, null,
074                    getSourceURL(), true);
075            l.checkEvent(AbstractFileConfiguration.EVENT_RELOAD, null,
076                    getSourceURL(), false);
077            l.done();
078        }
079    
080        /**
081         * Tests events generated by the reload() method when detail events are
082         * enabled.
083         */
084        @Test
085        public void testReloadEventWithDetails() throws ConfigurationException,
086                IOException
087        {
088            setUpFileConfiguration();
089            config.setDetailEvents(true);
090            config.isEmpty(); // This should cause a reload
091            l.checkEventCount(2);
092            l.checkEvent(AbstractFileConfiguration.EVENT_RELOAD, null,
093                    getSourceURL(), true);
094            l.skipToLast(AbstractFileConfiguration.EVENT_RELOAD);
095            l.checkEvent(AbstractFileConfiguration.EVENT_RELOAD, null,
096                    getSourceURL(), false);
097            l.done();
098        }
099    
100        /**
101         * Tests accessing a property during a reload event to ensure that no
102         * infinite loops are possible.
103         */
104        @Test
105        public void testAccessPropertiesOnReload() throws ConfigurationException,
106                IOException
107        {
108            setUpFileConfiguration();
109            config.addConfigurationListener(new ConfigurationListener()
110            {
111                public void configurationChanged(ConfigurationEvent event)
112                {
113                    config.getString("test");
114                }
115            });
116            config.isEmpty();
117            l.checkEvent(AbstractFileConfiguration.EVENT_RELOAD, null,
118                    getSourceURL(), true);
119            l.checkEvent(AbstractFileConfiguration.EVENT_RELOAD, null,
120                    getSourceURL(), false);
121            l.done();
122        }
123    
124        /**
125         * A dummy implementation of the ReloadingStrategy interface. This
126         * implementation will always indicate that a reload should be performed. So
127         * it can be used for testing reloading events.
128         */
129        static class AlwaysReloadingStrategy implements ReloadingStrategy
130        {
131            public void setConfiguration(FileConfiguration configuration)
132            {
133            }
134    
135            public void init()
136            {
137            }
138    
139            public boolean reloadingRequired()
140            {
141                return true;
142            }
143    
144            public void reloadingPerformed()
145            {
146            }
147        }
148    }