org.apache.felix.ipojo.composite.CompositeManager Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.apache.felix.ipojo.composite Show documentation
Show all versions of org.apache.felix.ipojo.composite Show documentation
iPOJO Composition Model. This is an iPOJO extension to execute service composition.
/*
* 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.apache.felix.ipojo.util.Logger;
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 Felix Project Team
*/
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;
/**
* Logger.
*/
private Logger m_logger;
/**
* 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);
m_logger = new Logger(m_context, 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) || name.equals(fact.getComponentDescription().getClassName())) {
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) {
m_logger.log(Logger.INFO, "Reconfiguring composite with " + configuration);
for (int i = 0; i < m_handlers.length; i++) {
m_logger.log(Logger.INFO, "Delegating reconfiguration to " + m_handlers[i].getClassName());
m_handlers[i].getHandler().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();
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy