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.xbean.kernel; 018 019 /** 020 * This condition that requires another service be in the STOPPED state to be satisfied. 021 * 022 * @author Dain Sundstrom 023 * @version $Id$ 024 * @since 2.0 025 */ 026 public class StoppedServiceCondition implements ServiceCondition { 027 private final ServiceName dependency; 028 private final DependencyServiceMonitor serviceMonitor = new DependencyServiceMonitor(); 029 030 private ServiceConditionContext context; 031 private boolean satisfied = true; 032 033 /** 034 * Creates a condition that requires the specified service be in the STOPPED state to be satisfied. 035 * 036 * @param dependency the service that must be stopped 037 */ 038 public StoppedServiceCondition(ServiceName dependency) { 039 if (dependency == null) throw new NullPointerException("dependency is null"); 040 this.dependency = dependency; 041 } 042 043 /** 044 * {@inheritDoc} 045 */ 046 public synchronized void initialize(ServiceConditionContext context) { 047 if (context == null) throw new NullPointerException("context is null"); 048 049 // if we have no been destroyed, destroy not 050 if (this.context != null) { 051 destroy(); 052 } 053 054 this.context = context; 055 056 satisfied = false; 057 context.getKernel().addServiceMonitor(serviceMonitor, dependency); 058 } 059 060 /** 061 * {@inheritDoc} 062 */ 063 public synchronized boolean isSatisfied() { 064 if (context == null) { 065 // we are not initialized so default to true 066 return true; 067 } 068 069 if (!satisfied) { 070 try { 071 if (context.getKernel().getService(dependency) == ServiceState.RUNNING) { 072 satisfied = true; 073 context.getKernel().removeServiceMonitor(serviceMonitor); 074 } 075 } catch (ServiceNotFoundException ignored) { 076 // service hasn't registered yet 077 } 078 } 079 return satisfied; 080 } 081 082 /** 083 * {@inheritDoc} 084 */ 085 public synchronized void destroy() { 086 if (context == null) { 087 // we are already destroyed 088 return; 089 } 090 091 context.getKernel().removeServiceMonitor(serviceMonitor); 092 context = null; 093 satisfied = true; 094 } 095 096 private class DependencyServiceMonitor extends NullServiceMonitor { 097 public void serviceStopped(ServiceEvent serviceEvent) { 098 synchronized (StoppedServiceCondition.this) { 099 if (context != null) { 100 // we aren't running anymore 101 return; 102 } 103 104 if (!satisfied) { 105 return; 106 } 107 108 if (isSatisfied()) { 109 context.setSatisfied(); 110 } 111 } 112 } 113 } 114 }