1 17 package org.apache.geronimo.gbean.runtime; 18 19 import org.apache.commons.logging.Log; 20 import org.apache.commons.logging.LogFactory; 21 import org.apache.geronimo.gbean.AbstractName; 22 import org.apache.geronimo.kernel.DependencyManager; 23 import org.apache.geronimo.kernel.GBeanNotFoundException; 24 import org.apache.geronimo.kernel.Kernel; 25 import org.apache.geronimo.kernel.management.State; 26 27 import java.util.Iterator ; 28 import java.util.Set ; 29 30 33 public class GBeanInstanceState { 34 private static final Log log = LogFactory.getLog(GBeanInstanceState.class); 35 36 39 private final GBeanInstance gbeanInstance; 40 41 44 private final Kernel kernel; 45 46 49 private final AbstractName abstractName; 50 51 54 private final DependencyManager dependencyManager; 55 56 59 private final LifecycleBroadcaster lifecycleBroadcaster; 60 61 private volatile State state = State.STOPPED; 64 65 GBeanInstanceState(AbstractName abstractName, Kernel kernel, DependencyManager dependencyManager, GBeanInstance gbeanInstance, LifecycleBroadcaster lifecycleBroadcaster) { 66 this.abstractName = abstractName; 67 this.kernel = kernel; 68 this.dependencyManager = dependencyManager; 69 this.gbeanInstance = gbeanInstance; 70 this.lifecycleBroadcaster = lifecycleBroadcaster; 71 } 72 73 81 public final void start() { 82 assert !Thread.holdsLock(this): "This method cannot be called while holding a synchronized lock on this"; 83 84 State originalState; 86 synchronized (this) { 87 originalState = getStateInstance(); 88 if (originalState == State.RUNNING) { 89 return; 90 } 91 if (originalState != State.STARTING) { 93 setStateInstance(State.STARTING); 94 } 95 } 96 97 if (originalState != State.STARTING) { 99 lifecycleBroadcaster.fireStartingEvent(); 100 } 101 102 attemptFullStart(); 103 } 104 105 112 public final void startRecursive() { 113 assert !Thread.holdsLock(this): "This method cannot be called while holding a synchronized lock on this"; 114 115 State state = getStateInstance(); 116 if (state != State.STOPPED && state != State.FAILED && state != State.RUNNING) { 117 return; 121 } 122 123 start(); 125 126 Set dependents = dependencyManager.getChildren(abstractName); 128 for (Iterator iterator = dependents.iterator(); iterator.hasNext();) { 129 AbstractName dependent = (AbstractName) iterator.next(); 130 try { 131 kernel.startRecursiveGBean(dependent); 132 } catch (GBeanNotFoundException e) { 133 } catch (Exception e) { 135 } 137 } 138 } 139 140 148 public final void stop() { 149 assert !Thread.holdsLock(this): "This method cannot be called while holding a synchronized lock on this"; 150 151 State originalState; 153 synchronized (this) { 154 originalState = getStateInstance(); 155 if (originalState == State.STOPPED) { 156 return; 157 } 158 159 if (originalState != State.STOPPING) { 161 setStateInstance(State.STOPPING); 162 } 163 } 164 165 if (originalState != State.STOPPING) { 167 lifecycleBroadcaster.fireStoppingEvent(); 168 } 169 170 172 Set dependents = dependencyManager.getChildren(abstractName); 174 for (Iterator iterator = dependents.iterator(); iterator.hasNext();) { 175 AbstractName child = (AbstractName) iterator.next(); 176 try { 177 log.trace("Checking if child is running: child=" + child); 178 if (kernel.getGBeanState(child) == State.RUNNING_INDEX) { 179 log.trace("Stopping child: child=" + child); 180 kernel.stopGBean(child); 181 log.trace("Stopped child: child=" + child); 182 } 183 } catch (Exception ignore) { 184 } 186 } 187 188 attemptFullStop(); 189 } 190 191 199 final void fail() { 200 assert !Thread.holdsLock(this): "This method cannot be called while holding a synchronized lock on this"; 201 202 synchronized (this) { 203 State state = getStateInstance(); 204 if (state == State.STOPPED || state == State.FAILED) { 205 return; 206 } 207 } 208 209 try { 210 if (gbeanInstance.destroyInstance(false)) { 211 return; 214 } 215 } catch (Throwable e) { 216 log.warn("Problem in doFail", e); 217 } 218 setStateInstance(State.FAILED); 219 lifecycleBroadcaster.fireFailedEvent(); 220 } 221 222 229 void attemptFullStart() { 230 assert !Thread.holdsLock(this): "This method cannot be called while holding a synchronized lock on this"; 231 232 synchronized (this) { 233 if (getStateInstance() != State.STARTING) { 235 return; 236 } 237 238 Set parents = dependencyManager.getParents(abstractName); 240 for (Iterator i = parents.iterator(); i.hasNext();) { 241 AbstractName parent = (AbstractName) i.next(); 242 if (!kernel.isLoaded(parent)) { 243 log.trace("Cannot run because parent is not registered: parent=" + parent); 244 return; 245 } 246 try { 247 log.trace("Checking if parent is running: parent=" + parent); 248 if (kernel.getGBeanState(parent) != State.RUNNING_INDEX) { 249 log.trace("Cannot run because parent is not running: parent=" + parent); 250 return; 251 } 252 log.trace("Parent is running: parent=" + parent); 253 } catch (GBeanNotFoundException e) { 254 log.trace("Cannot run because parent is not registered: parent=" + parent); 256 return; 257 } catch (Exception e) { 258 log.trace("Cannot run because an error occurred while checking if parent is running: parent=" + parent); 260 return; 261 } 262 } 263 } 264 265 try { 266 if (!gbeanInstance.createInstance()) { 268 return; 273 } 274 } catch (Throwable t) { 275 log.error("Error while starting; GBean is now in the FAILED state: abstractName=\"" + abstractName + "\"", t); 277 setStateInstance(State.FAILED); 278 lifecycleBroadcaster.fireFailedEvent(); 279 280 if (t instanceof Exception ) { 281 return; 283 } else if (t instanceof Error ) { 284 throw (Error ) t; 285 } else { 286 throw new Error (t); 287 } 288 } 289 290 setStateInstance(State.RUNNING); 292 lifecycleBroadcaster.fireRunningEvent(); 293 } 294 295 302 void attemptFullStop() { 303 assert !Thread.holdsLock(this): "This method cannot be called while holding a synchronized lock on this"; 304 305 synchronized (this) { 307 if (getStateInstance() != State.STOPPING) { 309 return; 310 } 311 312 Set children = dependencyManager.getChildren(abstractName); 314 for (Iterator i = children.iterator(); i.hasNext();) { 315 AbstractName child = (AbstractName) i.next(); 316 if (kernel.isLoaded(child)) { 317 try { 318 log.trace("Checking if child is stopped: child=" + child); 319 int state = kernel.getGBeanState(child); 320 if (state == State.RUNNING_INDEX) { 321 log.trace("Cannot stop because child is still running: child=" + child); 322 return; 323 } 324 } catch (GBeanNotFoundException e) { 325 } catch (Exception e) { 327 log.trace("Cannot run because an error occurred while checking if child is stopped: child=" + child); 329 return; 330 } 331 } 332 } 333 } 334 335 try { 337 if (!gbeanInstance.destroyInstance(true)) { 338 return; 341 } 342 } catch (Throwable t) { 343 log.error("Error while stopping; GBean is now in the FAILED state: abstractName=\"" + abstractName + "\"", t); 344 setStateInstance(State.FAILED); 345 lifecycleBroadcaster.fireFailedEvent(); 346 347 if (t instanceof Exception ) { 348 return; 350 } else if (t instanceof Error ) { 351 throw (Error ) t; 352 } else { 353 throw new Error (t); 354 } 355 } 356 357 setStateInstance(State.STOPPED); 359 lifecycleBroadcaster.fireStoppedEvent(); 360 } 361 362 public int getState() { 363 return state.toInt(); 364 } 365 366 public final State getStateInstance() { 367 return state; 368 } 369 370 376 private synchronized void setStateInstance(State newState) throws IllegalStateException { 377 switch (state.toInt()) { 378 case State.STOPPED_INDEX: 379 switch (newState.toInt()) { 380 case State.STARTING_INDEX: 381 break; 382 case State.STOPPED_INDEX: 383 case State.RUNNING_INDEX: 384 case State.STOPPING_INDEX: 385 case State.FAILED_INDEX: 386 throw new IllegalStateException ("Cannot transition to " + newState + " state from " + state); 387 } 388 break; 389 390 case State.STARTING_INDEX: 391 switch (newState.toInt()) { 392 case State.RUNNING_INDEX: 393 case State.FAILED_INDEX: 394 case State.STOPPING_INDEX: 395 break; 396 case State.STOPPED_INDEX: 397 case State.STARTING_INDEX: 398 throw new IllegalStateException ("Cannot transition to " + newState + " state from " + state); 399 } 400 break; 401 402 case State.RUNNING_INDEX: 403 switch (newState.toInt()) { 404 case State.STOPPING_INDEX: 405 case State.FAILED_INDEX: 406 break; 407 case State.STOPPED_INDEX: 408 case State.STARTING_INDEX: 409 case State.RUNNING_INDEX: 410 throw new IllegalStateException ("Cannot transition to " + newState + " state from " + state); 411 } 412 break; 413 414 case State.STOPPING_INDEX: 415 switch (newState.toInt()) { 416 case State.STOPPED_INDEX: 417 case State.FAILED_INDEX: 418 break; 419 case State.STARTING_INDEX: 420 case State.RUNNING_INDEX: 421 case State.STOPPING_INDEX: 422 throw new IllegalStateException ("Cannot transition to " + newState + " state from " + state); 423 } 424 break; 425 426 case State.FAILED_INDEX: 427 switch (newState.toInt()) { 428 case State.STARTING_INDEX: 429 case State.STOPPING_INDEX: 430 break; 431 case State.RUNNING_INDEX: 432 case State.STOPPED_INDEX: 433 case State.FAILED_INDEX: 434 throw new IllegalStateException ("Cannot transition to " + newState + " state from " + state); 435 } 436 break; 437 } 438 log.debug(toString() + " State changed from " + state + " to " + newState); 439 state = newState; 440 } 441 442 public String toString() { 443 return "GBeanInstanceState for: " + abstractName; 444 } 445 446 } 447 | Popular Tags |