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.standard;
018    
019    import java.util.concurrent.locks.Condition;
020    import java.util.concurrent.locks.Lock;
021    import org.apache.xbean.kernel.Kernel;
022    import org.apache.xbean.kernel.ServiceConditionContext;
023    import org.apache.xbean.kernel.ServiceName;
024    
025    /**
026     * This is the service context used by the service manager.
027     *
028     * @author Dain Sundstrom
029     * @version $Id$
030     * @since 2.0
031     */
032    public class StandardServiceConditionContext implements ServiceConditionContext {
033        /**
034         * The kernel in which the service is registered.
035         */
036        private final Kernel kernel;
037    
038        /**
039         * The unique name of the service in the kernel.
040         */
041        private final ServiceName serviceName;
042    
043        /**
044         * The class loader for the service.
045         */
046        private final ClassLoader classLoader;
047    
048        /**
049         * The lock that must be acquired before signaling the condition.
050         */
051        private final Lock lock;
052    
053        /**
054         * The condition to signal when the {@link #setSatisfied()} method is called.
055         */
056        private final Condition condition;
057    
058        /**
059         * Has this condition been satisfied?  Once satisfied a condition is always considered satisfied.
060         */
061        private boolean satisfied = false;
062    
063        /**
064         * Creates a service context for the specified service.
065         *
066         * @param kernel the kernel in which the service is registered
067         * @param serviceName the name of the service
068         * @param classLoader the class loader for the service
069         * @param lock the lock for the service manager
070         * @param condition the condition that should be notified when the {@link #setSatisfied()} method is called
071         */
072        public StandardServiceConditionContext(Kernel kernel, ServiceName serviceName, ClassLoader classLoader, Lock lock, Condition condition) {
073            this.kernel = kernel;
074            this.serviceName = serviceName;
075            this.classLoader = classLoader;
076            this.lock = lock;
077            this.condition = condition;
078        }
079    
080        /**
081         * {@inheritDoc}
082         */
083        public Kernel getKernel() {
084            return kernel;
085        }
086    
087        /**
088         * {@inheritDoc}
089         */
090        public ServiceName getServiceName() {
091            return serviceName;
092        }
093    
094        /**
095         * {@inheritDoc}
096         */
097        public ClassLoader getClassLoader() {
098            return classLoader;
099        }
100    
101        /**
102         * Gets the satisfied status of this condition.  Once satisfied a condition is considered satisfied until destroyed
103         * and reinitialized.  The ServiceManager uses the StandardServiceConditionContext to track the status of conditions
104         * so it will call setSatisfied() when the condition returns true from isSatisfied().
105         *
106         * @return satisfied status of this condition
107         */
108        public boolean isSatisfied() {
109            return satisfied;
110        }
111    
112        /**
113         * {@inheritDoc}
114         */
115        public void setSatisfied() {
116            lock.lock();
117            try {
118                if (!satisfied) {
119                    satisfied = true;
120                    condition.signalAll();
121                }
122            } finally {
123                lock.unlock();
124            }
125        }
126    }