FELIX-4785 : Incompatible SCR API
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1657502 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/bnd.bnd b/scr/bnd.bnd
index d618109..353ec6b 100644
--- a/scr/bnd.bnd
+++ b/scr/bnd.bnd
@@ -10,7 +10,7 @@
uses:="org.osgi.service.component";\
version:Version="1.3"
-Export-Package: org.apache.felix.scr;version=2.0, \
+Export-Package: org.apache.felix.scr;version=1.8.1, \
org.apache.felix.scr.component;version=1.1.0;mandatory:="status"; status="provisional", \
org.osgi.service.component;version=1.3;-split-package:=first, \
org.osgi.service.component.runtime.*;version=1.3, \
diff --git a/scr/src/main/java/org/apache/felix/scr/Component.java b/scr/src/main/java/org/apache/felix/scr/Component.java
new file mode 100644
index 0000000..eb4bc23
--- /dev/null
+++ b/scr/src/main/java/org/apache/felix/scr/Component.java
@@ -0,0 +1,403 @@
+/*
+ * 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.service.component.ComponentInstance;
+
+
+/**
+ * The <code>Component</code> interface represents a single component managed
+ * by the Service Component Runtime. Management agents may access the Component
+ * instances through the {@link ScrService}.
+ *
+ * @deprecated Use the ServiceComponentRuntime service.
+ */
+@Deprecated
+public interface Component
+{
+
+ /**
+ * The Component has just been created and is still disabled or it has
+ * been disabled by calling the {@link #disable()} method (value is 1).
+ */
+ static final int STATE_DISABLED = 1;
+
+ /**
+ * The Component is being enabled (value is 512). After the component has
+ * been enabled it enters the {@link #STATE_UNSATISFIED} state.
+ * @since 1.2
+ * @deprecated since 1.8.0
+ */
+ @Deprecated
+ static final int STATE_ENABLING = 512;
+
+ /**
+ * The Component has been enabled and is now going to be activated (value
+ * is 2).
+ * @deprecated as of version 1.2 the enabled state is collapsed into the
+ * {@link #STATE_UNSATISFIED} state. This status code is never returned
+ * from the {@link #getState()} method.
+ */
+ @Deprecated
+ static final int STATE_ENABLED = 2;
+
+ /**
+ * The Component activation failed because any dependency is not satisfied
+ * (value is 4).
+ */
+ static final int STATE_UNSATISFIED = 4;
+
+ /**
+ * The Component is currently being activated either because it has been
+ * enabled or because any dependency which was previously unsatisfied has
+ * become satisfied (value is 8).
+ * @deprecated since 1.8.0 transient states are no longer used
+ */
+ @Deprecated
+ static final int STATE_ACTIVATING = 8;
+
+ /**
+ * The Component has successfully been activated and is fully functional
+ * (value is 16). This is the state of immediate components after
+ * successful activation. Delayed and Service Factory Components enter
+ * this state when the service instance has actually been instantiated because
+ * the service has been acquired.
+ */
+ static final int STATE_ACTIVE = 16;
+
+ /**
+ * The Component has successfully been activated but is a Delayed or Service
+ * Factory Component pending instantiation on first use (value is 32).
+ */
+ static final int STATE_REGISTERED = 32;
+
+ /**
+ * The Component is a Component Factory ready to create Component instances
+ * with the <code>ComponentFactory.newInstance(Dictionary)</code> method
+ * or (if enabled with the <code>ds.factory.enabled</code> configuration) to
+ * manage Component instances from configuration data received from the
+ * Configuration Admin Service (value is 64).
+ */
+ static final int STATE_FACTORY = 64;
+
+ /**
+ * The Component is being deactivated either because it is being disabled
+ * or because a dependency is not satisfied any more (value is 128). After
+ * deactivation the Component enters the {@link #STATE_UNSATISFIED} state.
+ * @deprecated since 1.8.0 transient states are no longer used
+ */
+ @Deprecated
+ static final int STATE_DEACTIVATING = 128;
+
+ /**
+ * The Component is being disabled (value is 1024). After the component has
+ * been disabled it enters the {@link #STATE_DISABLED} state.
+ * @since 1.2
+ * @deprecated since 1.8.0 transient states are no longer used
+ */
+ @Deprecated
+ static final int STATE_DISABLING = 1024;
+
+ /**
+ * The Component is being disposed off (value is 2048). After the component
+ * has been disposed off it enters the {@link #STATE_DESTROYED} state.
+ * @since 1.2
+ * @deprecated since 1.8.0 transient states are no longer used
+ */
+ @Deprecated
+ static final int STATE_DISPOSING = 2048;
+
+ /**
+ * The Component has been destroyed and cannot be used any more (value is
+ * 256). This state is only used when the bundle declaring the component
+ * is being stopped and all components have to be removed.
+ * @deprecated as of version 1.2 this constant has been renamed to
+ * {@link #STATE_DISPOSED}.
+ */
+ @Deprecated
+ static final int STATE_DESTROYED = 256;
+
+ /**
+ * The Component has been disposed off and cannot be used any more (value is
+ * 256). This state is used when the bundle declaring the component
+ * is being stopped and all components have to be removed. This status is
+ * also the final status of a component after the
+ * <code>ComponentInstance.dispose()</code> method has been called.
+ * @since 1.2
+ */
+ static final int STATE_DISPOSED = 256;
+
+
+ /**
+ * Returns the component ID of this component. This ID is managed by the
+ * SCR. If the component is not currently enabled the ID might not be
+ * assigned to the component (yet) and this method will return -1 in this
+ * case.
+ */
+ long getId();
+
+
+ /**
+ * Returns the name of the component, which is also used as the service PID.
+ * This method provides access to the <code>name</code> attribute of the
+ * <code>component</code> element.
+ */
+ String getName();
+
+
+ /**
+ * Returns the current state of the Component, which is one of the
+ * <code>STATE_*</code> constants defined in this interface.
+ */
+ int getState();
+
+
+ /**
+ * Returns the <code>Bundle</code> declaring this component.
+ */
+ Bundle getBundle();
+
+
+ /**
+ * Returns the component factory name or <code>null</code> if this component
+ * is not defined as a component factory. This method provides access to
+ * the <code>factory</code> attribute of the <code>component</code>
+ * element.
+ */
+ String getFactory();
+
+
+ /**
+ * Returns <code>true</code> if this component is a service factory. This
+ * method returns the value of the <code>serviceFactory</code> attribute of
+ * the <code>service</code> element. If the component has no service
+ * element, this method returns <code>false</code>.
+ */
+ boolean isServiceFactory();
+
+
+ /**
+ * Returns the class name of the Component implementation. This method
+ * provides access to the <code>class</code> attribute of the
+ * <code>implementation</code> element.
+ */
+ String getClassName();
+
+
+ /**
+ * Returns whether the Component is declared to be enabled initially. This
+ * method provides access to the <code>enabled</code> attribute of the
+ * <code>component</code> element.
+ */
+ boolean isDefaultEnabled();
+
+
+ /**
+ * Returns whether the Component is an Immediate or a Delayed Component.
+ * This method provides access to the <code>immediate</code> attribute of
+ * the <code>component</code> element.
+ */
+ boolean isImmediate();
+
+
+ /**
+ * Returns an array of service names provided by this Component or
+ * <code>null</code> if the Component is not registered as a service. This
+ * method provides access to the <code>interface</code> attributes of the
+ * <code>provide</code> elements.
+ */
+ String[] getServices();
+
+
+ /**
+ * Returns the properties of the Component. The Dictionary returned is a
+ * private copy of the actual properties and contains the same entries as
+ * are used to register the Component as a service and are returned by
+ * the <code>ComponentContext.getProperties()</code> method.
+ */
+ Dictionary getProperties();
+
+
+ /**
+ * Returns an array of {@link Reference} instances representing the service
+ * references (or dependencies) of this Component. If the Component has no
+ * references, <code>null</code> is returned.
+ */
+ Reference[] getReferences();
+
+
+ /**
+ * Returns the <code>org.osgi.service.component.ComponentInstance</code>
+ * representing this component or <code>null</code> if this component
+ * is not been activated yet.
+ *
+ * @since 1.2
+ */
+ ComponentInstance getComponentInstance();
+
+
+ /**
+ * Returns the name of the method to be called when the component is being
+ * activated.
+ * <p>
+ * This method never returns <code>null</code>, that is, if this method is
+ * not declared in the component descriptor this method returns the
+ * default value <i>activate</i>.
+ *
+ * @since 1.2
+ */
+ String getActivate();
+
+
+ /**
+ * Returns <code>true</code> if the name of the method to be called on
+ * component activation (see {@link #getActivate()} is declared in the
+ * component descriptor or not.
+ * <p>
+ * For a component declared in a Declarative Services 1.0 descriptor, this
+ * method always returns <code>false</code>.
+ *
+ * @since 1.2
+ */
+ boolean isActivateDeclared();
+
+
+ /**
+ * Returns the name of the method to be called when the component is being
+ * deactivated.
+ * <p>
+ * This method never returns <code>null</code>, that is, if this method is
+ * not declared in the component descriptor this method returns the
+ * default value <i>deactivate</i>.
+ *
+ * @since 1.2
+ */
+ String getDeactivate();
+
+
+ /**
+ * Returns <code>true</code> if the name of the method to be called on
+ * component deactivation (see {@link #getDeactivate()} is declared in the
+ * component descriptor or not.
+ * <p>
+ * For a component declared in a Declarative Services 1.0 descriptor, this
+ * method always returns <code>false</code>.
+ *
+ * @since 1.2
+ */
+ boolean isDeactivateDeclared();
+
+
+ /**
+ * Returns the name of the method to be called when the component
+ * configuration has been updated or <code>null</code> if such a method is
+ * not declared in the component descriptor.
+ * <p>
+ * For a component declared in a Declarative Services 1.0 descriptor, this
+ * method always returns <code>null</code>.
+ *
+ * @since 1.2
+ */
+ String getModified();
+
+
+ /**
+ * Returns the configuration policy declared in the component descriptor.
+ * If the component descriptor is a Declarative Services 1.0 descriptor or
+ * no configuration policy has been declared, the default value
+ * <i>optional</i> is returned.
+ * <p>
+ * The returned string is one of the three policies defined in the
+ * Declarative Services specification 1.1:
+ * <dl>
+ * <dt>optional</dt>
+ * <dd>Configuration from the Configuration Admin service is supplied to
+ * the component if available. Otherwise the component is activated without
+ * Configuration Admin configuration. This is the default value reflecting
+ * the behaviour of Declarative Services 1.0</dd>
+ * <dt>require</dt>
+ * <dd>Configuration is required. The component remains unsatisfied until
+ * configuration is available from the Configuration Admin service.</dd>
+ * <dt>ignore</dt>
+ * <dd>Configuration is ignored. No Configuration Admin service
+ * configuration is supplied to the component.</dd>
+ * </dl>
+ *
+ * @since 1.2
+ */
+ String getConfigurationPolicy();
+
+ /**
+ * Returns the configuration pid declared in the component descriptor.
+ * The value is used to retrieve the component configuration from the
+ * OSGi configuration admin service. The value returned by this method
+ * depends on the Declarative Service namespace used by the component:
+ * <p>
+ * <dl>
+ * <dt>DS 1.0</dt>
+ * <dd>The component name is returned.</dd>
+ * <dt>DS 1.1</dt>
+ * <dd>The component name is returned, if it has been specified. If not specified,
+ * then the default component name is returned (that is the fully qualified component
+ * class name).
+ * <dt>DS 1.2</dt>
+ * <dd>The value of the configuration-pid attribute is returned if it has been specified.
+ * If not specified, then the same DS 1.1 rules are applied.</dd>
+ * </dl>
+ *
+ * @since 1.2
+ */
+ String getConfigurationPid();
+
+ /**
+ * Returns whether the configuration-pid has been declared in the descriptor
+ * or not.
+ *
+ * @return whether the configuration-pid has method has been declared in the descriptor
+ * or not.
+ * @since DS 1.2
+ */
+ boolean isConfigurationPidDeclared();
+
+ /**
+ * Enables this Component if it is disabled. If the Component is not
+ * currently {@link #STATE_DISABLED disabled} this method has no effect. If
+ * the Component is {@link #STATE_DESTROYED destroyed}, this method throws
+ * an <code>IllegalStateException</code>.
+ *
+ * @throws IllegalStateException If the Component is destroyed.
+ */
+ void enable();
+
+
+ /**
+ * Disables this Component if it is enabled. If the Component is already
+ * {@link #STATE_DISABLED disabled} this method has no effect. If the
+ * Component is {@link #STATE_DESTROYED destroyed}, this method throws an
+ * <code>IllegalStateException</code>.
+ *
+ * @throws IllegalStateException If the Component is destroyed.
+ */
+ void disable();
+
+}
diff --git a/scr/src/main/java/org/apache/felix/scr/Reference.java b/scr/src/main/java/org/apache/felix/scr/Reference.java
new file mode 100644
index 0000000..7371bc1
--- /dev/null
+++ b/scr/src/main/java/org/apache/felix/scr/Reference.java
@@ -0,0 +1,150 @@
+/*
+ * 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.ServiceReference;
+
+
+/**
+ * The <code>Reference</code> interface represents a single reference (or
+ * dependency) to a service used by a Component.
+ *
+ * @deprecated Use the ServiceComponentRuntime service.
+ */
+@Deprecated
+public interface Reference
+{
+
+ /**
+ * Returns the name of this Reference. This method provides access to the
+ * <code>name</code> attribute of the <code>referenec</code> element.
+ */
+ String getName();
+
+
+ /**
+ * Returns the name of the service used by this Reference. This method
+ * provides access to the <code>interface</code> attribute of the
+ * <code>reference</code> element.
+ */
+ String getServiceName();
+
+
+ /**
+ * Returns an array of references to the services bound to this Reference
+ * or <code>null</code> if no services are currently bound.
+ */
+ ServiceReference[] getServiceReferences();
+
+ /**
+ * added by mistake. Use getServiceReferences();
+ * @return
+ */
+ @Deprecated
+ ServiceReference[] getBoundServiceReferences();
+
+ /**
+ * Returns whether this reference is satisified. A {@link #isOptional() optional}
+ * component is always satsified. Otherwise <code>true</code> is only
+ * returned if at least one service is bound.
+ */
+ boolean isSatisfied();
+
+
+ /**
+ * Returns whether this reference is optional. This method provides access
+ * to the lower bound of the <code>cardinality</code> attribute of the
+ * <code>reference</code> element. In other words, this method returns
+ * <code>true</code> if the cardinality is <em>0..1</em> or <em>0..n</em>.
+ */
+ boolean isOptional();
+
+
+ /**
+ * Returns whether this reference is multiple. This method provides access
+ * to the upper bound of the <code>cardinality</code> attribute of the
+ * <code>reference</code> element. In other words, this method returns
+ * <code>true</code> if the cardinality is <em>0..n</em> or <em>1..n</em>.
+ */
+ boolean isMultiple();
+
+
+ /**
+ * Returns <code>true</code> if the reference is defined with static policy.
+ * This method provides access to the <code>policy</code> element of the
+ * <code>reference</code> element. <code>true</code> is returned if the
+ * policy is defined as <em>static</em>.
+ */
+ boolean isStatic();
+
+ /**
+ * Returns <code>true</code> if the reference is defined with reluctant
+ * policy option. This method provides access to the <code>policy-option</code>
+ * element of the <code>reference</code> element. <code>true</code> is
+ * returned if the policy option is defined as <em>reluctant</em>
+ *
+ * @since 1.7
+ */
+ boolean isReluctant();
+
+ /**
+ * Returns the value of the target property of this reference. Initially
+ * (without overwriting configuration) this method provides access to the
+ * <code>target</code> attribute of the <code>reference</code> element. If
+ * configuration overwrites the target property, this method returns the
+ * value of the Component property whose name is derived from the
+ * {@link #getName() reference name} plus the suffix <em>.target</em>. If
+ * no target property exists this method returns <code>null</code>.
+ */
+ String getTarget();
+
+
+ /**
+ * Returns the name of the method called if a service is being bound to
+ * the Component or <code>null</code> if no such method is configued. This
+ * method provides access to the <code>bind</code> attribute of the
+ * <code>reference</code> element.
+ */
+ String getBindMethodName();
+
+
+ /**
+ * Returns the name of the method called if a service is being unbound from
+ * the Component or <code>null</code> if no such method is configued. This
+ * method provides access to the <code>unbind</code> attribute of the
+ * <code>reference</code> element.
+ */
+ String getUnbindMethodName();
+
+
+ /**
+ * Returns the name of the method called if a bound service updates its
+ * service registration properties or <code>null</code> if no such method
+ * is configued. This method provides access to the <code>updated</code>
+ * attribute of the <code>reference</code> element.
+ * <p>
+ * For a component declared in a Declarative Services 1.0 and 1.1
+ * descriptor, this method always returns <code>null</code>.
+ *
+ * @since 1.4
+ */
+ String getUpdatedMethodName();
+
+}
diff --git a/scr/src/main/java/org/apache/felix/scr/ScrService.java b/scr/src/main/java/org/apache/felix/scr/ScrService.java
new file mode 100644
index 0000000..b892917
--- /dev/null
+++ b/scr/src/main/java/org/apache/felix/scr/ScrService.java
@@ -0,0 +1,92 @@
+/*
+ * 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;
+
+
+/**
+ * The <code>ScrService</code> represents the Declarative Services main
+ * controller also known as the Service Component Runtime or SCR for short.
+ * It provides access to the components managed the SCR.
+ *
+ * @deprecated Use the ServiceComponentRuntime service.
+ */
+@Deprecated
+public interface ScrService
+{
+
+ /**
+ * Returns an array of all components managed by this SCR instance. The
+ * components are returned in ascending order of their component.id. If
+ * there are no components currently managed by the SCR, <code>null</code>
+ * is returned.
+ *
+ * @return The components or <code>null</code> if there are none.
+ */
+ Component[] getComponents();
+
+
+ /**
+ * Returns the component whose component.id matches the given
+ * <code>componentId</code> or <code>null</code> if no component with the
+ * given id is currently managed.
+ *
+ * @param componentId The ID of the component to return
+ *
+ * @return The indicated component or <code>null</code> if no such
+ * component exists.
+ */
+ Component getComponent( long componentId );
+
+
+ /**
+ * Returns the components whose <code>component.name</code> matches the
+ * given <code>componentName</code> or <code>null</code> if no component
+ * with the given name is currently managed.
+ * <p>
+ * If the component name refers to a component factory component or a
+ * component configured with multiple factory configurations this method
+ * returns multiple component instances.
+ *
+ * @param componentName The name of the component to return
+ *
+ * @return The indicated components or <code>null</code> if no such
+ * component exists.
+ * @since 1.5 (Apache Felix Declarative Services 1.4.2)
+ */
+ Component[] getComponents( String componentName );
+
+
+ /**
+ * Reuturns an array of all components managed by this SCR instance on
+ * behalf of the given bundle. The components are returned in ascending
+ * order of their component.id. If there are no components managed by the
+ * SCR for the given bundle, <code>null</code> is returned.
+ *
+ * @param bundle The <code>Bundle</code> whose components are to be
+ * returned.
+ *
+ * @return The bundle's components or <code>null</code> if the bundle
+ * has none.
+ */
+ Component[] getComponents( Bundle bundle );
+
+}
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/Activator.java b/scr/src/main/java/org/apache/felix/scr/impl/Activator.java
index e9389d3..c081f88 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/Activator.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/Activator.java
@@ -76,8 +76,8 @@
// thread acting upon configurations
private ComponentActorThread m_componentActor;
-
- private ServiceRegistration<ServiceComponentRuntime> m_runtime_reg;
+
+ private ServiceRegistration<?> m_runtime_reg;
private ScrCommand m_scrCommand;
@@ -93,6 +93,7 @@
* @param context The <code>BundleContext</code> of the SCR implementation
* bundle.
*/
+ @Override
public void start( BundleContext context ) throws Exception
{
m_context = context;
@@ -103,7 +104,7 @@
// get the configuration
m_configuration.start( m_context ); //this will call restart, which calls super.start.
}
-
+
public void restart( boolean globalExtender )
{
BundleContext context;
@@ -137,16 +138,19 @@
{
log( LogService.LOG_ERROR, m_bundle, "Exception starting during restart", e );
}
-
+
}
+ @Override
protected void doStart() throws Exception {
// prepare component registry
m_componentBundles = new HashMap<Long, BundleComponentActivator>();
m_componentRegistry = new ComponentRegistry( m_context );
+
ServiceComponentRuntime runtime = new ServiceComponentRuntimeImpl(m_context, m_componentRegistry);
- m_runtime_reg = m_context.registerService(ServiceComponentRuntime.class, runtime, null);
+ m_runtime_reg = m_context.registerService(new String[] {ServiceComponentRuntime.class.getName()},
+ runtime, null);
// log SCR startup
log( LogService.LOG_INFO, m_bundle, " Version = {0}",
@@ -163,7 +167,8 @@
m_scrCommand = ScrCommand.register(m_context, runtime, m_configuration);
m_configuration.setScrCommand( m_scrCommand );
}
-
+
+ @Override
public void stop(BundleContext context) throws Exception
{
super.stop(context);
@@ -177,6 +182,7 @@
* which have been registered during the active life time of the SCR
* implementation bundle.
*/
+ @Override
public void doStop() throws Exception
{
// stop tracking
@@ -193,7 +199,11 @@
m_runtime_reg = null;
}
// dispose component registry
- m_componentRegistry.dispose();
+ if ( m_componentRegistry != null )
+ {
+ m_componentRegistry.dispose();
+ m_componentRegistry = null;
+ }
// terminate the actor thread
if ( m_componentActor != null )
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/ComponentRegistry.java b/scr/src/main/java/org/apache/felix/scr/impl/ComponentRegistry.java
index 6bc2688..3a48cb3 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/ComponentRegistry.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/ComponentRegistry.java
@@ -27,9 +27,10 @@
import java.util.Map;
import java.util.Set;
+import org.apache.felix.scr.ScrService;
import org.apache.felix.scr.impl.config.ComponentHolder;
-import org.apache.felix.scr.impl.config.ConfigurationSupport;
import org.apache.felix.scr.impl.config.ConfigurableComponentHolder;
+import org.apache.felix.scr.impl.config.ConfigurationSupport;
import org.apache.felix.scr.impl.manager.AbstractComponentManager;
import org.apache.felix.scr.impl.manager.DependencyManager;
import org.apache.felix.scr.impl.metadata.ComponentMetadata;
@@ -40,7 +41,6 @@
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.component.ComponentConstants;
import org.osgi.service.component.ComponentException;
@@ -121,7 +121,7 @@
private final Map<ServiceReference<?>, List<Entry<?, ?>>> m_missingDependencies = new HashMap<ServiceReference<?>, List<Entry<?, ?>>>( );
- protected ComponentRegistry( BundleContext context )
+ protected ComponentRegistry( final BundleContext context )
{
m_bundleContext = context;
m_componentHoldersByName = new HashMap<ComponentRegistryKey, ComponentHolder<?>>();
@@ -144,10 +144,8 @@
{
getOrCreateConfigurationSupport();
}
-
}
-
public void dispose()
{
m_bundleContext.removeServiceListener(this);
@@ -157,10 +155,10 @@
configurationSupport.dispose();
configurationSupport = null;
}
-
}
+
//---------- ComponentManager registration by component Id
/**
@@ -278,7 +276,7 @@
*/
final void registerComponentHolder( final ComponentRegistryKey key, ComponentHolder<?> componentHolder )
{
- Activator.log(LogService.LOG_DEBUG, null,
+ Activator.log(LogService.LOG_DEBUG, null,
"Registering component with pid {0} for bundle {1}",
new Object[] {componentHolder.getComponentMetadata().getConfigurationPid(), key.getBundleId()},
null);
@@ -314,7 +312,7 @@
set.add( componentHolder );
}
}
-
+
if (configurationSupport != null)
{
configurationSupport.configureComponentHolder(componentHolder);
@@ -363,6 +361,18 @@
}
/**
+ * We only need this for the ScrService implementation
+ * @param componentId
+ * @return
+ */
+ public final AbstractComponentManager<?> getComponentManagerById(final long componentId)
+ {
+ synchronized ( m_componentsById )
+ {
+ return m_componentsById.get( componentId );
+ }
+ }
+ /**
* Returns an array of all values currently stored in the component holders
* map. The entries in the array are either String types for component
* name reservations or {@link ComponentHolder} instances for actual
@@ -428,7 +438,7 @@
}
if (component != null) {
- Activator.log(LogService.LOG_DEBUG, null,
+ Activator.log(LogService.LOG_DEBUG, null,
"Unregistering component with pid {0} for bundle {1}",
new Object[] {component.getComponentMetadata().getConfigurationPid(), key.getBundleId()}, null);
synchronized (m_componentHoldersByPid)
@@ -623,5 +633,4 @@
return trackingCount;
}
}
-
}
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/config/ReferenceManager.java b/scr/src/main/java/org/apache/felix/scr/impl/config/ReferenceManager.java
index 4ea4d91..bc812ad 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/config/ReferenceManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/config/ReferenceManager.java
@@ -20,6 +20,7 @@
import java.util.List;
+import org.apache.felix.scr.impl.metadata.ReferenceMetadata;
import org.osgi.framework.ServiceReference;
public interface ReferenceManager<S, T> {
@@ -47,4 +48,5 @@
boolean isSatisfied();
+ ReferenceMetadata getReferenceMetadata();
}
\ No newline at end of file
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
index 07a5a8a..0280ddf 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
@@ -109,6 +109,11 @@
}
}
+ public ReferenceMetadata getReferenceMetadata()
+ {
+ return this.m_dependencyMetadata;
+ }
+
private static int defaultMinimumCardinality(ReferenceMetadata dependency)
{
return dependency.isOptional()? 0: 1;
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/runtime/ServiceComponentRuntimeImpl.java b/scr/src/main/java/org/apache/felix/scr/impl/runtime/ServiceComponentRuntimeImpl.java
index 438591a..9fe2b78 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/runtime/ServiceComponentRuntimeImpl.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/runtime/ServiceComponentRuntimeImpl.java
@@ -21,14 +21,22 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.Dictionary;
import java.util.HashMap;
+import java.util.Hashtable;
import java.util.List;
import java.util.Map;
+import org.apache.felix.scr.Component;
+import org.apache.felix.scr.Reference;
+import org.apache.felix.scr.ScrService;
+import org.apache.felix.scr.impl.BundleComponentActivator;
import org.apache.felix.scr.impl.ComponentRegistry;
import org.apache.felix.scr.impl.config.ComponentHolder;
import org.apache.felix.scr.impl.config.ComponentManager;
import org.apache.felix.scr.impl.config.ReferenceManager;
+import org.apache.felix.scr.impl.manager.AbstractComponentManager;
+import org.apache.felix.scr.impl.manager.SingleComponentManager;
import org.apache.felix.scr.impl.metadata.ComponentMetadata;
import org.apache.felix.scr.impl.metadata.ReferenceMetadata;
import org.osgi.dto.DTO;
@@ -38,6 +46,7 @@
import org.osgi.framework.ServiceReference;
import org.osgi.framework.dto.BundleDTO;
import org.osgi.framework.dto.ServiceReferenceDTO;
+import org.osgi.service.component.ComponentInstance;
import org.osgi.service.component.runtime.ServiceComponentRuntime;
import org.osgi.service.component.runtime.dto.ComponentConfigurationDTO;
import org.osgi.service.component.runtime.dto.ComponentDescriptionDTO;
@@ -46,7 +55,7 @@
import org.osgi.service.component.runtime.dto.UnsatisfiedReferenceDTO;
import org.osgi.util.promise.Promise;
-public class ServiceComponentRuntimeImpl implements ServiceComponentRuntime
+public class ServiceComponentRuntimeImpl implements ServiceComponentRuntime, ScrService
{
private static final String[] EMPTY = {};
@@ -344,4 +353,333 @@
return b;
}
+ // ScrService
+
+ /**
+ * @see org.apache.felix.scr.ScrService#getComponents()
+ */
+ public Component[] getComponents()
+ {
+ final List<ComponentHolder<?>> holders = componentRegistry.getComponentHolders();
+ ArrayList<Component> list = new ArrayList<Component>();
+ for ( ComponentHolder<?> holder: holders )
+ {
+ if ( holder != null )
+ {
+ final List<? extends ComponentManager<?>> components = holder.getComponents();
+ for ( ComponentManager<?> component: components )
+ {
+ list.add( new ComponentWrapper((AbstractComponentManager<?>)component) );
+ }
+ }
+ }
+
+ // nothing to return
+ if ( list.isEmpty() )
+ {
+ return null;
+ }
+
+ return list.toArray( new Component[list.size()] );
+ }
+
+
+ /**
+ * @see org.apache.felix.scr.ScrService#getComponents(org.osgi.framework.Bundle)
+ */
+ public Component[] getComponents( Bundle bundle )
+ {
+ final List<ComponentHolder<?>> holders = componentRegistry.getComponentHolders();
+ ArrayList<Component> list = new ArrayList<Component>();
+ for ( ComponentHolder<?> holder: holders )
+ {
+ if ( holder != null )
+ {
+ BundleComponentActivator activator = holder.getActivator();
+ if ( activator != null && activator.getBundleContext().getBundle() == bundle )
+ {
+ final List<? extends ComponentManager<?>> components = holder.getComponents();
+ for ( ComponentManager<?> component: components )
+ {
+ list.add( new ComponentWrapper((AbstractComponentManager<?>)component) );
+ }
+ }
+ }
+ }
+
+ // nothing to return
+ if ( list.isEmpty() )
+ {
+ return null;
+ }
+
+ return list.toArray( new Component[list.size()] );
+ }
+
+
+ /**
+ * @see org.apache.felix.scr.ScrService#getComponent(long)
+ */
+ public Component getComponent( long componentId )
+ {
+ final AbstractComponentManager<?> c = componentRegistry.getComponentManagerById(componentId);
+ if ( c != null )
+ {
+ return new ComponentWrapper(c);
+ }
+ return null;
+ }
+
+ /**
+ * @see org.apache.felix.scr.ScrService#getComponents(java.lang.String)
+ */
+ public Component[] getComponents( final String componentName )
+ {
+ final List<Component> list = new ArrayList<Component>();
+ final List<ComponentHolder<?>> holders = componentRegistry.getComponentHolders();
+ for ( ComponentHolder<?> holder: holders )
+ {
+ if ( holder.getComponentMetadata().getName().equals(componentName) )
+ {
+ final List<? extends ComponentManager<?>> components = holder.getComponents();
+ for ( ComponentManager<?> component: components )
+ {
+ list.add( new ComponentWrapper((AbstractComponentManager<?>)component) );
+ }
+ }
+ }
+
+ return ( list.isEmpty() ) ? null : list.toArray( new Component[list.size()] );
+ }
+
+
+ private static final class ComponentWrapper implements Component
+ {
+ private final AbstractComponentManager<?> mgr;
+
+ public ComponentWrapper(final AbstractComponentManager<?> mgr)
+ {
+ this.mgr = mgr;
+ }
+
+ public long getId()
+ {
+ return mgr.getId();
+ }
+
+ public String getName()
+ {
+ return mgr.getComponentMetadata().getName();
+ }
+
+ public int getState()
+ {
+ return mgr.getState();
+ }
+
+ public Bundle getBundle()
+ {
+ return mgr.getBundle();
+ }
+
+ public String getFactory()
+ {
+ return mgr.getComponentMetadata().getFactoryIdentifier();
+ }
+
+ public boolean isServiceFactory()
+ {
+ return mgr.getComponentMetadata().isFactory();
+ }
+
+ public String getClassName()
+ {
+ return mgr.getComponentMetadata().getImplementationClassName();
+ }
+
+ public boolean isDefaultEnabled()
+ {
+ return mgr.getComponentMetadata().isEnabled();
+ }
+
+ public boolean isImmediate()
+ {
+ return mgr.getComponentMetadata().isImmediate();
+ }
+
+ public String[] getServices()
+ {
+ if ( mgr.getComponentMetadata().getServiceMetadata() != null )
+ {
+ return mgr.getComponentMetadata().getServiceMetadata().getProvides();
+ }
+
+ return null;
+ }
+
+ public Dictionary getProperties()
+ {
+ return new Hashtable<String, Object>(mgr.getComponentMetadata().getProperties());
+ }
+
+ public Reference[] getReferences()
+ {
+ final List<? extends ReferenceManager<?, ?>> refs = mgr.getReferenceManagers();
+ if ( refs != null && refs.size() > 0 )
+ {
+ final List<Reference> list = new ArrayList<Reference>();
+ for(final ReferenceManager<?, ?> rm : refs)
+ {
+ list.add(new ReferenceWrapper(rm));
+ }
+ return list.toArray(
+ new Reference[list.size()] );
+ }
+
+ return null;
+ }
+
+ public ComponentInstance getComponentInstance()
+ {
+ if ( mgr instanceof SingleComponentManager<?> )
+ {
+ return ((SingleComponentManager<?>)mgr).getComponentInstance();
+ }
+
+ return null;
+ }
+
+ public String getActivate()
+ {
+ return mgr.getComponentMetadata().getActivate();
+ }
+
+ public boolean isActivateDeclared()
+ {
+ return mgr.getComponentMetadata().isActivateDeclared();
+ }
+
+ public String getDeactivate()
+ {
+ return mgr.getComponentMetadata().getDeactivate();
+ }
+
+ public boolean isDeactivateDeclared()
+ {
+ return mgr.getComponentMetadata().isDeactivateDeclared();
+ }
+
+ public String getModified()
+ {
+ return mgr.getComponentMetadata().getModified();
+ }
+
+ public String getConfigurationPolicy()
+ {
+ return mgr.getComponentMetadata().getConfigurationPolicy();
+ }
+
+ public String getConfigurationPid()
+ {
+ final List<String> pids = mgr.getComponentMetadata().getConfigurationPid();
+ if ( pids != null && pids.size() > 0 )
+ {
+ return pids.get(0);
+ }
+ return null;
+ }
+
+ public boolean isConfigurationPidDeclared()
+ {
+ return mgr.getComponentMetadata().isConfigurationPidDeclared();
+ }
+
+ public void enable()
+ {
+ mgr.enable(false);
+ }
+
+ public void disable()
+ {
+ mgr.disable(false);
+ }
+ }
+
+ private static final class ReferenceWrapper implements Reference
+ {
+ private final ReferenceManager<?, ?> mgr;
+
+ public ReferenceWrapper(final ReferenceManager<?, ?> mgr)
+ {
+ this.mgr = mgr;
+ }
+
+ public String getName()
+ {
+ return mgr.getReferenceMetadata().getName();
+ }
+
+ public String getServiceName()
+ {
+ return mgr.getReferenceMetadata().getInterface();
+ }
+
+ public ServiceReference[] getServiceReferences()
+ {
+ final List<ServiceReference<?>> refs = this.mgr.getServiceReferences();
+ return refs.toArray(new ServiceReference<?>[refs.size()]);
+ }
+
+ public ServiceReference<?>[] getBoundServiceReferences()
+ {
+ final List<ServiceReference<?>> refs = this.mgr.getServiceReferences();
+ return refs.toArray(new ServiceReference<?>[refs.size()]);
+ }
+
+ public boolean isSatisfied()
+ {
+ return mgr.isSatisfied();
+ }
+
+ public boolean isOptional()
+ {
+ return this.mgr.getReferenceMetadata().isOptional();
+ }
+
+ public boolean isMultiple()
+ {
+ return this.mgr.getReferenceMetadata().isMultiple();
+ }
+
+ public boolean isStatic()
+ {
+ return this.mgr.getReferenceMetadata().isStatic();
+ }
+
+ public boolean isReluctant()
+ {
+ return this.mgr.getReferenceMetadata().isReluctant();
+ }
+
+ public String getTarget()
+ {
+ return this.mgr.getTarget();
+ }
+
+ public String getBindMethodName()
+ {
+ return this.mgr.getReferenceMetadata().getBind();
+ }
+
+ public String getUnbindMethodName()
+ {
+ return this.mgr.getReferenceMetadata().getUnbind();
+ }
+
+ public String getUpdatedMethodName()
+ {
+ return this.mgr.getReferenceMetadata().getUpdated();
+ }
+
+ }
}