You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by fm...@apache.org on 2007/03/28 16:34:04 UTC
svn commit: r523345 [1/2] -
/incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/
Author: fmeschbe
Date: Wed Mar 28 07:34:01 2007
New Revision: 523345
URL: http://svn.apache.org/viewvc?view=rev&rev=523345
Log:
FELIX-258 Support Configuration Admin configuration
FELIX-259 Add support for factory components
Added:
incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/AbstractComponentManager.java (with props)
incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentContextImpl.java (with props)
incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentFactoryImpl.java (with props)
incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentRegistry.java (with props)
incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/DelayedComponentManager.java (with props)
incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/DependencyManager.java (with props)
incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ImmediateComponentManager.java (with props)
incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ReadOnlyDictionary.java (with props)
incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ServiceFactoryComponentManager.java (with props)
Removed:
incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentManagerImpl.java
Modified:
incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/Activator.java
incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/BundleComponentActivator.java
incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentManager.java
incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ManagerFactory.java
Added: incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/AbstractComponentManager.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/AbstractComponentManager.java?view=auto&rev=523345
==============================================================================
--- incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/AbstractComponentManager.java (added)
+++ incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/AbstractComponentManager.java Wed Mar 28 07:34:01 2007
@@ -0,0 +1,576 @@
+/*
+ * 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.scr;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.IdentityHashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.component.ComponentConstants;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.ComponentInstance;
+
+
+/**
+ * The default ComponentManager. Objects of this class are responsible for managing
+ * implementation object's lifecycle.
+ *
+ */
+abstract class AbstractComponentManager implements ComponentManager, ComponentInstance
+{
+ // manager has been newly created or disabled
+ static final int STATE_DISABLED = 1;
+
+ // manager has just been enabled and is going to be activated
+ static final int STATE_ENABLED = 2;
+
+ // manager has been enabled but not satisfied
+ static final int STATE_UNSATISFIED = 4;
+
+ // manager is currently activating
+ static final int STATE_ACTIVATING = 8;
+
+ // manager is now active
+ static final int STATE_ACTIVE = 16;
+
+ // manager for a delayed component has been registered (not active yet)
+ static final int STATE_REGISTERED = 32;
+
+ // manager for a component factory has been registered
+ static final int STATE_FACTORY = 64;
+
+ // manager is current deactivating
+ static final int STATE_DEACTIVATING = 128;
+
+ // manager has been destroyed and may not be used anymore
+ static final int STATE_DESTROYED = 256;
+
+ // The state of this instance manager
+ private int m_state;
+
+ // The metadata
+ private ComponentMetadata m_componentMetadata;
+
+ // The dependency managers that manage every dependency
+ private List m_dependencyManagers;
+
+ // A reference to the BundleComponentActivator
+ private BundleComponentActivator m_activator;
+
+ // The ServiceRegistration
+ private ServiceRegistration m_serviceRegistration;
+
+ /**
+ * The constructor receives both the activator and the metadata
+ *
+ * @param activator
+ * @param metadata
+ */
+ protected AbstractComponentManager(BundleComponentActivator activator, ComponentMetadata metadata)
+ {
+ m_activator = activator;
+ m_componentMetadata = metadata;
+
+ m_state = STATE_DISABLED;
+ m_dependencyManagers = new ArrayList();
+ }
+
+ /**
+ * Enable this component
+ *
+ * @return true if enabling was successful
+ */
+ public synchronized boolean enable() {
+
+ if (getState() == STATE_DESTROYED)
+ {
+ Activator.error( "Destroyed Component cannot be enabled", m_componentMetadata );
+ return false;
+ }
+ else if (getState() != STATE_DISABLED)
+ {
+ Activator.trace( "Component is already enabled", m_componentMetadata );
+ return true;
+ }
+
+ Activator.trace("Enabling component", m_componentMetadata);
+
+ try
+ {
+ // If this component has got dependencies, create dependency managers for each one of them.
+ if (m_componentMetadata.getDependencies().size() != 0)
+ {
+ Iterator dependencyit = m_componentMetadata.getDependencies().iterator();
+
+ while(dependencyit.hasNext())
+ {
+ ReferenceMetadata currentdependency = (ReferenceMetadata)dependencyit.next();
+
+ DependencyManager depmanager = new DependencyManager(this, currentdependency);
+
+ m_dependencyManagers.add(depmanager);
+ }
+ }
+
+ // enter enabled state before trying to activate
+ setState(STATE_ENABLED);
+
+ activate();
+
+ return true;
+ }
+ catch(Exception ex)
+ {
+ Activator.exception( "Failed enabled Component", m_componentMetadata, ex );
+
+ // ensure we get back to DISABLED state
+ disable();
+
+ return false;
+ }
+ }
+
+ /**
+ * Activate this Instance manager.
+ *
+ * 112.5.6 Activating a component configuration consists of the following steps
+ * 1. Load the component implementation class
+ * 2. Create the component instance and component context
+ * 3. Bind the target services
+ * 4. Call the activate method, if present
+ * [5. Register provided services]
+ */
+ synchronized void activate()
+ {
+ // CONCURRENCY NOTE: This method is called either by the enable()
+ // method or by the dependency managers or the reconfigure() method
+ if ( (getState() & (STATE_ENABLED|STATE_UNSATISFIED)) == 0)
+ {
+ // This state can only be entered from the ENABLED (in the enable()
+ // method) or UNSATISFIED (missing references) states
+ return;
+ }
+
+ // go to the activating state
+ setState(STATE_ACTIVATING);
+
+ // Before creating the implementation object, we are going to
+ // test if all the mandatory dependencies are satisfied
+ Iterator it = m_dependencyManagers.iterator();
+ while (it.hasNext())
+ {
+ DependencyManager dm = (DependencyManager)it.next();
+ if (!dm.isValid())
+ {
+ // at least one dependency is not satisfied
+ Activator.trace( "Dependency not satisfied: " + dm.getName(), m_componentMetadata );
+ setState(STATE_UNSATISFIED);
+ return;
+ }
+ }
+
+ // 1. Load the component implementation class
+ // 2. Create the component instance and component context
+ // 3. Bind the target services
+ // 4. Call the activate method, if present
+ createComponent();
+
+ // Validation occurs before the services are provided, otherwhise the
+ // service provider's service may be called by a service requester
+ // while it is still ACTIVATING
+ setState(getSatisfiedState());
+
+ // 5. Register provided services
+ m_serviceRegistration = registerComponentService();
+ }
+
+ /**
+ * Method is called by {@link #activate()} in STATE_ACTIVATING or by
+ * {@link DelayedComponentManager#getService(Bundle, ServiceRegistration)}
+ * in STATE_REGISTERED.
+ */
+ protected abstract void createComponent();
+
+ /**
+ * Method is called by {@link #deactivate()} in STATE_DEACTIVATING
+ *
+ */
+ protected abstract void deleteComponent();
+
+ /**
+ * Returns the state value to set, when the component is satisfied. The
+ * return value depends on the kind of the component:
+ * <dl>
+ * <dt>Immediate</dt><dd><code>STATE_ACTIVE</code></dd>
+ * <dt>Delayed</dt><dd><code>STATE_REGISTERED</code></dd>
+ * <dt>Component Factory</dt><dd><code>STATE_FACTORY</code></dd>
+ * </dl>
+ *
+ * @return
+ */
+ private int getSatisfiedState() {
+ if (m_componentMetadata.isFactory())
+ {
+ return STATE_FACTORY;
+ }
+ else if (m_componentMetadata.isImmediate())
+ {
+ return STATE_ACTIVE;
+ }
+ else
+ {
+ return STATE_REGISTERED;
+ }
+ }
+
+ /**
+ * Returns the service object to be registered if the service element is
+ * specified.
+ * <p>
+ * Extensions of this class may overwrite this method to return a
+ * ServiceFactory to register in the case of a delayed or a service
+ * factory component.
+ */
+ protected abstract Object getService();
+
+
+ // 5. Register provided services
+ protected ServiceRegistration registerComponentService()
+ {
+ if ( getComponentMetadata().getServiceMetadata() != null )
+ {
+ Activator.trace( "registering services", getComponentMetadata() );
+
+ // get a copy of the component properties as service properties
+ Dictionary serviceProperties = copyTo( null, getProperties() );
+
+ return getActivator().getBundleContext().registerService(
+ getComponentMetadata().getServiceMetadata().getProvides(), getService(), serviceProperties );
+ }
+
+ return null;
+ }
+
+ protected void unregisterComponentService()
+ {
+ if ( m_serviceRegistration != null )
+ {
+ m_serviceRegistration.unregister();
+ m_serviceRegistration = null;
+
+ Activator.trace( "unregistering the services", getComponentMetadata() );
+ }
+ }
+
+ /**
+ * Reconfigures this component by deactivating and activating it. During
+ * activation the new configuration data is retrieved from the Configuration
+ * Admin Service.
+ */
+ public void reconfigure()
+ {
+ Activator.trace( "Deactivating and Activating to reconfigure", m_componentMetadata );
+ reactivate();
+ }
+
+ /**
+ * Deactivates and activates this component instance.
+ */
+ void reactivate() {
+ deactivate();
+ Activator.trace( "Dependency Manager: RECREATING", m_componentMetadata );
+ activate();
+ }
+
+ /**
+ * This method deactivates the manager, performing the following steps
+ *
+ * [0. Remove published services from the registry]
+ * 1. Call the deactivate() method, if present
+ * 2. Unbind any bound services
+ * 3. Release references to the component instance and component context
+ **/
+ synchronized void deactivate()
+ {
+ // CONCURRENCY NOTE: This method may be called either from application
+ // code or by the dependency managers or reconfiguration
+ if ((getState() & (STATE_ACTIVATING|STATE_ACTIVE|STATE_REGISTERED|STATE_FACTORY)) == 0)
+ {
+ // This state can only be entered from the ACTIVATING (if activation
+ // fails), ACTIVE, REGISTERED or FACTORY states
+ return;
+ }
+// if (m_state != INSTANCE_VALID && m_state != INSTANCE_VALIDATING && m_state != INSTANCE_DESTROYING) {
+// return;
+// }
+
+ // start deactivation by resetting the state
+ setState( STATE_DEACTIVATING );
+
+ // 0.- Remove published services from the registry
+ unregisterComponentService();
+
+ // 1.- Call the deactivate method, if present
+ // 2. Unbind any bound services
+ // 3. Release references to the component instance and component context
+ deleteComponent();
+
+ //Activator.trace("InstanceManager from bundle ["+ m_activator.getBundleContext().getBundle().getBundleId() + "] was invalidated.");
+
+ // reset to state UNSATISFIED
+ setState( STATE_UNSATISFIED );
+ }
+
+ public synchronized void disable()
+ {
+ // CONCURRENCY NOTE: This method is only called from the BundleComponentActivator or by application logic
+ // but not by the dependency managers
+
+ // deactivate first, this does nothing if not active/registered/factory
+ deactivate();
+
+ // close all service listeners now, they are recreated on enable
+ // Stop the dependency managers to listen to events...
+ Iterator it = m_dependencyManagers.iterator();
+ while (it.hasNext())
+ {
+ DependencyManager dm = (DependencyManager)it.next();
+ dm.close();
+ }
+ m_dependencyManagers.clear();
+
+ // we are now disabled, ready for re-enablement or complete destroyal
+ setState( STATE_DISABLED );
+ }
+
+ /**
+ *
+ */
+ public synchronized void dispose()
+ {
+ // CONCURRENCY NOTE: This method is only called from the BundleComponentActivator or by application logic
+ // but not by the dependency managers
+
+ // disable first to clean up correctly
+ disable();
+
+ // this component must not be used any more
+ setState( STATE_DISABLED );
+
+ // release references (except component metadata for logging purposes)
+ m_activator = null;
+ m_dependencyManagers = null;
+ }
+
+ //**********************************************************************************************************
+
+ BundleComponentActivator getActivator() {
+ return m_activator;
+ }
+
+ Iterator getDependencyManagers() {
+ return m_dependencyManagers.iterator();
+ }
+
+ DependencyManager getDependencyManager( String name )
+ {
+ Iterator it = getDependencyManagers();
+ while ( it.hasNext() )
+ {
+ DependencyManager dm = ( DependencyManager ) it.next();
+ if ( name.equals( dm.getName() ) )
+ {
+ // only return the dm if it has service references
+ return ( dm.size() > 0 ) ? dm : null;
+ }
+ }
+
+ // not found
+ return null;
+ }
+
+ /**
+ * Get the object that is implementing this descriptor
+ *
+ * @return the object that implements the services
+ */
+ public abstract Object getInstance();
+ protected abstract Dictionary getProperties();
+
+ /**
+ * Copies the properties from the <code>source</code> <code>Dictionary</code>
+ * into the <code>target</code> <code>Dictionary</code>.
+ *
+ * @param target The <code>Dictionary</code> into which to copy the
+ * properties. If <code>null</code> a new <code>Hashtable</code> is
+ * created.
+ * @param source The <code>Dictionary</code> providing the properties to
+ * copy. If <code>null</code> or empty, nothing is copied.
+ *
+ * @return The <code>target</code> is returned, which may be empty if
+ * <code>source</code> is <code>null</code> or empty and
+ * <code>target</code> was <code>null</code>.
+ */
+ protected Dictionary copyTo( Dictionary target, Dictionary source )
+ {
+ if ( target == null )
+ {
+ target = new Hashtable();
+ }
+
+ if ( source != null && !source.isEmpty() )
+ {
+ for ( Enumeration ce = source.keys(); ce.hasMoreElements(); )
+ {
+ Object key = ce.nextElement();
+ target.put( key, source.get( key ) );
+ }
+ }
+
+ return target;
+ }
+
+ ServiceReference getServiceReference() {
+ return ( m_serviceRegistration != null ) ? m_serviceRegistration.getReference() : null;
+ }
+
+ /**
+ *
+ */
+ public ComponentMetadata getComponentMetadata() {
+ return m_componentMetadata;
+ }
+
+ int getState() {
+ return m_state;
+ }
+
+ /**
+ * sets the state of the manager
+ **/
+ protected synchronized void setState(int newState) {
+ Activator.trace( "State transition : " + stateToString( m_state ) + " -> " + stateToString( newState ),
+ m_componentMetadata );
+
+ m_state = newState;
+ }
+
+ private String stateToString(int state) {
+ switch (state) {
+ case STATE_DESTROYED:
+ return "Destroyed";
+ case STATE_DISABLED:
+ return "Disabled";
+ case STATE_ENABLED:
+ return "Enabled";
+ case STATE_UNSATISFIED:
+ return "Unsatisfied";
+ case STATE_ACTIVATING:
+ return "Activating";
+ case STATE_ACTIVE:
+ return "Active";
+ case STATE_REGISTERED:
+ return "Registered";
+ case STATE_FACTORY:
+ return "Factory";
+ case STATE_DEACTIVATING:
+ return "Deactivating";
+ default:
+ return String.valueOf(state);
+ }
+ }
+ /**
+ * Finds the named public or protected method in the given class or any
+ * super class. If such a method is found, its accessibility is enfored by
+ * calling the <code>Method.setAccessible</code> method if required and
+ * the method is returned. Enforcing accessibility is required to support
+ * invocation of protected methods.
+ *
+ * @param clazz The <code>Class</code> which provides the method.
+ * @param name The name of the method.
+ * @param parameterTypes The parameters to the method. Passing
+ * <code>null</code> is equivalent to using an empty array.
+ *
+ * @return The named method with enforced accessibility
+ *
+ * @throws NoSuchMethodException If no public or protected method with
+ * the given name can be found in the class or any of its super classes.
+ */
+ static Method getMethod(Class clazz, String name, Class[] parameterTypes)
+ throws NoSuchMethodException
+ {
+ // try the default mechanism first, which only yields public methods
+ try
+ {
+ return clazz.getMethod(name, parameterTypes);
+ }
+ catch (NoSuchMethodException nsme)
+ {
+ // it is ok to not find a public method, try to find a protected now
+ }
+
+ // now use method declarations, requiring walking up the class
+ // hierarchy manually. this algorithm also returns protected methods
+ // which is, what we need here
+ for ( ; clazz != null; clazz = clazz.getSuperclass())
+ {
+ try
+ {
+ Method method = clazz.getDeclaredMethod(name, parameterTypes);
+
+ // only accept a protected method, a public method should
+ // have been found above and neither private nor package
+ // protected methods are acceptable here
+ if (Modifier.isProtected(method.getModifiers())) {
+ method.setAccessible(true);
+ return method;
+ }
+ }
+ catch (NoSuchMethodException nsme)
+ {
+ // ignore for now
+ }
+ }
+
+ // walked up the complete super class hierarchy and still not found
+ // anything, sigh ...
+ throw new NoSuchMethodException(name);
+ }
+
+}
Propchange: incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/AbstractComponentManager.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/AbstractComponentManager.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Modified: incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/Activator.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/Activator.java?view=diff&rev=523345&r1=523344&r2=523345
==============================================================================
--- incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/Activator.java (original)
+++ incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/Activator.java Wed Mar 28 07:34:01 2007
@@ -18,18 +18,28 @@
*/
package org.apache.felix.scr;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import java.util.*;
-
-import org.osgi.framework.*;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.logging.Logger;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.Constants;
+import org.osgi.framework.SynchronousBundleListener;
import org.osgi.service.log.LogService;
+import org.osgi.util.tracker.ServiceTracker;
/**
* This activator is used to cover requirement described in section 112.8.1 @@ -27,14
* 37,202 @@ in active bundles.
*
*/
-public class Activator implements BundleActivator, SynchronousBundleListener, ServiceListener
+public class Activator implements BundleActivator, SynchronousBundleListener
{
// name of the LogService class
private static final String LOGSERVICE_CLASS = LogService.class.getName();
@@ -41,37 +51,20 @@
private static boolean m_error = true;
// A string containing the version number
- private static String m_version = "1.0.0 (12012006)";
+ private static String m_version = "1.0.0 (20070320)";
// this bundle's context
private BundleContext m_context;
// the log service to log messages to
- private static /* TODO: not very good, is it ? */ LogService m_logService;
+ private static ServiceTracker m_logService;
// map of BundleComponentActivator instances per Bundle indexed by Bundle symbolic
// name
private Map m_componentBundles;
- // Static initializations based on system properties
- static {
- // Get system properties to see if traces or errors need to be displayed
- String result = System.getProperty("ds.showtrace");
- if(result != null && result.equals("true"))
- {
- m_trace = true;
- }
- result = System.getProperty("ds.showerrors");
- if(result != null && result.equals("false"))
- {
- m_error = false;
- }
- result = System.getProperty("ds.showversion");
- if(result != null && result.equals("true"))
- {
- System.out.println("[ Version = "+m_version+" ]\n");
- }
- }
+ // registry of managed component
+ private ComponentRegistry m_componentRegistry;
/**
* Registers this instance as a (synchronous) bundle listener and loads the
@@ -84,15 +77,21 @@
{
m_context = context;
m_componentBundles = new HashMap();
+ m_componentRegistry = new ComponentRegistry( m_context );
// require the log service
- ServiceReference logRef = context.getServiceReference(LOGSERVICE_CLASS);
- if (logRef != null) {
- m_logService = (LogService) context.getService(logRef);
- }
- context.addServiceListener(this,
- "(" + Constants.OBJECTCLASS + "=" + LOGSERVICE_CLASS + ")");
+ m_logService = new ServiceTracker(context, LOGSERVICE_CLASS, null);
+ m_logService.open();
+ // configure logging from context properties
+ m_trace = "true".equalsIgnoreCase( context.getProperty( "ds.showtrace" ) );
+ m_error = !"false".equalsIgnoreCase( context.getProperty( "ds.showerrors" ) );
+ if ( "true".equalsIgnoreCase( context.getProperty( "ds.showversion" ) ) )
+ {
+ trace( context.getBundle().getSymbolicName() + "[ Version = "
+ + context.getBundle().getHeaders().get( Constants.BUNDLE_VERSION ) + " ]", null );
+ }
+
// register for bundle updates
context.addBundleListener(this);
@@ -115,6 +114,9 @@
// 112.8.2 dispose off all active components
disposeAllComponents();
+
+ // dispose off the component registry
+ m_componentRegistry.dispose();
}
// ---------- BundleListener Interface -------------------------------------
@@ -139,23 +141,7 @@
}
}
- //---------- ServiceListener ----------------------------------------------
-
- // TODO:
- public void serviceChanged(ServiceEvent event)
- {
- if (event.getType() == ServiceEvent.REGISTERED)
- {
- m_logService = (LogService) m_context.getService(event.getServiceReference());
- }
- else if (event.getType() == ServiceEvent.UNREGISTERING)
- {
- m_logService = null;
- m_context.ungetService(event.getServiceReference());
- }
- }
-
- // ---------- Component Management -----------------------------------------
+ //---------- Component Management -----------------------------------------
// Loads the components of all bundles currently active.
private void loadAllComponents(BundleContext context)
@@ -192,14 +178,13 @@
BundleContext context = getBundleContext(bundle);
if (context == null)
{
- error("Cannot get BundleContext of bundle "
- + bundle.getSymbolicName());
+ error( "Cannot get BundleContext of bundle " + bundle.getSymbolicName(), null );
return;
}
try
{
- BundleComponentActivator ga = new BundleComponentActivator(context);
+ BundleComponentActivator ga = new BundleComponentActivator( m_componentRegistry, context );
m_componentBundles.put(bundle.getSymbolicName(), ga);
}
catch (Exception e)
@@ -267,15 +252,21 @@
*/
private BundleContext getBundleContext(Bundle bundle)
{
- for (Class clazz = bundle.getClass(); clazz != null; clazz = clazz.getSuperclass())
+// try {
+// return bundle.getBundleContext();
+// } catch (Throwable t) {
+// // don't care, might be that the implementation is not yet updated
+// // to OSGi Rev 4.1
+// }
+
+ BundleContext context = null;
+ for (Class clazz = bundle.getClass(); context == null && clazz != null; clazz = clazz.getSuperclass())
{
try
{
- Method m = clazz.getDeclaredMethod("getContext", null);
- if (m.getReturnType().equals(BundleContext.class))
- {
- m.setAccessible(true);
- return (BundleContext) m.invoke(bundle, null);
+ context = getBundleContext( clazz, bundle, "getBundleContext" );
+ if (context == null) {
+ context = getBundleContext( clazz, bundle, "getContext" );
}
}
catch (NoSuchMethodException nsme)
@@ -289,10 +280,23 @@
}
}
- // fall back to nothing
- return null;
+ // return what we found
+ return context;
}
+ private BundleContext getBundleContext( Class clazz, Bundle bundle, String methodName )
+ throws NoSuchMethodException, InvocationTargetException, IllegalAccessException
+ {
+ Method m = clazz.getDeclaredMethod( methodName, null );
+ if ( m.getReturnType().equals( BundleContext.class ) )
+ {
+ m.setAccessible( true );
+ return ( BundleContext ) m.invoke( bundle, null );
+ }
+
+ // method exists but has wrong return type
+ return null;
+ }
/**
* Method to display traces
@@ -310,7 +314,7 @@
}
msg.append(message);
- LogService log = m_logService;
+ LogService log = (LogService) m_logService.getService();
if (log == null)
{
System.out.println(msg);
@@ -326,14 +330,19 @@
* Method to display errors
*
* @param message a string to be displayed
+ * @param metadata optional metadata providing more information to log
**/
- static void error(String message)
+ static void error(String message, ComponentMetadata metadata)
{
if(m_error)
{
- StringBuffer msg = new StringBuffer("### ").append(message);
+ StringBuffer msg = new StringBuffer("### ");
+ if(metadata != null) {
+ msg.append("[").append(metadata.getName()).append("] ");
+ }
+ msg.append(message);
- LogService log = m_logService;
+ LogService log = (LogService) m_logService.getService();
if (log == null)
{
System.err.println(msg);
@@ -361,7 +370,7 @@
msg.append("Exception with component : ");
msg.append(message).append(" ---");
- LogService log = m_logService;
+ LogService log = (LogService) m_logService.getService();
if (log == null)
{
System.err.println(msg);
Modified: incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/BundleComponentActivator.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/BundleComponentActivator.java?view=diff&rev=523345&r1=523344&r2=523345
==============================================================================
--- incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/BundleComponentActivator.java (original)
+++ incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/BundleComponentActivator.java Wed Mar 28 07:34:01 2007
@@ -24,15 +24,21 @@
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
+import javax.naming.ConfigurationException;
+
import org.apache.felix.scr.parser.KXml2SAXParser;
import org.osgi.framework.BundleContext;
+import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.component.ComponentException;
+import org.osgi.util.tracker.ServiceTracker;
/**
* The BundleComponentActivator is helper class to load and unload Components of
@@ -41,27 +47,41 @@
*/
class BundleComponentActivator
{
- // The bundle context
+ // global component registration
+ private ComponentRegistry m_componentRegistry;
+
+ // The bundle context owning the registered component
private BundleContext m_context = null;
// This is a list of component instance managers that belong to a particular bundle
private List m_managers = new ArrayList();
- // Global Registry of component names
- private static Set m_componentNames = new HashSet();
+ // The Configuration Admin tracker providing configuration for components
+ private ServiceTracker m_configurationAdmin;
/**
* Called upon starting of the bundle. This method invokes initialize() which
* parses the metadata and creates the instance managers
*
- * @param context The bundle context passed by the framework
- * @exception Exception any exception thrown from initialize
+ * @param componentRegistry The <code>ComponentRegistry</code> used to
+ * register components with to ensure uniqueness of component names
+ * and to ensure configuration updates.
+ * @param context The bundle context owning the components
+ *
+ * @throws ComponentException if any error occurrs initializing this class
*/
- BundleComponentActivator(BundleContext context) throws ComponentException
+ BundleComponentActivator(ComponentRegistry componentRegistry, BundleContext context) throws ComponentException
{
+ // The global "Component" registry
+ this.m_componentRegistry = componentRegistry;
+
// Stores the context
m_context = context;
+ // have the Configuration Admin Service handy (if available)
+ m_configurationAdmin = new ServiceTracker(context, ConfigurationAdmin.class.getName(), null);
+ m_configurationAdmin.open();
+
// Get the Metadata-Location value from the manifest
String descriptorLocations =
(String) m_context.getBundle().getHeaders().get("Service-Component");
@@ -95,12 +115,13 @@
{
// 112.4.1 If an XML document specified by the header cannot be located in the bundle and its attached
// fragments, SCR must log an error message with the Log Service, if present, and continue.
- Activator.error("Component descriptor entry '" + descriptorLocation + "' not found");
+ Activator.error( "Component descriptor entry '" + descriptorLocation + "' not found", null );
continue;
}
+ InputStream stream = null;
try {
- InputStream stream = descriptorURL.openStream();
+ stream = descriptorURL.openStream();
BufferedReader in = new BufferedReader(new InputStreamReader(stream));
XmlHandler handler = new XmlHandler();
@@ -121,16 +142,23 @@
validate(metadata);
// Request creation of the component manager
- ComponentManager manager = ManagerFactory.createManager(this,metadata);
+ ComponentManager manager;
+
+ if (metadata.isFactory()) {
+ // 112.2.4 SCR must register a Component Factory service on behalf ot the component
+ // as soon as the component factory is satisfied
+ manager = new ComponentFactoryImpl(this, metadata, m_componentRegistry);
+ } else {
+ manager = ManagerFactory.createManager( this, metadata, m_componentRegistry
+ .createComponentId() );
+ }
- if(metadata.isFactory())
- {
- // 112.2.4 SCR must register a Component Factory service on behalf ot the component
- // as soon as the component factory is satisfied
- }
- else if(metadata.isEnabled())
+ // register the component after validation
+ m_componentRegistry.registerComponent( metadata.getName(), manager );
+
+ // enable the component
+ if(metadata.isEnabled())
{
- // enable the component
manager.enable();
}
@@ -144,9 +172,6 @@
Activator.exception("Cannot register Component", metadata, e);
}
}
-
- stream.close();
-
}
catch ( IOException ex )
{
@@ -161,6 +186,19 @@
Activator.exception("General problem with descriptor entry '"
+ descriptorLocation + "'", null, ex);
}
+ finally
+ {
+ if ( stream != null )
+ {
+ try
+ {
+ stream.close();
+ }
+ catch ( IOException ignore )
+ {
+ }
+ }
+ }
}
}
@@ -193,11 +231,16 @@
}
finally
{
- m_componentNames.remove(manager.getComponentMetadata().getName());
+ m_componentRegistry.unregisterComponent( manager.getComponentMetadata().getName() );
}
}
+ // close the Configuration Admin tracker
+ if (m_configurationAdmin != null) {
+ m_configurationAdmin.close();
+ }
+
Activator.trace("BundleComponentActivator : Bundle ["
+ m_context.getBundle().getBundleId() + "] STOPPED", null);
@@ -225,6 +268,16 @@
}
/**
+ * Returns the <code>ConfigurationAdmin</code> service used to retrieve
+ * configuration data for components managed by this activator or
+ * <code>null</code> if no Configuration Admin Service is available in the
+ * framework.
+ */
+ protected ConfigurationAdmin getConfigurationAdmin() {
+ return (ConfigurationAdmin) m_configurationAdmin.getService();
+ }
+
+ /**
* Implements the <code>ComponentContext.enableComponent(String)</code>
* method by first finding the component(s) for the <code>name</code> and
* then starting a thread to actually enable all components found.
@@ -255,8 +308,7 @@
}
catch (Throwable t)
{
- Activator.exception("Cannot enable component",
- cm[i].getComponentMetadata(), t);
+ Activator.exception( "Cannot enable component", cm[i].getComponentMetadata(), t );
}
}
}
@@ -291,7 +343,7 @@
{
try
{
- cm[i].dispose();
+ cm[i].disable();
}
catch (Throwable t)
{
@@ -326,7 +378,7 @@
return (ComponentManager[]) m_managers.toArray(new ComponentManager[m_managers.size()]);
}
- if (m_componentNames.contains(name))
+ if ( m_componentRegistry.getComponent( name ) != null )
{
// otherwise just find it
Iterator it = m_managers.iterator();
@@ -358,16 +410,19 @@
void validate(ComponentMetadata component) throws ComponentException
{
- if(m_componentNames.contains(component.getName()))
- {
- throw new ComponentException("The component name '"+component.getName()+"' has already been registered.");
- }
+ m_componentRegistry.checkComponentName( component.getName() );
- component.validate();
+ try
+ {
+ component.validate();
+ }
+ catch ( ComponentException ce )
+ {
+ // remove the reservation before leaving
+ m_componentRegistry.unregisterComponent( component.getName() );
+ throw ce;
+ }
- // register the component after validation
- m_componentNames.add(component.getName());
-
- Activator.trace("Validated and registered component",component);
+ Activator.trace( "Validated and registered component", component );
}
}
Added: incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentContextImpl.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentContextImpl.java?view=auto&rev=523345
==============================================================================
--- incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentContextImpl.java (added)
+++ incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentContextImpl.java Wed Mar 28 07:34:01 2007
@@ -0,0 +1,157 @@
+/*
+ * 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.scr;
+
+
+import java.util.Dictionary;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.ComponentInstance;
+
+
+/**
+ * Implementation for the ComponentContext interface
+ *
+ */
+class ComponentContextImpl implements ComponentContext
+{
+
+ private AbstractComponentManager m_componentManager;
+
+
+ ComponentContextImpl( AbstractComponentManager componentManager )
+ {
+ m_componentManager = componentManager;
+ }
+
+
+ protected AbstractComponentManager getComponentManager()
+ {
+ return m_componentManager;
+ }
+
+ public Dictionary getProperties()
+ {
+ // 112.11.3.5 The Dictionary is read-only and cannot be modified
+ return new ReadOnlyDictionary( m_componentManager.getProperties() );
+ }
+
+
+ public Object locateService( String name )
+ {
+ DependencyManager dm = m_componentManager.getDependencyManager( name );
+ if ( dm == null )
+ {
+ return null;
+ }
+
+ ServiceReference selectedRef;
+ if ( dm.size() == 1 )
+ {
+ // short cut for single bound service
+ selectedRef = dm.getServiceReference();
+ }
+ else
+ {
+ // is it correct to assume an ordered bound services set ?
+ int maxRanking = Integer.MIN_VALUE;
+ long minId = Long.MAX_VALUE;
+ selectedRef = null;
+
+ ServiceReference[] refs = dm.getServiceReferences();
+ for ( int i = 0; refs != null && i < refs.length; i++ )
+ {
+ ServiceReference ref = refs[i];
+ Integer rank = ( Integer ) ref.getProperty( Constants.SERVICE_RANKING );
+ int ranking = ( rank == null ) ? Integer.MIN_VALUE : rank.intValue();
+ long id = ( ( Long ) ref.getProperty( Constants.SERVICE_ID ) ).longValue();
+ if ( maxRanking < ranking || ( maxRanking == ranking && id < minId ) )
+ {
+ maxRanking = ranking;
+ minId = id;
+ selectedRef = ref;
+ }
+ }
+ }
+
+ // this is not realistic, as at least one service is available
+ // whose service id is smaller than Long.MAX_VALUE, still be sure
+ if ( selectedRef == null )
+ {
+ return null;
+ }
+
+ // return the service for the selected reference
+ return dm.getService( selectedRef );
+ }
+
+
+ public Object locateService( String name, ServiceReference ref )
+ {
+ DependencyManager dm = m_componentManager.getDependencyManager( name );
+ return ( dm != null ) ? dm.getService( ref ) : null;
+ }
+
+
+ public Object[] locateServices( String name )
+ {
+ DependencyManager dm = m_componentManager.getDependencyManager( name );
+ return ( dm != null ) ? dm.getServices() : null;
+ }
+
+
+ public BundleContext getBundleContext()
+ {
+ return m_componentManager.getActivator().getBundleContext();
+ }
+
+
+ public Bundle getUsingBundle()
+ {
+ return null;
+ }
+
+
+ public ComponentInstance getComponentInstance()
+ {
+ return m_componentManager;
+ }
+
+
+ public void enableComponent( String name )
+ {
+ m_componentManager.getActivator().enableComponent( name );
+ }
+
+
+ public void disableComponent( String name )
+ {
+ m_componentManager.getActivator().disableComponent( name );
+ }
+
+
+ public ServiceReference getServiceReference()
+ {
+ return m_componentManager.getServiceReference();
+ }
+}
Propchange: incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentContextImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentContextImpl.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentFactoryImpl.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentFactoryImpl.java?view=auto&rev=523345
==============================================================================
--- incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentFactoryImpl.java (added)
+++ incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentFactoryImpl.java Wed Mar 28 07:34:01 2007
@@ -0,0 +1,248 @@
+/*
+ * 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.scr;
+
+
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.IdentityHashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.cm.ManagedServiceFactory;
+import org.osgi.service.component.ComponentConstants;
+import org.osgi.service.component.ComponentFactory;
+import org.osgi.service.component.ComponentInstance;
+
+
+/**
+ * The <code>ComponentFactoryImpl</code> TODO
+ *
+ * @author fmeschbe
+ */
+public class ComponentFactoryImpl extends AbstractComponentManager implements ComponentFactory, ManagedServiceFactory
+{
+
+ // The component registry used to retrieve component IDs
+ private ComponentRegistry m_componentRegistry;
+
+ // The map of components created from Configuration objects
+ // maps PID to ComponentManager for configuration updating
+ // this map is lazily created
+ private Map m_configuredServices;
+
+ // Actually we only use the identity key stuff, but there is
+ // no IdentityHashSet and HashSet internally uses a HashMap anyway
+ private Map m_createdComponents;
+
+ ComponentFactoryImpl( BundleComponentActivator activator, ComponentMetadata metadata,
+ ComponentRegistry componentRegistry )
+ {
+ super( activator, metadata );
+ m_componentRegistry = componentRegistry;
+ m_createdComponents = new IdentityHashMap();
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.component.ComponentFactory#newInstance(java.util.Dictionary)
+ */
+ public ComponentInstance newInstance( Dictionary dictionary )
+ {
+ return ( ComponentInstance ) createComponentManager( dictionary );
+ }
+
+
+ protected void createComponent()
+ {
+ // not component to create, newInstance must be used instead
+ }
+
+ public void reconfigure()
+ {
+ super.reconfigure();
+ }
+
+ protected void deleteComponent()
+ {
+ // nothing to delete
+ }
+
+
+ protected ServiceRegistration registerComponentService()
+ {
+ Activator.trace( "registering component factory", getComponentMetadata() );
+
+ Dictionary serviceProperties = getProperties();
+ return getActivator().getBundleContext().registerService( new String[]
+ { ComponentFactory.class.getName(), ManagedServiceFactory.class.getName() }, getService(),
+ serviceProperties );
+ }
+
+
+ public Object getInstance()
+ {
+ // this does not return the component instance actually
+ return null;
+ }
+
+
+ protected Dictionary getProperties()
+ {
+ Dictionary props = new Hashtable();
+
+ // 112.5.5 The Component Factory service must register with the following properties
+ props.put( ComponentConstants.COMPONENT_NAME, getComponentMetadata().getName() );
+ props.put( ComponentConstants.COMPONENT_FACTORY, getComponentMetadata().getFactoryIdentifier() );
+
+ // also register with the factory PID
+ props.put( Constants.SERVICE_PID, getComponentMetadata().getName() );
+
+ return props;
+ }
+
+
+ protected Object getService()
+ {
+ return this;
+ }
+
+
+ //---------- ManagedServiceFactory interface ------------------------------
+
+ public void updated( String pid, Dictionary configuration )
+ {
+ ComponentManager cm;
+ if ( m_configuredServices != null )
+ {
+ cm = ( ComponentManager ) m_configuredServices.get( pid );
+ }
+ else
+ {
+ m_configuredServices = new HashMap();
+ cm = null;
+ }
+
+ if ( cm == null )
+ {
+ // create a new instance with the current configuration
+ cm = createComponentManager( configuration );
+
+ // keep a reference for future updates
+ m_configuredServices.put( pid, cm );
+ }
+ else
+ {
+ if ( cm instanceof ImmediateComponentManager )
+ {
+ // inject current configuration before cycling
+ ( ( ImmediateComponentManager ) cm ).setFactoryProperties( configuration );
+ }
+
+ // reconfigure the component
+ cm.reconfigure();
+ }
+ }
+
+
+ public void deleted( String pid )
+ {
+ if ( m_configuredServices != null )
+ {
+ ComponentManager cm = ( ComponentManager ) m_configuredServices.remove( pid );
+ if ( cm != null )
+ {
+ disposeComponentManager( cm );
+ }
+ }
+
+ }
+
+
+ public String getName()
+ {
+ return "Component Factory " + getComponentMetadata().getName();
+ }
+
+
+ //---------- internal -----------------------------------------------------
+
+ /**
+ * ComponentManager instances created by this method are not registered
+ * with the ComponentRegistry. Therefore, any configuration update to these
+ * components must be effected by this class !
+ */
+ private ComponentManager createComponentManager( Dictionary configuration )
+ {
+ long componentId = m_componentRegistry.createComponentId();
+ ComponentManager cm = ManagerFactory.createManager( getActivator(), getComponentMetadata(), componentId );
+
+ // add the new component to the activators instances
+ getActivator().getInstanceReferences().add( cm );
+
+ // register with the internal set of created components
+ m_createdComponents.put(cm, cm);
+
+ // inject configuration if possible
+ if ( cm instanceof ImmediateComponentManager )
+ {
+ ( ( ImmediateComponentManager ) cm ).setFactoryProperties( configuration );
+ }
+
+ // immediately enable this ComponentManager
+ cm.enable();
+
+ return cm;
+ }
+
+ private void disposeComponentManager(ComponentManager cm) {
+ // remove from created components
+ m_createdComponents.remove( cm );
+
+ // remove from activators list
+ getActivator().getInstanceReferences().remove( cm );
+
+ // finally dispose it
+ cm.dispose();
+ }
+
+ private class ComponentInstanceWrapper implements ComponentInstance {
+
+ private ComponentManager m_component;
+
+ ComponentInstanceWrapper(ComponentManager component) {
+ m_component = component;
+ }
+
+ public Object getInstance()
+ {
+ return ((ComponentInstance) m_component).getInstance();
+ }
+
+ public void dispose()
+ {
+ disposeComponentManager( m_component );
+ }
+ }
+}
Propchange: incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentFactoryImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentFactoryImpl.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Modified: incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentManager.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentManager.java?view=diff&rev=523345&r1=523344&r2=523345
==============================================================================
--- incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentManager.java (original)
+++ incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentManager.java Wed Mar 28 07:34:01 2007
@@ -18,6 +18,8 @@
*/
package org.apache.felix.scr;
+import java.util.Dictionary;
+
/**
* This interface is provided so that there can be multiple implementations of
* managers that are responsible for managing component's lifecycle.
@@ -32,9 +34,21 @@
*/
public boolean enable();
+ /**
+ * Reconfigure the component with configuration data newly retrieved from
+ * the Configuration Admin Service.
+ */
+ public void reconfigure();
+
+ /**
+ * Disable the component. After disabling the component may be re-enabled
+ * by calling the {@link #enable()} method.
+ */
+ public void disable();
+
/**
- * Dispose the component
- *
+ * Dispose the component. After disposing the component manager it must not
+ * be used anymore.
*/
public void dispose();
Added: incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentRegistry.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentRegistry.java?view=auto&rev=523345
==============================================================================
--- incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentRegistry.java (added)
+++ incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentRegistry.java Wed Mar 28 07:34:01 2007
@@ -0,0 +1,141 @@
+/*
+ * 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.scr;
+
+
+import java.awt.Component;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cm.ConfigurationEvent;
+import org.osgi.service.cm.ConfigurationListener;
+import org.osgi.service.component.ComponentException;
+
+
+/**
+ * The <code>ComponentRegistry</code> TODO
+ *
+ * @author fmeschbe
+ */
+public class ComponentRegistry implements ConfigurationListener
+{
+
+ // Known and registered ComponentManager instances
+ private Map m_componentNames;
+
+ // component id counter
+ private long m_componentCounter;
+
+ // the service registration of the ConfigurationListener service
+ private ServiceRegistration registration;
+
+
+ ComponentRegistry( BundleContext context )
+ {
+ m_componentNames = new HashMap();
+ m_componentCounter = -1;
+
+ Dictionary props = new Hashtable();
+ props.put( Constants.SERVICE_DESCRIPTION, "Service Component Configuration Support" );
+ props.put( Constants.SERVICE_VENDOR, "Apache Software Foundation" );
+ registration = context.registerService( ConfigurationListener.class.getName(), this, props );
+ }
+
+
+ void dispose()
+ {
+ if ( registration != null )
+ {
+ registration.unregister();
+ registration = null;
+ }
+ }
+
+
+ //---------- ConfigurationListener ----------------------------------------
+
+ public void configurationEvent( ConfigurationEvent configEvent )
+ {
+ String pid = configEvent.getPid();
+ ComponentManager cm = getComponent( pid );
+ if ( cm != null )
+ {
+ cm.reconfigure();
+ }
+ }
+
+
+ //---------- ComponentManager registration support ------------------------
+
+ long createComponentId()
+ {
+ m_componentCounter++;
+ return m_componentCounter;
+ }
+
+
+ void checkComponentName( String name )
+ {
+ if ( m_componentNames.containsKey( name ) )
+ {
+ throw new ComponentException( "The component name '" + name + "' has already been registered." );
+ }
+
+ // reserve the name
+ m_componentNames.put( name, name );
+ }
+
+
+ void registerComponent( String name, ComponentManager component )
+ {
+ // only register the component if there is a registration for it !
+ if ( !name.equals( m_componentNames.get( name ) ) )
+ {
+ // this is not expected if all works ok
+ throw new ComponentException( "The component name '" + name + "' has already been registered." );
+ }
+
+ m_componentNames.put( name, component );
+ }
+
+
+ ComponentManager getComponent( String name )
+ {
+ Object entry = m_componentNames.get( name );
+
+ // only return the entry if non-null and not a reservation
+ if ( entry instanceof ComponentManager )
+ {
+ return ( ComponentManager ) entry;
+ }
+
+ return null;
+ }
+
+
+ void unregisterComponent( String name )
+ {
+ m_componentNames.remove( name );
+ }
+}
Propchange: incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentRegistry.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentRegistry.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/DelayedComponentManager.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/DelayedComponentManager.java?view=auto&rev=523345
==============================================================================
--- incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/DelayedComponentManager.java (added)
+++ incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/DelayedComponentManager.java Wed Mar 28 07:34:01 2007
@@ -0,0 +1,84 @@
+/*
+ * 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.scr;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.component.ComponentContext;
+
+/**
+ * The <code>DelayedComponentManager</code> TODO
+ *
+ * @author fmeschbe
+ * @version $Rev$, $Date$
+ */
+public class DelayedComponentManager extends ImmediateComponentManager implements ServiceFactory
+{
+
+ /**
+ * @param activator
+ * @param metadata
+ * @param componentId
+ */
+ public DelayedComponentManager( BundleComponentActivator activator, ComponentMetadata metadata, long componentId )
+ {
+ super( activator, metadata, componentId );
+ }
+
+ protected void createComponent()
+ {
+ // nothing to do here for a delayed component, will be done in the
+ // getService method for the first bundle acquiring the component
+ }
+
+ protected Object getService()
+ {
+ return this;
+ }
+
+ //---------- ServiceFactory interface -------------------------------------
+
+ public Object getService( Bundle arg0, ServiceRegistration arg1 )
+ {
+ Activator.trace("DelayedComponentServiceFactory.getService()", getComponentMetadata());
+ // When the getServiceMethod is called, the implementation object must be created
+ // unless another bundle has already retrievd it
+
+ if (getInstance() == null) {
+ super.createComponent();
+
+ // if component creation failed, we were deactivated and the state
+ // is not REGISTERED any more. Otherwise go to standard ACTIVE
+ // state now
+ if (getState() == STATE_REGISTERED)
+ {
+ setState( STATE_ACTIVE );
+ }
+ }
+
+ return getInstance();
+ }
+
+ public void ungetService( Bundle arg0, ServiceRegistration arg1, Object arg2 )
+ {
+ // nothing to do here
+ }
+
+}
Propchange: incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/DelayedComponentManager.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/DelayedComponentManager.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url