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 java.util.ArrayList;
020 import java.util.Collection;
021 import java.util.concurrent.atomic.AtomicBoolean;
022
023 import org.apache.camel.Service;
024 import org.apache.camel.util.ObjectHelper;
025 import org.apache.camel.util.ServiceHelper;
026
027 /**
028 * A useful base class which ensures that a service is only initialized once and
029 * provides some helper methods for enquiring of its status
030 *
031 * @version $Revision: 722318 $
032 */
033 public abstract class ServiceSupport implements Service {
034 private static int threadCounter;
035 private AtomicBoolean started = new AtomicBoolean(false);
036 private AtomicBoolean starting = new AtomicBoolean(false);
037 private AtomicBoolean stopping = new AtomicBoolean(false);
038 private AtomicBoolean stopped = new AtomicBoolean(false);
039 private Collection childServices;
040 private String version;
041
042 public void start() throws Exception {
043 if (started.compareAndSet(false, true)) {
044 starting.set(true);
045 try {
046 if (childServices != null) {
047 ServiceHelper.startServices(childServices);
048 }
049 doStart();
050 } finally {
051 starting.set(false);
052 }
053 }
054 }
055
056 public void stop() throws Exception {
057 if (started.get() && stopping.compareAndSet(false, true)) {
058 try {
059 doStop();
060 } finally {
061 if (childServices != null) {
062 ServiceHelper.stopServices(childServices);
063 }
064 stopped.set(true);
065 started.set(false);
066 stopping.set(false);
067 }
068 }
069 }
070
071 /**
072 * @return true if this service has been started
073 */
074 public boolean isStarted() {
075 return started.get();
076 }
077
078 /**
079 * @return true if this service is
080 */
081 public boolean isStarting() {
082 return starting.get();
083 }
084
085 /**
086 * @return true if this service is in the process of closing
087 */
088 public boolean isStopping() {
089 return stopping.get();
090 }
091
092 /**
093 * Helper methods so the service knows if it should keep running.
094 * Returns false if the service is being stopped or is stopped.
095 *
096 * @return true if the service should continue to run.
097 */
098 protected boolean isRunAllowed() {
099 return !(stopping.get() || stopped.get());
100 }
101
102 /**
103 * @return true if this service is closed
104 */
105 public boolean isStopped() {
106 return stopped.get();
107 }
108
109 protected abstract void doStart() throws Exception;
110
111 protected abstract void doStop() throws Exception;
112
113 /**
114 * Creates a new thread name with the given prefix
115 */
116 protected String getThreadName(String prefix) {
117 return prefix + " thread:" + nextThreadCounter();
118 }
119
120 protected static synchronized int nextThreadCounter() {
121 return ++threadCounter;
122 }
123
124 protected void addChildService(Object childService) {
125 if (childServices == null) {
126 childServices = new ArrayList();
127 }
128 childServices.add(childService);
129 }
130
131 protected boolean removeChildService(Object childService) {
132 if (childServices != null) {
133 return childServices.remove(childService);
134 } else {
135 return false;
136 }
137 }
138
139 protected synchronized String getVersion() {
140 if (ObjectHelper.isNotNullAndNonEmpty(version)) {
141 return version;
142 }
143
144 Package aPackage = getClass().getPackage();
145 if (aPackage != null) {
146 version = aPackage.getImplementationVersion();
147 if (version == null) {
148 version = aPackage.getSpecificationVersion();
149 if (version == null) {
150 version = "";
151 }
152 }
153 } else {
154 version = "";
155 }
156
157 return version;
158 }
159 }