Return-Path: Delivered-To: apmail-felix-commits-archive@www.apache.org Received: (qmail 34616 invoked from network); 4 Feb 2011 10:50:49 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 4 Feb 2011 10:50:49 -0000 Received: (qmail 57037 invoked by uid 500); 4 Feb 2011 10:50:48 -0000 Delivered-To: apmail-felix-commits-archive@felix.apache.org Received: (qmail 56948 invoked by uid 500); 4 Feb 2011 10:50:47 -0000 Mailing-List: contact commits-help@felix.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@felix.apache.org Delivered-To: mailing list commits@felix.apache.org Received: (qmail 56941 invoked by uid 99); 4 Feb 2011 10:50:47 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 04 Feb 2011 10:50:47 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 04 Feb 2011 10:50:41 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 1651A23888FD; Fri, 4 Feb 2011 10:50:19 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1067145 - in /felix/trunk/scr: ./ src/main/java/org/apache/felix/scr/impl/ src/main/java/org/apache/felix/scr/impl/config/ src/test/java/org/apache/felix/scr/impl/config/ src/test/java/org/apache/felix/scr/integration/ Date: Fri, 04 Feb 2011 10:50:18 -0000 To: commits@felix.apache.org From: fmeschbe@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20110204105019.1651A23888FD@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: fmeschbe Date: Fri Feb 4 10:50:18 2011 New Revision: 1067145 URL: http://svn.apache.org/viewvc?rev=1067145&view=rev Log: FELIX-2578 Refactor SCR configuration setup to support late wiring of Configuration Admin API Refactored configuration admin support into a support class and unified component handling again. If Configuration Admin is there the support class provides configuration, otherwise the support class is not instantiated and components are not provided with additional configuration. Added: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurationSupport.java (with props) felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ImmediateComponentHolder.java (contents, props changed) - copied, changed from r1067144, felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ConfiguredComponentHolder.java felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ScrManagedService.java (with props) felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ScrManagedServiceMetaTypeProvider.java (contents, props changed) - copied, changed from r1067144, felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/MetaTypeProviderImpl.java felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ScrManagedServiceServiceFactory.java (with props) Removed: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/AbstractComponentHolder.java felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurationComponentRegistry.java felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ConfiguredComponentHolder.java felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/MetaTypeProviderImpl.java felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/UnconfiguredComponentHolder.java Modified: felix/trunk/scr/pom.xml felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/Activator.java felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/ComponentRegistry.java felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ScrConfiguration.java felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/config/ConfiguredComponentHolderTest.java felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java Modified: felix/trunk/scr/pom.xml URL: http://svn.apache.org/viewvc/felix/trunk/scr/pom.xml?rev=1067145&r1=1067144&r2=1067145&view=diff ============================================================================== --- felix/trunk/scr/pom.xml (original) +++ felix/trunk/scr/pom.xml Fri Feb 4 10:50:18 2011 @@ -219,18 +219,6 @@ org.osgi.service.packageadmin;version="[1.2,2)";resolution:=optional, - org.osgi.service.cm;version="[1.2,2)", - - - org.osgi.service.metatype;version="[1.1,2)";resolution:=optional, - - org.osgi.service.component;version="[1.1,1.2)" + + + org.osgi.service.cm;version="[1.2,2)", + + + org.osgi.service.metatype;version="[1.1,2)" + kxml2 Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/Activator.java URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/Activator.java?rev=1067145&r1=1067144&r2=1067145&view=diff ============================================================================== --- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/Activator.java (original) +++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/Activator.java Fri Feb 4 10:50:18 2011 @@ -23,7 +23,6 @@ import java.io.PrintStream; import java.util.HashMap; import java.util.Map; -import org.apache.felix.scr.impl.config.ConfigurationComponentRegistry; import org.apache.felix.scr.impl.config.ScrConfiguration; import org.osgi.framework.Bundle; import org.osgi.framework.BundleActivator; @@ -94,7 +93,7 @@ public class Activator implements Bundle // prepare component registry m_componentBundles = new HashMap(); - m_componentRegistry = createComponentRegistry( context); + m_componentRegistry = new ComponentRegistry( context ); // get the configuration m_configuration = new ScrConfiguration( context ); @@ -368,22 +367,6 @@ public class Activator implements Bundle } - public static ComponentRegistry createComponentRegistry( BundleContext bundleContext ) - { - try - { - return new ConfigurationComponentRegistry( bundleContext ); - } - catch ( Throwable t ) - { - log( LogService.LOG_INFO, bundleContext.getBundle(), - "ConfigurationAdmin supporting ComponentRegistry not available, not using ConfigurationAdmin", t ); - } - - return new ComponentRegistry( bundleContext ); - } - - /** * Method to actually emit the log message. If the LogService is available, * the message will be logged through the LogService. Otherwise the message Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/ComponentRegistry.java URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/ComponentRegistry.java?rev=1067145&r1=1067144&r2=1067145&view=diff ============================================================================== --- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/ComponentRegistry.java (original) +++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/ComponentRegistry.java Fri Feb 4 10:50:18 2011 @@ -28,13 +28,18 @@ import java.util.Map; import org.apache.felix.scr.Component; import org.apache.felix.scr.ScrService; import org.apache.felix.scr.impl.config.ComponentHolder; -import org.apache.felix.scr.impl.config.UnconfiguredComponentHolder; +import org.apache.felix.scr.impl.config.ConfigurationSupport; +import org.apache.felix.scr.impl.config.ImmediateComponentHolder; import org.apache.felix.scr.impl.manager.AbstractComponentManager; import org.apache.felix.scr.impl.manager.ComponentFactoryImpl; import org.apache.felix.scr.impl.metadata.ComponentMetadata; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceEvent; +import org.osgi.framework.ServiceListener; +import org.osgi.framework.ServiceReference; import org.osgi.framework.ServiceRegistration; import org.osgi.service.component.ComponentException; @@ -45,9 +50,15 @@ import org.osgi.service.component.Compon * registers itself as the {@link ScrService} to support access to the * registered components. */ -public class ComponentRegistry implements ScrService +public class ComponentRegistry implements ScrService, ServiceListener { + // the name of the ConfigurationAdmin service + public static final String CONFIGURATION_ADMIN = "org.osgi.service.cm.ConfigurationAdmin"; + + // the bundle context + private BundleContext m_bundleContext; + /** * The map of known components indexed by component name. The values are * either the component names (for name reservations) or implementations @@ -88,13 +99,27 @@ public class ComponentRegistry implement */ private ServiceRegistration m_registration; + // ConfigurationAdmin support -- created on demand upon availability of + // the ConfigurationAdmin service + private ConfigurationSupport configurationSupport; protected ComponentRegistry( BundleContext context ) { + m_bundleContext = context; m_componentHoldersByName = new HashMap(); m_componentsById = new HashMap(); m_componentCounter = -1; + // keep me informed on ConfigurationAdmin state changes + try + { + context.addServiceListener( this, "(objectclass=" + CONFIGURATION_ADMIN + ")" ); + } + catch ( InvalidSyntaxException ise ) + { + // not expected (filter is tested valid) + } + // register as ScrService Dictionary props = new Hashtable(); props.put( Constants.SERVICE_DESCRIPTION, "Declarative Services Management Agent" ); @@ -106,6 +131,14 @@ public class ComponentRegistry implement public void dispose() { + m_bundleContext.removeServiceListener(this); + + if (configurationSupport != null) + { + configurationSupport.dispose(); + configurationSupport = null; + } + if ( m_registration != null ) { m_registration.unregister(); @@ -378,18 +411,69 @@ public class ComponentRegistry implement */ public ComponentHolder createComponentHolder( BundleComponentActivator activator, ComponentMetadata metadata ) { - if ( metadata.isFactory() ) + ComponentHolder holder; + + 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 - return new ComponentFactoryImpl( activator, metadata ); + holder = new ComponentFactoryImpl(activator, metadata); + } + else + { + holder = new ImmediateComponentHolder(activator, metadata); } - return new UnconfiguredComponentHolder( activator, metadata ); + if (configurationSupport != null) + { + configurationSupport.configureComponentHolder(holder); + } + + return holder; } + //---------- ServiceListener + + /** + * Called if the Configuration Admin service changes state. This + * implementation is mainly interested in the Configuration Admin service + * being registered after the Declarative Services setup to be able + * to forward existing configuration. + * + * @param event The service change event + */ + public void serviceChanged(ServiceEvent event) + { + if (event.getType() == ServiceEvent.REGISTERED) + { + this.configurationSupport = new ConfigurationSupport(this.m_bundleContext, this); + + final ServiceReference caRef = event.getServiceReference(); + final Object service = m_bundleContext.getService(caRef); + if (service != null) + { + try + { + this.configurationSupport.configureComponentHolders(caRef, service); + } + finally + { + m_bundleContext.ungetService(caRef); + } + } + } + else if (event.getType() == ServiceEvent.UNREGISTERING) + { + if (configurationSupport != null) + { + this.configurationSupport.dispose(); + this.configurationSupport = null; + } + } + } + //---------- Helper method /** Added: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurationSupport.java URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurationSupport.java?rev=1067145&view=auto ============================================================================== --- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurationSupport.java (added) +++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurationSupport.java Fri Feb 4 10:50:18 2011 @@ -0,0 +1,301 @@ +/* + * 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.impl.config; + +import java.io.IOException; +import java.util.Dictionary; +import java.util.Hashtable; + +import org.apache.felix.scr.impl.Activator; +import org.apache.felix.scr.impl.BundleComponentActivator; +import org.apache.felix.scr.impl.ComponentRegistry; +import org.osgi.framework.BundleContext; +import org.osgi.framework.Constants; +import org.osgi.framework.InvalidSyntaxException; +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.cm.ConfigurationEvent; +import org.osgi.service.cm.ConfigurationListener; +import org.osgi.service.log.LogService; + +public class ConfigurationSupport implements ConfigurationListener +{ + + final ComponentRegistry m_registry; + + // the service m_registration of the ConfigurationListener service + private ServiceRegistration m_registration; + + public ConfigurationSupport(final BundleContext bundleContext, final ComponentRegistry registry) + { + this.m_registry = registry; + + // register as listener for configurations + Dictionary props = new Hashtable(); + props.put(Constants.SERVICE_DESCRIPTION, "Declarative Services Configuration Support Listener"); + props.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation"); + this.m_registration = bundleContext.registerService(new String[] + { "org.osgi.service.cm.ConfigurationListener" }, this, props); + } + + public void dispose() + { + if (this.m_registration != null) + { + this.m_registration.unregister(); + this.m_registration = null; + } + } + + // ---------- BaseConfigurationSupport overwrites + + public void configureComponentHolder(final ComponentHolder holder) + { + + // 112.7 configure unless configuration not required + if (!holder.getComponentMetadata().isConfigurationIgnored()) + { + final BundleContext bundleContext = holder.getActivator().getBundleContext(); + final String bundleLocation = bundleContext.getBundle().getLocation(); + final String name = holder.getComponentMetadata().getName(); + + final ServiceReference caRef = bundleContext.getServiceReference(ComponentRegistry.CONFIGURATION_ADMIN); + if (caRef != null) + { + final ConfigurationAdmin ca = (ConfigurationAdmin) bundleContext.getService(caRef); + if (ca != null) + { + try + { + final Configuration[] factory = findFactoryConfigurations(ca, name); + if (factory != null) + { + for (int i = 0; i < factory.length; i++) + { + final String pid = factory[i].getPid(); + final Dictionary props = getConfiguration(ca, pid, bundleLocation); + holder.configurationUpdated(pid, props); + } + } + else + { + // check for configuration and configure the holder + final Configuration singleton = findSingletonConfiguration(ca, name); + if (singleton != null) + { + final Dictionary props = getConfiguration(ca, name, bundleLocation); + holder.configurationUpdated(name, props); + } + } + } + finally + { + bundleContext.ungetService(caRef); + } + } + } + } + } + + // ---------- ServiceListener + + public void configureComponentHolders(final ServiceReference configurationAdminReference, + final Object configurationAdmin) + { + if (configurationAdmin instanceof ConfigurationAdmin) + { + Configuration[] configs = findConfigurations((ConfigurationAdmin) configurationAdmin, null); + if (configs != null) + { + for (int i = 0; i < configs.length; i++) + { + ConfigurationEvent cfgEvent = new ConfigurationEvent(configurationAdminReference, + ConfigurationEvent.CM_UPDATED, configs[i].getFactoryPid(), configs[i].getPid()); + configurationEvent(cfgEvent); + } + } + } + } + + // ---------- ConfigurationListener + + /** + * Called by the Configuration Admin service if a configuration is updated + * or removed. + *

