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    }