| /* |
| * 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; |
| |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.net.URL; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.Enumeration; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.StringTokenizer; |
| import java.util.concurrent.CountDownLatch; |
| import java.util.concurrent.TimeUnit; |
| import java.util.concurrent.atomic.AtomicBoolean; |
| |
| import javax.xml.parsers.SAXParser; |
| import javax.xml.parsers.SAXParserFactory; |
| |
| import org.apache.felix.scr.impl.helper.ConfigAdminTracker; |
| import org.apache.felix.scr.impl.logger.BundleLogger; |
| import org.apache.felix.scr.impl.logger.ComponentLogger; |
| import org.apache.felix.scr.impl.logger.ScrLogger; |
| import org.apache.felix.scr.impl.manager.AbstractComponentManager; |
| import org.apache.felix.scr.impl.manager.ComponentActivator; |
| import org.apache.felix.scr.impl.manager.ComponentHolder; |
| import org.apache.felix.scr.impl.manager.DependencyManager; |
| import org.apache.felix.scr.impl.manager.ExtendedServiceEvent; |
| import org.apache.felix.scr.impl.manager.ExtendedServiceListener; |
| import org.apache.felix.scr.impl.manager.RegionConfigurationSupport; |
| import org.apache.felix.scr.impl.manager.ScrConfiguration; |
| import org.apache.felix.scr.impl.metadata.ComponentMetadata; |
| import org.apache.felix.scr.impl.xml.XmlHandler; |
| import org.osgi.framework.Bundle; |
| import org.osgi.framework.BundleContext; |
| import org.osgi.framework.Filter; |
| import org.osgi.framework.InvalidSyntaxException; |
| import org.osgi.framework.ServiceEvent; |
| import org.osgi.framework.ServiceListener; |
| import org.osgi.framework.ServiceReference; |
| import org.osgi.service.cm.ConfigurationAdmin; |
| import org.osgi.service.component.ComponentException; |
| import org.osgi.service.log.LogService; |
| |
| /** |
| * The BundleComponentActivator is helper class to load and unload Components of |
| * a single bundle. It will read information from the metadata.xml file |
| * descriptors and create the corresponding managers. |
| */ |
| public class BundleComponentActivator implements ComponentActivator |
| { |
| |
| // global component registration |
| private final ComponentRegistry m_componentRegistry; |
| |
| // The bundle owning the registered component |
| private final Bundle m_bundle; |
| |
| // The bundle context owning the registered component |
| private final BundleContext m_context; |
| |
| // This is a list of component holders that belong to a particular bundle |
| private final List<ComponentHolder<?>> m_holders = new ArrayList<>(); |
| |
| // thread acting upon configurations |
| private final ComponentActorThread m_componentActor; |
| |
| // true as long as the dispose method is not called |
| private final AtomicBoolean m_active = new AtomicBoolean( true ); |
| private final CountDownLatch m_closeLatch = new CountDownLatch( 1 ); |
| |
| // the configuration |
| private final ScrConfiguration m_configuration; |
| |
| private final ConfigAdminTracker configAdminTracker; |
| |
| private final Map<String, ListenerInfo> listenerMap = new HashMap<>(); |
| |
| private final BundleLogger logger; |
| |
| private static class ListenerInfo implements ServiceListener |
| { |
| private Map<Filter, List<ExtendedServiceListener<ExtendedServiceEvent>>> filterMap = new HashMap<>(); |
| |
| @Override |
| public void serviceChanged(ServiceEvent event) |
| { |
| ServiceReference<?> ref = event.getServiceReference(); |
| ExtendedServiceEvent extEvent = null; |
| ExtendedServiceEvent endMatchEvent = null; |
| Map<Filter, List<ExtendedServiceListener<ExtendedServiceEvent>>> filterMap; |
| synchronized ( this ) |
| { |
| filterMap = this.filterMap; |
| } |
| for ( Map.Entry<Filter, List<ExtendedServiceListener<ExtendedServiceEvent>>> entry : filterMap.entrySet() ) |
| { |
| Filter filter = entry.getKey(); |
| if ( filter == null || filter.match( ref ) ) |
| { |
| if ( extEvent == null ) |
| { |
| extEvent = new ExtendedServiceEvent( event ); |
| } |
| for ( ExtendedServiceListener<ExtendedServiceEvent> forwardTo : entry.getValue() ) |
| { |
| forwardTo.serviceChanged( extEvent ); |
| } |
| } |
| else if ( event.getType() == ServiceEvent.MODIFIED ) |
| { |
| if ( endMatchEvent == null ) |
| { |
| endMatchEvent = new ExtendedServiceEvent( ServiceEvent.MODIFIED_ENDMATCH, ref ); |
| } |
| for ( ExtendedServiceListener<ExtendedServiceEvent> forwardTo : entry.getValue() ) |
| { |
| forwardTo.serviceChanged( endMatchEvent ); |
| } |
| } |
| } |
| if ( extEvent != null ) |
| { |
| extEvent.activateManagers(); |
| } |
| if ( endMatchEvent != null ) |
| { |
| endMatchEvent.activateManagers(); |
| } |
| } |
| |
| public synchronized void add(Filter filter, ExtendedServiceListener<ExtendedServiceEvent> listener) |
| { |
| filterMap = new HashMap<>( filterMap ); |
| List<ExtendedServiceListener<ExtendedServiceEvent>> listeners = filterMap.get( filter ); |
| if ( listeners == null ) |
| { |
| listeners = Collections.<ExtendedServiceListener<ExtendedServiceEvent>> singletonList( listener ); |
| } |
| else |
| { |
| listeners = new ArrayList<>( listeners ); |
| listeners.add( listener ); |
| } |
| filterMap.put( filter, listeners ); |
| } |
| |
| public synchronized boolean remove(Filter filter, ExtendedServiceListener<ExtendedServiceEvent> listener) |
| { |
| List<ExtendedServiceListener<ExtendedServiceEvent>> listeners = filterMap.get( filter ); |
| if ( listeners != null ) |
| { |
| filterMap = new HashMap<>( filterMap ); |
| listeners = new ArrayList<>( listeners ); |
| listeners.remove( listener ); |
| if ( listeners.isEmpty() ) |
| { |
| filterMap.remove( filter ); |
| } |
| else |
| { |
| filterMap.put( filter, listeners ); |
| } |
| } |
| return filterMap.isEmpty(); |
| } |
| } |
| |
| @Override |
| public void addServiceListener(String classNameFilter, Filter eventFilter, |
| ExtendedServiceListener<ExtendedServiceEvent> listener) |
| { |
| ListenerInfo listenerInfo; |
| synchronized ( listenerMap ) |
| { |
| logger.log( LogService.LOG_DEBUG, "classNameFilter: " + classNameFilter + " event filter: " + eventFilter, null); |
| listenerInfo = listenerMap.get( classNameFilter ); |
| if ( listenerInfo == null ) |
| { |
| listenerInfo = new ListenerInfo(); |
| listenerMap.put( classNameFilter, listenerInfo ); |
| try |
| { |
| m_context.addServiceListener( listenerInfo, classNameFilter ); |
| } |
| catch ( InvalidSyntaxException e ) |
| { |
| throw (IllegalArgumentException) new IllegalArgumentException( |
| "invalid class name filter" ).initCause( e ); |
| } |
| } |
| } |
| listenerInfo.add( eventFilter, listener ); |
| } |
| |
| @Override |
| public void removeServiceListener(String className, Filter filter, |
| ExtendedServiceListener<ExtendedServiceEvent> listener) |
| { |
| synchronized ( listenerMap ) |
| { |
| ListenerInfo listenerInfo = listenerMap.get( className ); |
| if ( listenerInfo != null ) |
| { |
| if ( listenerInfo.remove( filter, listener ) ) |
| { |
| listenerMap.remove( className ); |
| m_context.removeServiceListener( listenerInfo ); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Called upon starting of the bundle. This method invokes initialize() which |
| * parses the metadata and creates the holders |
| * |
| * @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 |
| */ |
| public BundleComponentActivator(final ScrLogger scrLogger, |
| final ComponentRegistry componentRegistry, |
| final ComponentActorThread componentActor, |
| final BundleContext context, |
| final ScrConfiguration configuration, |
| final List<ComponentMetadata> cachedComponentMetadata) |
| throws ComponentException |
| { |
| // create a logger on behalf of the bundle |
| this.logger = new BundleLogger(context, scrLogger); |
| // keep the parameters for later |
| m_componentRegistry = componentRegistry; |
| m_componentActor = componentActor; |
| m_context = context; |
| m_bundle = context.getBundle(); |
| |
| m_configuration = configuration; |
| |
| logger.log( LogService.LOG_DEBUG, "BundleComponentActivator : Bundle active", null); |
| |
| initialize(cachedComponentMetadata); |
| ConfigAdminTracker tracker = null; |
| for ( ComponentHolder<?> holder : m_holders ) |
| { |
| if ( !holder.getComponentMetadata().isConfigurationIgnored() ) |
| { |
| tracker = new ConfigAdminTracker( this ); |
| break; |
| } |
| } |
| configAdminTracker = tracker; |
| } |
| |
| /** |
| * Gets the MetaData location, parses the meta data and requests the processing |
| * of binder instances |
| * @param cachedComponentMetadata |
| * |
| * @throws IllegalStateException If the bundle has already been uninstalled. |
| */ |
| protected void initialize(List<ComponentMetadata> cachedComponentMetadata) |
| { |
| if (cachedComponentMetadata != null) |
| { |
| for (ComponentMetadata metadata : cachedComponentMetadata) |
| { |
| validateAndRegister(metadata); |
| } |
| } |
| else |
| { |
| // Get the Metadata-Location value from the manifest |
| String descriptorLocations = m_bundle.getHeaders("").get("Service-Component"); |
| if (descriptorLocations == null) |
| { |
| throw new ComponentException( |
| "Service-Component entry not found in the manifest"); |
| } |
| |
| logger.log(LogService.LOG_DEBUG, |
| "BundleComponentActivator : Descriptor locations {0}", null, |
| descriptorLocations); |
| |
| // 112.4.1: The value of the the header is a comma separated list of XML entries within the Bundle |
| StringTokenizer st = new StringTokenizer(descriptorLocations, ", "); |
| |
| while (st.hasMoreTokens()) |
| { |
| String descriptorLocation = st.nextToken(); |
| |
| URL[] descriptorURLs = findDescriptors(m_bundle, descriptorLocation); |
| if (descriptorURLs.length == 0) |
| { |
| // 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. |
| logger.log(LogService.LOG_ERROR, |
| "Component descriptor entry ''{0}'' not found", null, |
| descriptorLocation); |
| continue; |
| } |
| |
| |
| // load from the descriptors |
| for (URL descriptorURL : descriptorURLs) |
| { |
| loadDescriptor(descriptorURL); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Called outside the constructor so that the m_managers field is completely initialized. |
| * A component might possibly start a thread to enable other components, which could access m_managers |
| */ |
| void initialEnable() |
| { |
| //enable all the enabled components |
| for ( ComponentHolder<?> componentHolder : m_holders ) |
| { |
| logger.log( LogService.LOG_DEBUG, "BundleComponentActivator : May enable component holder {0}", null, |
| componentHolder.getComponentMetadata().getName() ); |
| |
| if ( componentHolder.getComponentMetadata().isEnabled() ) |
| { |
| logger.log( LogService.LOG_DEBUG, "BundleComponentActivator :Enabling component holder {0}", null, |
| componentHolder.getComponentMetadata().getName() ); |
| |
| try |
| { |
| componentHolder.enableComponents( false ); |
| } |
| catch ( Throwable t ) |
| { |
| // caught on unhandled RuntimeException or Error |
| // (e.g. ClassDefNotFoundError) |
| |
| // make sure the component is properly disabled, just in case |
| try |
| { |
| componentHolder.disableComponents( false ); |
| } |
| catch ( Throwable ignore ) |
| { |
| } |
| |
| logger.log( LogService.LOG_ERROR, |
| "BundleComponentActivator : Unexpected failure enabling component holder {0}", t, |
| componentHolder.getComponentMetadata().getName() ); |
| } |
| } |
| else |
| { |
| logger.log( LogService.LOG_DEBUG, |
| "BundleComponentActivator : Will not enable component holder {0}", null, |
| componentHolder.getComponentMetadata().getName() ); |
| } |
| } |
| } |
| |
| /** |
| * Finds component descriptors based on descriptor location. |
| * |
| * @param bundle bundle to search for descriptor files |
| * @param descriptorLocation descriptor location |
| * @return array of descriptors or empty array if none found |
| */ |
| static URL[] findDescriptors(final Bundle bundle, final String descriptorLocation) |
| { |
| if ( bundle == null || descriptorLocation == null || descriptorLocation.trim().length() == 0 ) |
| { |
| return new URL[0]; |
| } |
| |
| // split pattern and path |
| final int lios = descriptorLocation.lastIndexOf( "/" ); |
| final String path; |
| final String filePattern; |
| if ( lios > 0 ) |
| { |
| path = descriptorLocation.substring( 0, lios ); |
| filePattern = descriptorLocation.substring( lios + 1 ); |
| } |
| else |
| { |
| path = "/"; |
| filePattern = descriptorLocation; |
| } |
| |
| // find the entries |
| final Enumeration<URL> entries = bundle.findEntries( path, filePattern, false ); |
| if ( entries == null || !entries.hasMoreElements() ) |
| { |
| return new URL[0]; |
| } |
| |
| // create the result list |
| List<URL> urls = new ArrayList<>(); |
| while ( entries.hasMoreElements() ) |
| { |
| urls.add( entries.nextElement() ); |
| } |
| return urls.toArray( new URL[urls.size()] ); |
| } |
| |
| private void loadDescriptor(final URL descriptorURL) |
| { |
| // simple path for log messages |
| final String descriptorLocation = descriptorURL.getPath(); |
| |
| InputStream stream = null; |
| try |
| { |
| stream = descriptorURL.openStream(); |
| |
| XmlHandler handler = new XmlHandler( m_bundle, this.logger, getConfiguration().isFactoryEnabled(), |
| getConfiguration().keepInstances() ); |
| final SAXParserFactory factory = SAXParserFactory.newInstance(); |
| factory.setNamespaceAware(true); |
| final SAXParser parser = factory.newSAXParser(); |
| |
| parser.parse( stream, handler ); |
| |
| // 112.4.2 Component descriptors may contain a single, root component element |
| // or one or more component elements embedded in a larger document |
| for ( ComponentMetadata metadata : handler.getComponentMetadataList() ) |
| { |
| validateAndRegister(metadata); |
| } |
| } |
| catch ( IOException ex ) |
| { |
| // 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. |
| |
| logger.log( LogService.LOG_ERROR, "Problem reading descriptor entry ''{0}''", ex, descriptorLocation ); |
| } |
| catch ( Exception ex ) |
| { |
| logger.log( LogService.LOG_ERROR, "General problem with descriptor entry ''{0}''", ex, descriptorLocation ); |
| } |
| finally |
| { |
| if ( stream != null ) |
| { |
| try |
| { |
| stream.close(); |
| } |
| catch ( IOException ignore ) |
| { |
| } |
| } |
| } |
| } |
| |
| void validateAndRegister(ComponentMetadata metadata) |
| { |
| final ComponentLogger componentLogger = new ComponentLogger(metadata, logger); |
| ComponentRegistryKey key = null; |
| try |
| { |
| // validate the component metadata |
| metadata.validate(); |
| |
| // check and reserve the component name (validate ensures it's never null) |
| key = m_componentRegistry.checkComponentName(m_bundle, metadata.getName()); |
| |
| // Request creation of the component manager |
| ComponentHolder<?> holder = m_componentRegistry.createComponentHolder(this, |
| metadata, componentLogger); |
| |
| // register the component after validation |
| m_componentRegistry.registerComponentHolder(key, holder); |
| m_holders.add(holder); |
| |
| componentLogger.log(LogService.LOG_DEBUG, |
| "BundleComponentActivator : ComponentHolder created.", null); |
| |
| } |
| catch (Throwable t) |
| { |
| // There is a problem with this particular component, we'll log the error |
| // and proceed to the next one |
| componentLogger.log(LogService.LOG_ERROR, "Cannot register component", t); |
| |
| // make sure the name is not reserved any more |
| if (key != null) |
| { |
| m_componentRegistry.unregisterComponentHolder(key); |
| } |
| } |
| } |
| |
| /** |
| * Dispose of this component activator instance and all the component |
| * managers. |
| */ |
| void dispose(int reason) |
| { |
| if ( m_active.compareAndSet( true, false ) ) |
| { |
| logger.log( LogService.LOG_DEBUG, "BundleComponentActivator : Will destroy {0} instances", |
| null, m_holders.size() ); |
| |
| for ( ComponentHolder<?> holder : m_holders ) |
| { |
| try |
| { |
| holder.disposeComponents( reason ); |
| } |
| catch ( Exception e ) |
| { |
| logger.log( LogService.LOG_ERROR, "BundleComponentActivator : Exception invalidating", e, |
| holder.getComponentMetadata() ); |
| } |
| finally |
| { |
| m_componentRegistry.unregisterComponentHolder( m_bundle, holder.getComponentMetadata().getName() ); |
| } |
| |
| } |
| if ( configAdminTracker != null ) |
| { |
| configAdminTracker.dispose(); |
| } |
| |
| logger.log( LogService.LOG_DEBUG, "BundleComponentActivator : Bundle STOPPED", |
| null ); |
| |
| logger.close(); |
| m_closeLatch.countDown(); |
| } |
| else |
| { |
| try |
| { |
| m_closeLatch.await( m_configuration.lockTimeout(), TimeUnit.MILLISECONDS ); |
| } |
| catch ( InterruptedException e ) |
| { |
| //ignore interruption during concurrent shutdown. |
| Thread.currentThread().interrupt(); |
| } |
| } |
| |
| } |
| |
| /** |
| * Returns <true> if this instance is active, that is if components |
| * may be activated for this component. The active flag is set early |
| * in the constructor indicating the activator is basically active |
| * (not fully setup, though) and reset early in the process of |
| * {@link #dispose(int) disposing} this instance. |
| */ |
| @Override |
| public boolean isActive() |
| { |
| return m_active.get(); |
| } |
| |
| /** |
| * Returns the BundleContext |
| * |
| * @return the BundleContext |
| */ |
| @Override |
| public BundleContext getBundleContext() |
| { |
| return m_context; |
| } |
| |
| @Override |
| public ScrConfiguration getConfiguration() |
| { |
| return m_configuration; |
| } |
| |
| /** |
| * Implements the <code>ComponentContext.enableComponent(String)</code> |
| * method by first finding the component(s) for the <code>name</code> and |
| * enabling them. The enable method will schedule activation. |
| * <p> |
| * |
| * @param name The name of the component to enable or <code>null</code> to |
| * enable all components. |
| */ |
| @Override |
| public void enableComponent(final String name) |
| { |
| final List<ComponentHolder<?>> holder = getSelectedComponents( name ); |
| for ( ComponentHolder<?> aHolder : holder ) |
| { |
| try |
| { |
| // TODO use component logger |
| logger.log( LogService.LOG_DEBUG, "Enabling Component {0}", null, aHolder.getComponentMetadata().getName() ); |
| aHolder.enableComponents( true ); |
| } |
| catch ( Throwable t ) |
| { |
| // TODO use component logger |
| logger.log( LogService.LOG_ERROR, "Cannot enable component {0}", t, aHolder.getComponentMetadata().getName() ); |
| } |
| } |
| } |
| |
| /** |
| * Implements the <code>ComponentContext.disableComponent(String)</code> |
| * method by first finding the component(s) for the <code>name</code> and |
| * disabling them. The disable method will schedule deactivation |
| * <p> |
| * |
| * @param name The name of the component to disable or <code>null</code> to |
| * disable all components. |
| */ |
| @Override |
| public void disableComponent(final String name) |
| { |
| final List<ComponentHolder<?>> holder = getSelectedComponents( name ); |
| for ( ComponentHolder<?> aHolder : holder ) |
| { |
| try |
| { |
| // TODO use component logger |
| logger.log( LogService.LOG_DEBUG, "Disabling Component {0}", null, aHolder.getComponentMetadata().getName() ); |
| aHolder.disableComponents( true ); |
| } |
| catch ( Throwable t ) |
| { |
| // TODO use component logger |
| logger.log( LogService.LOG_ERROR, "Cannot disable component {0}", t, aHolder.getComponentMetadata().getName() ); |
| } |
| } |
| } |
| |
| /** |
| * Returns an array of {@link ComponentHolder} instances which match the |
| * <code>name</code>. If the <code>name</code> is <code>null</code> an |
| * array of all currently known component managers is returned. Otherwise |
| * an array containing a single component manager matching the name is |
| * returned if one is registered. Finally, if no component manager with the |
| * given name is registered, <code>null</code> is returned. |
| * |
| * @param name The name of the component manager to return or |
| * <code>null</code> to return an array of all component managers. |
| * |
| * @return An array containing one or more component managers according |
| * to the <code>name</code> parameter or <code>null</code> if no |
| * component manager with the given name is currently registered. |
| */ |
| List<ComponentHolder<?>> getSelectedComponents(String name) |
| { |
| // if all components are selected |
| if ( name == null ) |
| { |
| return m_holders; |
| } |
| |
| ComponentHolder<?> componentHolder = m_componentRegistry.getComponentHolder( m_bundle, name ); |
| if ( componentHolder != null ) |
| { |
| return Collections.<ComponentHolder<?>> singletonList( componentHolder ); |
| } |
| |
| // if the component is not known |
| return Collections.emptyList(); |
| } |
| |
| //---------- Component ID support |
| |
| @Override |
| public long registerComponentId(AbstractComponentManager<?> componentManager) |
| { |
| return m_componentRegistry.registerComponentId( componentManager ); |
| } |
| |
| @Override |
| public void unregisterComponentId(AbstractComponentManager<?> componentManager) |
| { |
| m_componentRegistry.unregisterComponentId( componentManager.getId() ); |
| } |
| |
| //---------- Asynchronous Component Handling ------------------------------ |
| |
| /** |
| * Schedules the given <code>task</code> for asynchrounous execution or |
| * synchronously runs the task if the thread is not running. If this instance |
| * is {@link #isActive() not active}, the task is not executed. |
| * |
| * @param task The component task to execute |
| */ |
| @Override |
| public void schedule(Runnable task) |
| { |
| if ( isActive() ) |
| { |
| ComponentActorThread cat = m_componentActor; |
| if ( cat != null ) |
| { |
| cat.schedule( task ); |
| } |
| else |
| { |
| logger.log( LogService.LOG_DEBUG, "Component Actor Thread not running, calling synchronously", null ); |
| try |
| { |
| synchronized ( this ) |
| { |
| task.run(); |
| } |
| } |
| catch ( Throwable t ) |
| { |
| logger.log( LogService.LOG_WARNING, "Unexpected problem executing task", t ); |
| } |
| } |
| } |
| else |
| { |
| logger.log( LogService.LOG_WARNING, "BundleComponentActivator is not active; not scheduling {0}", |
| null, task ); |
| } |
| } |
| |
| @Override |
| public BundleLogger getLogger() { |
| return logger; |
| } |
| |
| @Override |
| public <T> boolean enterCreate(ServiceReference<T> serviceReference) |
| { |
| return m_componentRegistry.enterCreate( serviceReference ); |
| } |
| |
| @Override |
| public <T> void leaveCreate(ServiceReference<T> serviceReference) |
| { |
| m_componentRegistry.leaveCreate( serviceReference ); |
| } |
| |
| @Override |
| public <T> void missingServicePresent(ServiceReference<T> serviceReference) |
| { |
| m_componentRegistry.missingServicePresent( serviceReference, m_componentActor ); |
| } |
| |
| @Override |
| public <S, T> void registerMissingDependency(DependencyManager<S, T> dependencyManager, |
| ServiceReference<T> serviceReference, int trackingCount) |
| { |
| m_componentRegistry.registerMissingDependency( dependencyManager, serviceReference, trackingCount ); |
| } |
| |
| @Override |
| public RegionConfigurationSupport setRegionConfigurationSupport(ServiceReference<ConfigurationAdmin> reference) |
| { |
| RegionConfigurationSupport rcs = m_componentRegistry.registerRegionConfigurationSupport( reference ); |
| if (rcs != null) { |
| for ( ComponentHolder<?> holder : m_holders ) |
| { |
| rcs.configureComponentHolder( holder ); |
| } |
| } |
| return rcs; |
| } |
| |
| @Override |
| public void unsetRegionConfigurationSupport(RegionConfigurationSupport rcs) |
| { |
| m_componentRegistry.unregisterRegionConfigurationSupport( rcs ); |
| // TODO anything needed? |
| } |
| |
| @Override |
| public void updateChangeCount() { |
| this.m_componentRegistry.updateChangeCount(); |
| } |
| } |