Package org.apache.geronimo.gbean.runtime

Source Code of org.apache.geronimo.gbean.runtime.GBeanDependency

/**
*
* Copyright 2004 The Apache Software Foundation
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package org.apache.geronimo.gbean.runtime;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.geronimo.gbean.AbstractName;
import org.apache.geronimo.gbean.AbstractNameQuery;
import org.apache.geronimo.gbean.InvalidConfigurationException;
import org.apache.geronimo.kernel.GBeanNotFoundException;
import org.apache.geronimo.kernel.Kernel;
import org.apache.geronimo.kernel.lifecycle.LifecycleAdapter;
import org.apache.geronimo.kernel.lifecycle.LifecycleListener;
import org.apache.geronimo.kernel.management.State;

/**
* @version $Rev: 390769 $ $Date: 2006-04-02 04:01:40 +0200 (Sun, 02 Apr 2006) $
*/
public final class GBeanDependency {


    private static final Log log = LogFactory.getLog(GBeanDependency.class);

    /**
     * The GBeanInstance to which this reference belongs.
     */
    private final GBeanInstance gbeanInstance;

    /**
     * The target objectName targetName to watch for a connection.
     */
    private final AbstractName targetName;

    /**
     * Our listener for lifecycle events
     */
    private final LifecycleListener listener;

    /**
     * The kernel to which the reference is bound.
     */
    private final Kernel kernel;

    private boolean targetRunning = false;
    private boolean dependencyRegistered = false;

    public GBeanDependency(GBeanInstance gbeanInstance, AbstractName targetName, Kernel kernel) throws InvalidConfigurationException {
        this.gbeanInstance = gbeanInstance;
        this.kernel = kernel;
        this.targetName = targetName;
        listener = createLifecycleListener();
    }

    public AbstractName getTargetName() {
        return targetName;
    }

    public final synchronized void online() {
        //TODO consider including interfaces in query
        AbstractNameQuery query = new AbstractNameQuery(targetName, null);
        kernel.getLifecycleMonitor().addLifecycleListener(listener, query);
        targetRunning = isRunning(kernel, targetName);
    }

    public synchronized boolean start() {
        if (targetRunning && !dependencyRegistered) {
            AbstractName abstractName = gbeanInstance.getAbstractName();
            kernel.getDependencyManager().addDependency(abstractName, targetName);
            dependencyRegistered = true;
        }
        return targetRunning;
    }


    public synchronized void stop() {
        if (dependencyRegistered) {
            AbstractName abstractName = gbeanInstance.getAbstractName();
            kernel.getDependencyManager().removeDependency(abstractName, targetName);
            dependencyRegistered = false;
        }
    }

    public final synchronized void offline() {
        // make sure we are stopped
        stop();

        kernel.getLifecycleMonitor().removeLifecycleListener(listener);
        targetRunning = false;
    }

    private synchronized void attemptFullStart() {
        try {
            // there could be an issue with really badly written components holding up a stop when the
            // component never reached the starting phase... then a target registers and we automatically
            // attempt to restart
//            waitingForMe = false;
            gbeanInstance.start();
        } catch (Exception e) {
            log.warn("Exception occured while attempting to fully start: objectName=" + gbeanInstance.getObjectName(), e);
        }
    }

    protected LifecycleListener createLifecycleListener() {
        return new LifecycleAdapter() {
            public void running(AbstractName abstractName) {
                addTarget(abstractName);
            }

            public void stopped(AbstractName abstractName) {
                removeTarget(abstractName);
            }

            public void failed(AbstractName abstractName) {
                removeTarget(abstractName);
            }

            public void unloaded(AbstractName abstractName) {
                removeTarget(abstractName);
            }
        };
    }

    protected final void addTarget(AbstractName abstractName) {
        // if we are running, and we now have two valid targets, which is an illegal state so we need to fail
        synchronized (this) {
            targetRunning = true;
            GBeanInstance gbeanInstance1 = gbeanInstance;
            if (gbeanInstance1.getStateInstance() == State.RUNNING) {
                log.error("Illegal state: two or more targets are running for a dependency: " + getDescription() +
                        ",\n    newTarget=" + abstractName);
            }
            attemptFullStart();
        }
    }

    protected final void removeTarget(AbstractName abstractName) {
        synchronized (this) {
            targetRunning = false;
            GBeanInstance gbeanInstance1 = gbeanInstance;
            if (gbeanInstance1.getStateInstance() == State.RUNNING) {
                // we no longer have a valid target, which is an illegal state so we need to fail
                log.error("Illegal state: current target for a single valued reference stopped: " + getDescription() +
                        ",\n    stopped Target=" + abstractName);
                gbeanInstance1.referenceFailed();
            }
        }
    }


    /**
     * Is the component in the Running state
     *
     * @param objectName name of the component to check
     * @return true if the component is running; false otherwise
     */
    private boolean isRunning(Kernel kernel, AbstractName objectName) {
        try {
            final int state = kernel.getGBeanState(objectName);
            return state == State.RUNNING_INDEX;
        } catch (GBeanNotFoundException e) {
            // gbean is no longer registerd
            return false;
        } catch (Exception e) {
            // problem getting the attribute, gbean has most likely failed
            return false;
        }
    }

    protected final String getDescription() {
        return "\n    GBeanInstance: " + gbeanInstance.getName() +
                "\n    Target Name: " + targetName;
    }

    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        final GBeanDependency that = (GBeanDependency) o;

        if (gbeanInstance != null ? !gbeanInstance.equals(that.gbeanInstance) : that.gbeanInstance != null) {
            return false;
        }
        return !(targetName != null ? !targetName.equals(that.targetName) : that.targetName != null);

    }

    public int hashCode() {
        int result;
        result = (gbeanInstance != null ? gbeanInstance.hashCode() : 0);
        result = 29 * result + (targetName != null ? targetName.hashCode() : 0);
        return result;
    }
}
TOP

Related Classes of org.apache.geronimo.gbean.runtime.GBeanDependency

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.