+ * This method is really only called upon configuration changes; it is not + * called for existing configurations upon startup of the Configuration + * Admin service. To bridge this gap, the + * {@link #serviceChanged(ServiceEvent)} method called when the + * Configuration Admin service is registered calls this method for all + * existing configurations to be able to foward existing configurations to + * components. + * + * @param event The configuration change event + */ + public void configurationEvent(ConfigurationEvent event) + { + final String pid = event.getPid(); + final String factoryPid = event.getFactoryPid(); + + final ComponentHolder cm; + if (factoryPid == null) + { + cm = this.m_registry.getComponentHolder(pid); + } + else + { + cm = this.m_registry.getComponentHolder(factoryPid); + } + + Activator.log(LogService.LOG_DEBUG, null, "configurationEvent: Handling " + + ((event.getType() == ConfigurationEvent.CM_DELETED) ? "DELETE" : "UPDATE") + " of Configuration PID=" + + pid, null); + + if (cm != null && !cm.getComponentMetadata().isConfigurationIgnored()) + { + switch (event.getType()) + { + case ConfigurationEvent.CM_DELETED: + cm.configurationDeleted(pid); + break; + + case ConfigurationEvent.CM_UPDATED: + final BundleComponentActivator activator = cm.getActivator(); + if (activator == null) + { + break; + } + + final BundleContext bundleContext = activator.getBundleContext(); + if (bundleContext == null) + { + break; + } + + final ServiceReference caRef = bundleContext + .getServiceReference(ComponentRegistry.CONFIGURATION_ADMIN); + if (caRef != null) + { + try + { + final ConfigurationAdmin ca = (ConfigurationAdmin) bundleContext.getService(caRef); + if (ca != null) + { + try + { + final Dictionary dict = getConfiguration(ca, pid, bundleContext.getBundle() + .getLocation()); + if (dict != null) + { + cm.configurationUpdated(pid, dict); + } + } + finally + { + bundleContext.ungetService(caRef); + } + } + } + catch (IllegalStateException ise) + { + // If the bundle has been stopped conurrently + } + } + break; + + default: + Activator.log(LogService.LOG_WARNING, null, "Unknown ConfigurationEvent type " + event.getType(), + null); + } + } + } + + private Dictionary getConfiguration(final ConfigurationAdmin ca, final String pid, final String bundleLocation) + { + try + { + final Configuration cfg = ca.getConfiguration(pid); + if (bundleLocation.equals(cfg.getBundleLocation()) || Activator.hasCtWorkaround()) + { + return cfg.getProperties(); + } + + // configuration belongs to another bundle, cannot be used here + Activator.log(LogService.LOG_ERROR, null, "Cannot use configuration pid=" + pid + " for bundle " + + bundleLocation + " because it belongs to bundle " + cfg.getBundleLocation(), null); + } + catch (IOException ioe) + { + Activator.log(LogService.LOG_WARNING, null, "Failed reading configuration for pid=" + pid, ioe); + } + + return null; + } + + /** + * Returns the configuration whose PID equals the given pid. If no such + * configuration exists, null is returned. + * + * @param ctx + * @param pid + * @return + */ + public Configuration findSingletonConfiguration(final ConfigurationAdmin ca, final String pid) + { + final String filter = "(service.pid=" + pid + ")"; + final Configuration[] cfg = findConfigurations(ca, filter); + return (cfg == null || cfg.length == 0) ? null : cfg[0]; + } + + /** + * Returns all configurations whose factory PID equals the given factory PID + * or null if no such configurations exist + * + * @param ctx + * @param factoryPid + * @return + */ + public Configuration[] findFactoryConfigurations(final ConfigurationAdmin ca, final String factoryPid) + { + final String filter = "(service.factoryPid=" + factoryPid + ")"; + return findConfigurations(ca, filter); + } + + private Configuration[] findConfigurations(final ConfigurationAdmin ca, final String filter) + { + try + { + return ca.listConfigurations(filter); + } + catch (IOException ioe) + { + Activator.log(LogService.LOG_WARNING, null, "Problem listing configurations for filter=" + filter, ioe); + } + catch (InvalidSyntaxException ise) + { + Activator.log(LogService.LOG_ERROR, null, "Invalid Configuration selection filter " + filter, ise); + } + + // no factories in case of problems + return null; + } +} Propchange: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurationSupport.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurationSupport.java ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Rev Url Copied: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ImmediateComponentHolder.java (from r1067144, felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ConfiguredComponentHolder.java) URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ImmediateComponentHolder.java?p2=felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ImmediateComponentHolder.java&p1=felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ConfiguredComponentHolder.java&r1=1067144&r2=1067145&rev=1067145&view=diff ============================================================================== --- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ConfiguredComponentHolder.java (original) +++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ImmediateComponentHolder.java Fri Feb 4 10:50:18 2011 @@ -26,7 +26,9 @@ import java.util.Map; import org.apache.felix.scr.Component; import org.apache.felix.scr.impl.BundleComponentActivator; +import org.apache.felix.scr.impl.manager.DelayedComponentManager; import org.apache.felix.scr.impl.manager.ImmediateComponentManager; +import org.apache.felix.scr.impl.manager.ServiceFactoryComponentManager; import org.apache.felix.scr.impl.metadata.ComponentMetadata; import org.osgi.service.component.ComponentConstants; @@ -52,10 +54,20 @@ import org.osgi.service.component.Compon * service.factoryPid equals the component name. * */ -public class ConfiguredComponentHolder extends AbstractComponentHolder +public class ImmediateComponentHolder implements ComponentHolder { /** + * The activator owning the per-bundle components + */ + private final BundleComponentActivator m_activator; + + /** + * The {@link ComponentMetadata} describing the held component(s) + */ + private final ComponentMetadata m_componentMetadata; + + /** * A map of components configured with factory configuration. The indices * are the PIDs (service.pid) of the configuration objects. * The values are the {@link ImmediateComponentManager component instances} @@ -91,15 +103,60 @@ public class ConfiguredComponentHolder e private boolean m_enabled; - ConfiguredComponentHolder( final BundleComponentActivator activator, final ComponentMetadata metadata ) + public ImmediateComponentHolder( final BundleComponentActivator activator, final ComponentMetadata metadata ) { - super( activator, metadata ); - + this.m_activator = activator; + this.m_componentMetadata = metadata; this.m_components = new HashMap(); this.m_singleComponent = createComponentManager(); this.m_enabled = false; } + protected ImmediateComponentManager createComponentManager() + { + + ImmediateComponentManager manager; + if ( m_componentMetadata.isFactory() ) + { + throw new IllegalArgumentException( "Cannot create component factory for " + m_componentMetadata.getName() ); + } + else if ( m_componentMetadata.isImmediate() ) + { + manager = new ImmediateComponentManager( m_activator, this, m_componentMetadata ); + } + else if ( m_componentMetadata.getServiceMetadata() != null ) + { + if ( m_componentMetadata.getServiceMetadata().isServiceFactory() ) + { + manager = new ServiceFactoryComponentManager( m_activator, this, m_componentMetadata ); + } + else + { + manager = new DelayedComponentManager( m_activator, this, m_componentMetadata ); + } + } + else + { + // if we get here, which is not expected after all, we fail + throw new IllegalArgumentException( "Cannot create a component manager for " + + m_componentMetadata.getName() ); + } + + return manager; + } + + + public final BundleComponentActivator getActivator() + { + return m_activator; + } + + + public final ComponentMetadata getComponentMetadata() + { + return m_componentMetadata; + } + /** * The configuration with the given pid @@ -128,7 +185,7 @@ public class ConfiguredComponentHolder e return; } - if ( pid.equals( getComponentName() ) ) + if ( pid.equals( getComponentMetadata().getName() ) ) { // singleton configuration deleted m_singleComponent.reconfigure( null ); @@ -195,7 +252,7 @@ public class ConfiguredComponentHolder e return; } - if ( pid.equals( getComponentName() ) ) + if ( pid.equals( getComponentMetadata().getName() ) ) { // singleton configuration has pid equal to component name m_singleComponent.reconfigure( props ); Propchange: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ImmediateComponentHolder.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ImmediateComponentHolder.java ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Rev Url Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ScrConfiguration.java URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ScrConfiguration.java?rev=1067145&r1=1067144&r2=1067145&view=diff ============================================================================== --- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ScrConfiguration.java (original) +++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ScrConfiguration.java Fri Feb 4 10:50:18 2011 @@ -25,10 +25,7 @@ import java.util.Hashtable; import org.apache.felix.scr.impl.Activator; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; -import org.osgi.service.cm.ConfigurationException; -import org.osgi.service.cm.ManagedService; import org.osgi.service.log.LogService; -import org.osgi.service.metatype.MetaTypeProvider; /** @@ -68,8 +65,6 @@ public class ScrConfiguration private boolean factoryEnabled; - private boolean ctWorkaround; - static final String PID = "org.apache.felix.scr.ScrService"; public ScrConfiguration( BundleContext bundleContext ) @@ -80,35 +75,12 @@ public class ScrConfiguration configure( null ); // listen for Configuration Admin configuration - try - { - Object service = new ManagedService() - { - public void updated( Dictionary properties ) throws ConfigurationException - { - configure( properties ); - } - }; - // add meta type provider if interfaces are available - Object enhancedService = tryToCreateMetaTypeProvider(service); - final String[] interfaceNames; - if ( enhancedService == null ) - { - interfaceNames = new String[] {ManagedService.class.getName()}; - } - else - { - interfaceNames = new String[] {ManagedService.class.getName(), MetaTypeProvider.class.getName()}; - service = enhancedService; - } - Dictionary props = new Hashtable(); - props.put( Constants.SERVICE_PID, PID ); - bundleContext.registerService( interfaceNames, service, props ); - } - catch ( Throwable t ) - { - // don't care - } + Dictionary props = new Hashtable(); + props.put(Constants.SERVICE_PID, PID); + props.put(Constants.SERVICE_DESCRIPTION, "SCR Configurator"); + props.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation"); + bundleContext.registerService("org.osgi.service.cm.ManagedService", new ScrManagedServiceServiceFactory(this), + props); } void configure( Dictionary config ) @@ -223,19 +195,4 @@ public class ScrConfiguration // default log level (errors only) return LogService.LOG_ERROR; } - - - private Object tryToCreateMetaTypeProvider( final Object managedService ) - { - try - { - return new MetaTypeProviderImpl( getDefaultLogLevel(), getDefaultFactoryEnabled(), - ( ManagedService ) managedService ); - } - catch ( Throwable t ) - { - // we simply ignore this - } - return null; - } } Added: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ScrManagedService.java URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ScrManagedService.java?rev=1067145&view=auto ============================================================================== --- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ScrManagedService.java (added) +++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ScrManagedService.java Fri Feb 4 10:50:18 2011 @@ -0,0 +1,51 @@ +/* + * 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.impl.config; + +import java.util.Dictionary; + +import org.osgi.service.cm.ConfigurationException; +import org.osgi.service.cm.ManagedService; + +/** + * The ScrManagedService receives configuration for the Declarative + * Services Runtime itself. This class is instantiated in a ServiceFactory + * manner by the {@link ScrManagedServiceServiceFactory} when the Configuration + * Admin service implementation and API is available. + */ +public class ScrManagedService implements ManagedService +{ + + private final ScrConfiguration scrConfiguration; + + protected final ScrConfiguration getScrConfiguration() + { + return scrConfiguration; + } + + public ScrManagedService(final ScrConfiguration scrConfiguration) + { + this.scrConfiguration = scrConfiguration; + } + + public void updated(Dictionary properties) throws ConfigurationException + { + this.scrConfiguration.configure(properties); + } +} Propchange: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ScrManagedService.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ScrManagedService.java ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Rev Url Copied: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ScrManagedServiceMetaTypeProvider.java (from r1067144, felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/MetaTypeProviderImpl.java) URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ScrManagedServiceMetaTypeProvider.java?p2=felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ScrManagedServiceMetaTypeProvider.java&p1=felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/MetaTypeProviderImpl.java&r1=1067144&r2=1067145&rev=1067145&view=diff ============================================================================== --- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/MetaTypeProviderImpl.java (original) +++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ScrManagedServiceMetaTypeProvider.java Fri Feb 4 10:50:18 2011 @@ -20,38 +20,29 @@ package org.apache.felix.scr.impl.config import java.io.InputStream; import java.util.ArrayList; -import java.util.Dictionary; -import org.osgi.service.cm.ConfigurationException; import org.osgi.service.cm.ManagedService; import org.osgi.service.metatype.AttributeDefinition; import org.osgi.service.metatype.MetaTypeProvider; import org.osgi.service.metatype.ObjectClassDefinition; -public class MetaTypeProviderImpl - implements MetaTypeProvider, ManagedService +/** + * The ScrManagedServiceMetaTypeProvider receives the Declarative + * Services Runtime configuration (by extending the {@link ScrManagedService} + * class but also provides a MetaType Service ObjectClassDefinition. + */ +class ScrManagedServiceMetaTypeProvider extends ScrManagedService + implements MetaTypeProvider { - private final int logLevel; - - private final boolean factoryEnabled; - - private final ManagedService delegatee; - - public MetaTypeProviderImpl(final int logLevel, - final boolean factoryEnabled, - final ManagedService delegatee) + static ManagedService create(final ScrConfiguration scrConfiguration) { - this.logLevel = logLevel; - this.factoryEnabled = factoryEnabled; - this.delegatee = delegatee; + return new ScrManagedServiceMetaTypeProvider(scrConfiguration); } - private ObjectClassDefinition ocd; - - public void updated(Dictionary properties) throws ConfigurationException + private ScrManagedServiceMetaTypeProvider(final ScrConfiguration scrConfiguration) { - this.delegatee.updated(properties); + super(scrConfiguration); } /** @@ -72,68 +63,61 @@ public class MetaTypeProviderImpl return null; } - if ( ocd == null ) - { - final ArrayList adList = new ArrayList(); - - adList.add( new AttributeDefinitionImpl( ScrConfiguration.PROP_LOGLEVEL, "SCR Log Level", - "Allows limiting the amount of logging information sent to the OSGi LogService." + - " Supported values are DEBUG, INFO, WARN, and ERROR. Default is ERROR.", - AttributeDefinition.INTEGER, - new String[] {String.valueOf(this.logLevel)}, 0, - new String[] {"Debug", "Information", "Warnings", "Error"}, - new String[] {"4", "3", "2", "1"} ) ); - - adList.add( new AttributeDefinitionImpl( ScrConfiguration.PROP_FACTORY_ENABLED, "Extended Factory Components", - "Whether or not to enable the support for creating Factory Component instances based on factory configuration." + - " This is an Apache Felix SCR specific extension, explicitly not supported by the Declarative Services " + - "specification. Reliance on this feature prevent the component from being used with other Declarative " + - "Services implementations. The default value is false to disable this feature.", - this.factoryEnabled ) ); - - ocd = new ObjectClassDefinition() - { - - private final AttributeDefinition[] attrs = ( AttributeDefinition[] ) adList - .toArray( new AttributeDefinition[adList.size()] ); - + final ArrayList adList = new ArrayList(); - public String getName() - { - return "Apache Felix Declarative Service Implementation"; - } - - - public InputStream getIcon( int arg0 ) - { - return null; - } + adList.add(new AttributeDefinitionImpl(ScrConfiguration.PROP_LOGLEVEL, "SCR Log Level", + "Allows limiting the amount of logging information sent to the OSGi LogService." + + " Supported values are DEBUG, INFO, WARN, and ERROR. Default is ERROR.", AttributeDefinition.INTEGER, + new String[] + { String.valueOf(this.getScrConfiguration().getLogLevel()) }, 0, new String[] + { "Debug", "Information", "Warnings", "Error" }, new String[] + { "4", "3", "2", "1" })); + + adList + .add(new AttributeDefinitionImpl( + ScrConfiguration.PROP_FACTORY_ENABLED, + "Extended Factory Components", + "Whether or not to enable the support for creating Factory Component instances based on factory configuration." + + " This is an Apache Felix SCR specific extension, explicitly not supported by the Declarative Services " + + "specification. Reliance on this feature prevent the component from being used with other Declarative " + + "Services implementations. The default value is false to disable this feature.", this + .getScrConfiguration().isFactoryEnabled())); + return new ObjectClassDefinition() + { - public String getID() - { - return ScrConfiguration.PID; - } + private final AttributeDefinition[] attrs = (AttributeDefinition[]) adList + .toArray(new AttributeDefinition[adList.size()]); + public String getName() + { + return "Apache Felix Declarative Service Implementation"; + } - public String getDescription() - { - return "Configuration for the Apache Felix Declarative Services Implementation." + - " This configuration overwrites configuration defined in framework properties of the same names."; - } + public InputStream getIcon(int arg0) + { + return null; + } + public String getID() + { + return ScrConfiguration.PID; + } - public AttributeDefinition[] getAttributeDefinitions( int filter ) - { - return ( filter == OPTIONAL ) ? null : attrs; - } - }; - } + public String getDescription() + { + return "Configuration for the Apache Felix Declarative Services Implementation." + + " This configuration overwrites configuration defined in framework properties of the same names."; + } - return ocd; + public AttributeDefinition[] getAttributeDefinitions(int filter) + { + return (filter == OPTIONAL) ? null : attrs; + } + }; } - class AttributeDefinitionImpl implements AttributeDefinition + private static class AttributeDefinitionImpl implements AttributeDefinition { private final String id; Propchange: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ScrManagedServiceMetaTypeProvider.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ScrManagedServiceMetaTypeProvider.java ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Rev Url Propchange: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ScrManagedServiceMetaTypeProvider.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ScrManagedServiceServiceFactory.java URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ScrManagedServiceServiceFactory.java?rev=1067145&view=auto ============================================================================== --- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ScrManagedServiceServiceFactory.java (added) +++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ScrManagedServiceServiceFactory.java Fri Feb 4 10:50:18 2011 @@ -0,0 +1,67 @@ +/* + * 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.impl.config; + +import org.apache.felix.scr.impl.Activator; +import org.osgi.framework.Bundle; +import org.osgi.framework.ServiceFactory; +import org.osgi.framework.ServiceRegistration; +import org.osgi.service.log.LogService; + +/** + * The ScrManagedServiceServiceFactory is the ServiceFactory + * registered on behalf of the {@link ScrManagedService} (or + * {@link ScrManagedServiceMetaTypeProvider}, resp.) to create the instance on + * demand once it is used by the Configuration Admin Service or the MetaType + * Service. + *

+ * In contrast to the {@link ScrManagedService} and + * {@link ScrManagedServiceMetaTypeProvider} classes, this class only requires + * core OSGi API and thus may be instantiated without the Configuration Admin + * and/or MetaType Service API actually available at the time of instantiation. + */ +public class ScrManagedServiceServiceFactory implements ServiceFactory +{ + private final ScrConfiguration scrConfiguration; + + public ScrManagedServiceServiceFactory(final ScrConfiguration scrConfiguration) + { + this.scrConfiguration = scrConfiguration; + } + + public Object getService(Bundle bundle, ServiceRegistration registration) + { + try + { + return ScrManagedServiceMetaTypeProvider.create(this.scrConfiguration); + } + catch (Throwable t) + { + // assume MetaType Service API not available + Activator.log(LogService.LOG_ERROR, null, "Cannot create MetaType providing ManagedService", t); + } + return new ScrManagedService(this.scrConfiguration); + } + + public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) + { + // nothing really todo; GC will do the rest + } + +} Propchange: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ScrManagedServiceServiceFactory.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ScrManagedServiceServiceFactory.java ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Rev Url Modified: felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/config/ConfiguredComponentHolderTest.java URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/config/ConfiguredComponentHolderTest.java?rev=1067145&r1=1067144&r2=1067145&view=diff ============================================================================== --- felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/config/ConfiguredComponentHolderTest.java (original) +++ felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/config/ConfiguredComponentHolderTest.java Fri Feb 4 10:50:18 2011 @@ -178,11 +178,11 @@ public class ConfiguredComponentHolderTe } - private static ImmediateComponentManager getSingleManager( ConfiguredComponentHolder holder ) + private static ImmediateComponentManager getSingleManager( ImmediateComponentHolder holder ) { try { - final Field f = ConfiguredComponentHolder.class.getDeclaredField( "m_singleComponent" ); + final Field f = ImmediateComponentHolder.class.getDeclaredField( "m_singleComponent" ); f.setAccessible( true ); return ( ImmediateComponentManager ) f.get( holder ); } @@ -194,11 +194,11 @@ public class ConfiguredComponentHolderTe } - private static ImmediateComponentManager[] getComponentManagers( ConfiguredComponentHolder holder ) + private static ImmediateComponentManager[] getComponentManagers( ImmediateComponentHolder holder ) { try { - final Method m = ConfiguredComponentHolder.class.getDeclaredMethod( "getComponentManagers", new Class[] + final Method m = ImmediateComponentHolder.class.getDeclaredMethod( "getComponentManagers", new Class[] { Boolean.TYPE } ); m.setAccessible( true ); return ( ImmediateComponentManager[] ) m.invoke( holder, new Object[] @@ -211,7 +211,7 @@ public class ConfiguredComponentHolderTe } } - private static class TestingConfiguredComponentHolder extends ConfiguredComponentHolder + private static class TestingConfiguredComponentHolder extends ImmediateComponentHolder { TestingConfiguredComponentHolder( ComponentMetadata metadata ) { Modified: felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java?rev=1067145&r1=1067144&r2=1067145&view=diff ============================================================================== --- felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java (original) +++ felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java Fri Feb 4 10:50:18 2011 @@ -44,6 +44,7 @@ import org.ops4j.pax.exam.Option; import org.ops4j.pax.exam.OptionUtils; import org.ops4j.pax.exam.container.def.PaxRunnerOptions; import org.ops4j.pax.exam.junit.Configuration; +import org.ops4j.pax.exam.options.MavenArtifactUrlReference; import org.ops4j.pax.swissbox.tinybundles.core.TinyBundles; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; @@ -120,9 +121,9 @@ public abstract class ComponentTestBase @Before public void setUp() throws BundleException { - scrTracker = new ServiceTracker( bundleContext, ScrService.class.getName(), null ); + scrTracker = new ServiceTracker( bundleContext, "org.apache.felix.scr.ScrService", null ); scrTracker.open(); - configAdminTracker = new ServiceTracker( bundleContext, ConfigurationAdmin.class.getName(), null ); + configAdminTracker = new ServiceTracker( bundleContext, "org.osgi.service.cm.ConfigurationAdmin", null ); configAdminTracker.open(); bundle = installBundle( descriptorFile );