001// Copyright 2004, 2005 The Apache Software Foundation
002//
003// Licensed under the Apache License, Version 2.0 (the "License");
004// you may not use this file except in compliance with the License.
005// You may obtain a copy of the License at
006//
007//     http://www.apache.org/licenses/LICENSE-2.0
008//
009// Unless required by applicable law or agreed to in writing, software
010// distributed under the License is distributed on an "AS IS" BASIS,
011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012// See the License for the specific language governing permissions and
013// limitations under the License.
014
015package org.apache.hivemind.impl;
016
017import java.util.HashSet;
018import java.util.Iterator;
019import java.util.Set;
020
021import org.apache.commons.logging.Log;
022import org.apache.commons.logging.LogFactory;
023import org.apache.hivemind.ShutdownCoordinator;
024import org.apache.hivemind.events.RegistryShutdownListener;
025import org.apache.hivemind.util.EventListenerList;
026
027/**
028 * Manages a list of objects that implement the
029 * {@link org.apache.hivemind.events.RegistryShutdownListener} interface.
030 * 
031 * @author Howard Lewis Ship
032 */
033public final class ShutdownCoordinatorImpl implements ShutdownCoordinator
034{
035    private final Log _log;
036
037    private Set alreadyShutdown;
038
039    public ShutdownCoordinatorImpl()
040    {
041        this(LogFactory.getLog(ShutdownCoordinatorImpl.class));
042    }
043
044    public ShutdownCoordinatorImpl(Log log)
045    {
046        _log = log;        
047    }
048
049    private EventListenerList _listenerList;
050
051    public synchronized void addRegistryShutdownListener(
052            RegistryShutdownListener s)
053    {
054        if (_listenerList == null)
055            _listenerList = new EventListenerList();
056
057        _listenerList.addListener(s);
058    }
059
060    public synchronized void removeRegistryShutdownListener(
061            RegistryShutdownListener s)
062    {
063        if (_listenerList != null)
064            _listenerList.removeListener(s);
065    }
066
067    public void shutdown()
068    {
069        if (_listenerList == null)
070            return;
071
072        Iterator i = _listenerList.getListeners();
073
074        _listenerList = null;
075
076        while (i.hasNext())
077        {
078            RegistryShutdownListener s = (RegistryShutdownListener) i.next();
079
080            shutdown(s);
081        }
082
083        _listenerList = null;
084    }
085
086    private void shutdown(RegistryShutdownListener s)
087    {
088        if (alreadyShutdown == null)
089        {
090            alreadyShutdown = new HashSet();
091        }
092        final Long id = new Long(System.identityHashCode(s));
093        if (!alreadyShutdown.contains(id))
094        {
095            try
096            {
097                s.registryDidShutdown();
098            }
099            catch (RuntimeException ex)
100            {
101                _log.error(ImplMessages.shutdownCoordinatorFailure(s, ex), ex);
102            }
103            finally
104            {
105                alreadyShutdown.add(id);
106            }
107        }
108    }
109
110}