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.activemq.util;
018    
019    import java.util.Iterator;
020    import java.util.List;
021    
022    import org.apache.activemq.Service;
023    import org.slf4j.Logger;
024    import org.slf4j.LoggerFactory;
025    
026    /**
027     * A helper class used to stop a bunch of services, catching and logging any
028     * exceptions and then throwing the first exception when everything is stoped.
029     * 
030     * 
031     */
032    public class ServiceStopper {
033        private Throwable firstException;
034    
035        /**
036         * Stops the given service, catching any exceptions that are thrown.
037         */
038        public void stop(Service service) {
039            try {
040                if (service != null) {
041                    service.stop();
042                }
043            } catch (Exception e) {
044                onException(service, e);
045            }
046        }
047    
048        /**
049         * Performs the given code to stop some service handling the exceptions
050         * which may be thrown properly
051         */
052        public void run(Callback stopClosure) {
053            try {
054                stopClosure.execute();
055            } catch (Throwable e) {
056                onException(stopClosure, e);
057            }
058        }
059    
060        /**
061         * Stops a list of services
062         */
063        public void stopServices(List services) {
064            for (Iterator iter = services.iterator(); iter.hasNext();) {
065                Service service = (Service)iter.next();
066                stop(service);
067            }
068        }
069    
070        public void onException(Object owner, Throwable e) {
071            logError(owner, e);
072            if (firstException == null) {
073                firstException = e;
074            }
075        }
076    
077        /**
078         * Throws the first exception that was thrown if there was one.
079         */
080        public void throwFirstException() throws Exception {
081            if (firstException != null) {
082                if (firstException instanceof Exception) {
083                    Exception e = (Exception)firstException;
084                    throw e;
085                } else if (firstException instanceof RuntimeException) {
086                    RuntimeException e = (RuntimeException)firstException;
087                    throw e;
088                } else {
089                    throw new RuntimeException("Unknown type of exception: " + firstException, firstException);
090                }
091            }
092        }
093    
094        protected void logError(Object service, Throwable e) {
095            Logger log = LoggerFactory.getLogger(service.getClass());
096            log.error("Could not stop service: " + service + ". Reason: " + e, e);
097        }
098    
099    }