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 }