Package org.apache.felix.ipojo.composite

Source Code of org.apache.felix.ipojo.composite.CompositeManager

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you 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.felix.ipojo.composite;

import java.util.ArrayList;
import java.util.Dictionary;
import java.util.List;

import org.apache.felix.ipojo.ComponentFactory;
import org.apache.felix.ipojo.ComponentInstance;
import org.apache.felix.ipojo.ConfigurationException;
import org.apache.felix.ipojo.Handler;
import org.apache.felix.ipojo.HandlerFactory;
import org.apache.felix.ipojo.HandlerManager;
import org.apache.felix.ipojo.IPojoContext;
import org.apache.felix.ipojo.InstanceStateListener;
import org.apache.felix.ipojo.ServiceContext;
import org.apache.felix.ipojo.architecture.InstanceDescription;
import org.apache.felix.ipojo.metadata.Element;
import org.osgi.framework.BundleContext;

/**
* iPOJO Composite manager. The composite manager class manages one instance of
* a component type which is a composition. It manages component lifecycle, and
* handlers...
*
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
public class CompositeManager implements ComponentInstance, InstanceStateListener {

    /**
     * The context of the component.
     */
    private final BundleContext m_context;

    /**
     * Parent factory (ComponentFactory).
     */
    private final CompositeFactory m_factory;

    /**
     * Composite Handler list.
     */
    private HandlerManager[] m_handlers;

    /**
     * Instance State Listener List.
     */
    private List m_listeners = new ArrayList();

    /**
     * Internal service context of the composition.
     */
    private CompositeServiceContext m_internalContext;
   
    /**
     * The instance description.
     */
    private final CompositeInstanceDescription m_description;
   
    /**
     * Name of the component instance.
     */
    private String m_name;

    /**
     * Component state (STOPPED at the beginning).
     */
    private int m_state = STOPPED;

    /**
     * Construct a new Component Manager.
     * @param factory : the factory managing the instance manager
     * @param context : the bundle context to give to the instance
     * @param handlers : the handlers to plug
     */
    public CompositeManager(CompositeFactory factory, BundleContext context, HandlerManager[] handlers) {
        m_factory = factory;
        m_context = context;
        // Initialize the service context.
        m_internalContext = new CompositeServiceContext(m_context, this);
        m_handlers = handlers;
        m_description = new CompositeInstanceDescription(m_factory.getComponentDescription(), this);

    }

    /**
     * Plug the given handler to the current container.
     * @param handler : the handler to plug.
     */
    public synchronized void addCompositeHandler(HandlerManager handler) {
        if (m_handlers.length > 0) {
            HandlerManager[] newInstances = new HandlerManager[m_handlers.length + 1];
            System.arraycopy(m_handlers, 0, newInstances, 0, m_handlers.length);
            newInstances[m_handlers.length] = handler;
            m_handlers = newInstances;
        } else {
            m_handlers = new HandlerManager[] { handler };
        }
    }

    /**
     * Add an instance to the created instance list.
     * @param listener : the instance state listener to add.
     * @see org.apache.felix.ipojo.ComponentInstance#addInstanceStateListener(org.apache.felix.ipojo.InstanceStateListener)
     */
    public void addInstanceStateListener(InstanceStateListener listener) {
        synchronized (m_listeners) {
            m_listeners.add(listener);
        }
    }

    /**
     * Configure the instance manager. Stop the existing handler, clear the
     * handler list, change the metadata, recreate the handler
     *
     * @param metadata : the component type metadata
     * @param configuration : the configuration of the instance
     * @throws ConfigurationException : occurs when the component type are incorrect.
     */
    public void configure(Element metadata, Dictionary configuration) throws ConfigurationException {       
        // Add the name
        m_name = (String) configuration.get("instance.name");
       
        // Create the standard handlers and add these handlers to the list
        for (int i = 0; i < m_handlers.length; i++) {
            m_handlers[i].init(this, metadata, configuration);
        }
    }
   
    /**
     * Dispose the instance.
     * @see org.apache.felix.ipojo.ComponentInstance#dispose()
     */
    public void dispose() {
        if (m_state > STOPPED) { stop(); }
       
        for (int i = 0; i < m_listeners.size(); i++) {
            ((InstanceStateListener) m_listeners.get(i)).stateChanged(this, DISPOSED);
        }
       
        m_factory.disposed(this);

        // Cleaning
        m_state = DISPOSED;
        for (int i = m_handlers.length - 1; i > -1; i--) {
            m_handlers[i].dispose();
        }
        m_handlers = new HandlerManager[0];
        m_listeners.clear();
    }

    /**
     * Return a specified handler.
     * @param name : class name of the handler to find
     * @return : the handler, or null if not found
     */
    public CompositeHandler getCompositeHandler(String name) {
        for (int i = 0; i < m_handlers.length; i++) {
            HandlerFactory fact = (HandlerFactory) m_handlers[i].getFactory();
            if (fact.getHandlerName().equals(name) || fact.getComponentDescription().getClassName().equals(name)) {
                return (CompositeHandler) m_handlers[i].getHandler();
            }
        }
        return null;
    }

    /**
     * Get the bundle context used by this instance.
     * @return the parent context of the instance.
     * @see org.apache.felix.ipojo.ComponentInstance#getContext()
     */
    public BundleContext getContext() {
        return m_context;
    }

    /**
     * Get the factory which create this instance.
     * @return the factory of the component
     * @see org.apache.felix.ipojo.ComponentInstance#getFactory()
     */
    public ComponentFactory getFactory() {
        return m_factory;
    }
   
    /**
     * Get the global bundle context.
     * @return the global bundle context.
     */
    public BundleContext getGlobalContext() {
        IPojoContext context = (IPojoContext) m_context;
        return context.getGlobalContext();
    }
   
    /**
     * Return the instance description of this instance.
     * @return the instance description.
     * @see org.apache.felix.ipojo.ComponentInstance#getInstanceDescription()
     */
    public InstanceDescription getInstanceDescription() {
        return m_description;
    }

    /**
     * Get the instance name.
     * @return the instance name
     * @see org.apache.felix.ipojo.ComponentInstance#getInstanceName()
     */
    public String getInstanceName() {
        return m_name;
    }

    /**
     * Get the parent service context.
     * @return the parent service context.
     */
    public ServiceContext getParentServiceContext() {
        IPojoContext context = (IPojoContext) m_context;
        return context.getServiceContext();
    }

    /**
     * REturn the list of handlers plugged on this instance.
     * @return the list of the registered handlers.
     */
    public CompositeHandler[] getRegistredCompositeHandlers() {
        CompositeHandler[] handler = new CompositeHandler[m_handlers.length];
        for (int i = 0; i < m_handlers.length; i++) {
            handler[i] = (CompositeHandler) m_handlers[i].getHandler();
        }
        return handler;
    }
   
    /**
     * Get the internal service context of this instance.
     * @return the internal service context.
     */
    public ServiceContext getServiceContext() {
        return m_internalContext;
    }
   
    /**
     * Get the actual state of the instance.
     * @return the actual state of the instance
     * @see org.apache.felix.ipojo.ComponentInstance#getState()
     */
    public int getState() {
        return m_state;
    }
   
    /**
     * Check if the instance is started.
     * @return true if the instance is started.
     * @see org.apache.felix.ipojo.ComponentInstance#isStarted()
     */
    public boolean isStarted() {
        return m_state > STOPPED;
    }

    /**
     * Reconfigure the current instance.
     * @param configuration : the new instance configuration.
     * @see org.apache.felix.ipojo.ComponentInstance#reconfigure(java.util.Dictionary)
     */
    public void reconfigure(Dictionary configuration) {
        for (int i = 0; i < m_handlers.length; i++) {
            m_handlers[i].reconfigure(configuration);
        }
    }

    /**
     * Remove an instance state listener.
     * @param listener : the listener to remove
     * @see org.apache.felix.ipojo.ComponentInstance#removeInstanceStateListener(org.apache.felix.ipojo.InstanceStateListener)
     */
    public void removeInstanceStateListener(InstanceStateListener listener) {
        synchronized (m_listeners) {
            m_listeners.remove(listener);
        }
    }

    /**
     * Set the state of the component.
     * if the state changed call the stateChanged(int) method on the handlers.
     * @param state : new state
     */
    public void setState(int state) {
        if (m_state != state) {
            if (state > m_state) {
                // The state increases (Stopped = > IV, IV => V) => invoke handlers from the higher priority to the lower
                m_state = state;
                for (int i = 0; i < m_handlers.length; i++) {
                    m_handlers[i].getHandler().stateChanged(state);
                }
            } else {
                // The state decreases (V => IV, IV = > Stopped, Stopped => Disposed)
                m_state = state;
                for (int i = m_handlers.length - 1; i > -1; i--) {
                    m_handlers[i].getHandler().stateChanged(state);
                }
            }
           
            for (int i = 0; i < m_listeners.size(); i++) {
                ((InstanceStateListener) m_listeners.get(i)).stateChanged(this, state);
            }
        }
    }

    /**
     * Start the instance manager.
     */
    public synchronized void start() {
        if (m_state > STOPPED) {
            return;
        } // Instance already started


        // The new state of the component is UNRESOLVED
        m_state = INVALID;

        m_internalContext.start(); // Turn on the factory tracking
       
        // Plug handler descriptions
        Handler[] handlers = getRegistredCompositeHandlers();
        for (int i = 0; i < handlers.length; i++) {
            m_description.addHandler(handlers[i].getDescription());
        }

        for (int i = 0; i < m_handlers.length; i++) {
            m_handlers[i].start();
            m_handlers[i].addInstanceStateListener(this);
        }
       
        for (int i = 0; i < m_handlers.length; i++) {
            if (m_handlers[i].getState() != VALID) {
                setState(INVALID);
                return;
            }
        }
        setState(VALID);
       
    }

    /**
     * State Change listener callback.
     * This method is notified at each time a plugged handler becomes invalid.
     * @param instance : changing instance
     * @param newState : new state
     * @see org.apache.felix.ipojo.InstanceStateListener#stateChanged(org.apache.felix.ipojo.ComponentInstance, int)
     */
    public synchronized void stateChanged(ComponentInstance instance, int newState) {
        if (m_state <= STOPPED) { return; }
    
        // Update the component state if necessary
        if (newState == INVALID && m_state == VALID) {
            // Need to update the state to UNRESOLVED
            setState(INVALID);
            return;
        }
        if (newState == VALID && m_state == INVALID) {
            // An handler becomes valid => check if all handlers are valid
            boolean isValid = true;
            for (int i = 0; i < m_handlers.length; i++) {
                isValid = isValid && m_handlers[i].getState() == VALID;
            }
           
            if (isValid) { setState(VALID); }
        }
        if (newState == DISPOSED) {
            kill();
        }
    }

    /**
     * Stop the instance manager.
     */
    public synchronized void stop() {
        if (m_state <= STOPPED) {
            return;
        } // Instance already stopped

        setState(INVALID);
        // Stop all the handlers
        for (int i = m_handlers.length - 1; i > -1; i--) {
            m_handlers[i].removeInstanceStateListener(this);
            m_handlers[i].stop();
        }

        m_internalContext.stop(); // Turn off the factory tracking
        m_state = STOPPED;
       
        for (int i = 0; i < m_listeners.size(); i++) {
            ((InstanceStateListener) m_listeners.get(i)).stateChanged(this, STOPPED);
        }
    }
   
    /**
     * Kill the current instance.
     * Only the factory of this instance can call this method.
     */
    protected synchronized void kill() {
        if (m_state > STOPPED) { stop(); }
       
        for (int i = 0; i < m_listeners.size(); i++) {
            ((InstanceStateListener) m_listeners.get(i)).stateChanged(this, DISPOSED);
        }

        // Cleaning
        m_state = DISPOSED;
       
        for (int i = m_handlers.length - 1; i > -1; i--) {
            m_handlers[i].dispose();
        }
        m_handlers = new HandlerManager[0];
        m_listeners.clear();
    }
}
TOP

Related Classes of org.apache.felix.ipojo.composite.CompositeManager

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.