001 // Copyright 2006, 2007, 2011 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
015 package org.apache.tapestry5.ioc.internal.services;
016
017 import org.apache.tapestry5.func.F;
018 import org.apache.tapestry5.func.Worker;
019 import org.apache.tapestry5.ioc.internal.util.OneShotLock;
020 import org.apache.tapestry5.ioc.services.RegistryShutdownHub;
021 import org.apache.tapestry5.ioc.services.RegistryShutdownListener;
022 import org.slf4j.Logger;
023
024 import java.util.List;
025
026 import static org.apache.tapestry5.ioc.internal.util.CollectionFactory.newThreadSafeList;
027
028 public class RegistryShutdownHubImpl implements RegistryShutdownHub
029 {
030 private final OneShotLock lock = new OneShotLock();
031
032 private final Logger logger;
033
034 private final List<Runnable> listeners = newThreadSafeList();
035
036 private final List<Runnable> preListeners = newThreadSafeList();
037
038 public RegistryShutdownHubImpl(Logger logger)
039 {
040 this.logger = logger;
041 }
042
043 public void addRegistryShutdownListener(final RegistryShutdownListener listener)
044 {
045 assert listener != null;
046
047 addRegistryShutdownListener(new Runnable()
048 {
049 public void run()
050 {
051 listener.registryDidShutdown();
052 }
053 });
054 }
055
056 public void addRegistryShutdownListener(Runnable listener)
057 {
058 assert listener != null;
059
060 lock.check();
061
062 listeners.add(listener);
063 }
064
065 public void addRegistryWillShutdownListener(Runnable listener)
066 {
067 assert listener != null;
068
069 lock.check();
070
071 preListeners.add(listener);
072 }
073
074 /**
075 * Fires the {@link RegistryShutdownListener#registryDidShutdown()} method on each listener. At the end, all the
076 * listeners are discarded.
077 */
078 public void fireRegistryDidShutdown()
079 {
080 lock.lock();
081
082 F.flow(preListeners).concat(listeners).each(new Worker<Runnable>()
083 {
084 public void work(Runnable element)
085 {
086 try
087 {
088 element.run();
089 } catch (RuntimeException ex)
090 {
091 logger.error(ServiceMessages.shutdownListenerError(element, ex), ex);
092 }
093 }
094 });
095
096 preListeners.clear();
097 listeners.clear();
098 }
099
100 }