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 }