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.camel.impl;
018
019 import org.apache.camel.Service;
020 import org.apache.camel.util.ServiceHelper;
021
022 import java.util.ArrayList;
023 import java.util.Collection;
024 import java.util.concurrent.atomic.AtomicBoolean;
025
026 import org.springframework.jmx.export.annotation.ManagedAttribute;
027 import org.springframework.jmx.export.annotation.ManagedOperation;
028 import org.springframework.jmx.export.annotation.ManagedResource;
029
030 /**
031 * A useful base class which ensures that a service is only initialized once and
032 * provides some helper methods for enquiring of its status
033 *
034 * @version $Revision: 565270 $
035 */
036 public abstract class ServiceSupport implements Service {
037 private static int threadCounter;
038 private AtomicBoolean started = new AtomicBoolean(false);
039 private AtomicBoolean stopping = new AtomicBoolean(false);
040 private AtomicBoolean stopped = new AtomicBoolean(false);
041 private Collection childServices;
042
043 public void start() throws Exception {
044 if (started.compareAndSet(false, true)) {
045 if (childServices != null) {
046 ServiceHelper.startServices(childServices);
047 }
048 doStart();
049 }
050 }
051
052 public void stop() throws Exception {
053 if (started.get() && stopping.compareAndSet(false, true)) {
054 try {
055 doStop();
056 }
057 finally {
058 if (childServices != null) {
059 ServiceHelper.stopServices(childServices);
060 }
061 stopped.set(true);
062 started.set(false);
063 stopping.set(false);
064 }
065 }
066 }
067
068 /**
069 * @return true if this service has been started
070 */
071 public boolean isStarted() {
072 return started.get();
073 }
074
075 /**
076 * @return true if this service is in the process of closing
077 */
078 public boolean isStopping() {
079 return stopping.get();
080 }
081
082 /**
083 * @return true if this service is closed
084 */
085 public boolean isStopped() {
086 return stopped.get();
087 }
088
089 protected abstract void doStart() throws Exception;
090
091 protected abstract void doStop() throws Exception;
092
093 /**
094 * Creates a new thread name with the given prefix
095 */
096 protected String getThreadName(String prefix) {
097 return prefix + " thread:" + nextThreadCounter();
098 }
099
100 protected static synchronized int nextThreadCounter() {
101 return ++threadCounter;
102 }
103
104 protected void addChildService(Object childService) {
105 if (childServices == null) {
106 childServices = new ArrayList();
107 }
108 childServices.add(childService);
109 }
110
111 protected boolean removeChildService(Object childService) {
112 if (childServices != null) {
113 return childServices.remove(childService);
114 }
115 else {
116 return false;
117 }
118 }
119 }