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: 1856 $ 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 }