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.support; 018 019 import java.util.LinkedHashSet; 020 import java.util.Set; 021 022 import org.apache.camel.util.ServiceHelper; 023 024 public abstract class ChildServiceSupport extends ServiceSupport { 025 private Set<Object> childServices; 026 027 public void start() throws Exception { 028 start(true); 029 } 030 031 public void start(boolean startChildren) throws Exception { 032 if (!started.get()) { 033 if (starting.compareAndSet(false, true)) { 034 boolean childrenStarted = false; 035 Exception ex = null; 036 try { 037 if (childServices != null && startChildren) { 038 ServiceHelper.startServices(childServices); 039 } 040 childrenStarted = true; 041 doStart(); 042 } catch (Exception e) { 043 ex = e; 044 } finally { 045 if (ex != null) { 046 try { 047 stop(childrenStarted); 048 } catch (Exception e) { 049 // Ignore exceptions as we want to show the original exception 050 } 051 throw ex; 052 } else { 053 started.set(true); 054 starting.set(false); 055 stopping.set(false); 056 stopped.set(false); 057 suspending.set(false); 058 suspended.set(false); 059 shutdown.set(false); 060 shuttingdown.set(false); 061 } 062 } 063 } 064 } 065 } 066 067 private void stop(boolean childrenStarted) throws Exception { 068 if (stopping.compareAndSet(false, true)) { 069 try { 070 try { 071 starting.set(false); 072 suspending.set(false); 073 if (childrenStarted) { 074 doStop(); 075 } 076 } finally { 077 started.set(false); 078 suspended.set(false); 079 if (childServices != null) { 080 ServiceHelper.stopServices(childServices); 081 } 082 } 083 } finally { 084 stopped.set(true); 085 stopping.set(false); 086 starting.set(false); 087 started.set(false); 088 suspending.set(false); 089 suspended.set(false); 090 shutdown.set(false); 091 shuttingdown.set(false); 092 } 093 } 094 } 095 096 public void stop() throws Exception { 097 if (!stopped.get()) { 098 stop(true); 099 } 100 } 101 102 public void shutdown() throws Exception { 103 // ensure we are stopped first 104 stop(); 105 106 if (shuttingdown.compareAndSet(false, true)) { 107 try { 108 try { 109 doShutdown(); 110 } finally { 111 if (childServices != null) { 112 ServiceHelper.stopAndShutdownServices(childServices); 113 } 114 } 115 } finally { 116 // shutdown is also stopped so only set shutdown flags 117 shutdown.set(true); 118 shuttingdown.set(false); 119 } 120 } 121 } 122 123 protected void addChildService(Object childService) { 124 synchronized (this) { 125 if (childServices == null) { 126 childServices = new LinkedHashSet<Object>(); 127 } 128 } 129 childServices.add(childService); 130 } 131 132 protected boolean removeChildService(Object childService) { 133 return childServices != null && childServices.remove(childService); 134 } 135 136 }