Fixed in https://builds.apache.org/job/Aries/org.apache.aries.blueprint$org.apache.aries.blueprint.itests/1597/ . Thank you!
-- Mark On 24 July 2012 10:53, Guillaume Nodet <[email protected]> wrote: > Sure, I'll investigate. They seem to have passed correctly on my machine, > so it may be a timing issue. > > On Tue, Jul 24, 2012 at 11:33 AM, Mark Nuttall <[email protected]> > wrote: > > > Hi Guillaume, > > Perhaps you've noticed all ready, but this change plus the three before > it > > is causing > > > org.apache.aries.blueprint.itests.TestConfigAdmin.testManagedServiceFactory > > to fail, and so breaking the Hudson build. We saw this first in > > https://builds.apache.org/job/Aries/1592/changes ; it can be seen again > in > > https://builds.apache.org/job/Aries/1593/ . > > > > Please would you revert these changes, or fix the resulting test failure? > > Thank you. > > > > Regards, > > Mark > > > > On 24 July 2012 07:35, <[email protected]> wrote: > > > > > Author: gnodet > > > Date: Tue Jul 24 06:35:34 2012 > > > New Revision: 1364914 > > > > > > URL: http://svn.apache.org/viewvc?rev=1364914&view=rev > > > Log: > > > [ARIES-584] Refactor ManagedServiceFactory to avoid holding lock while > > > registering/unregistering services and have a safer destruction > mechanism > > > > > > Added: > > > > > > > > > aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/BaseManagedServiceFactory.java > > > Modified: > > > > > > > > > aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmManagedServiceFactory.java > > > > > > > > > aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmNamespaceHandler.java > > > > > > > > > aries/trunk/blueprint/blueprint-cm/src/test/java/org/apache/aries/blueprint/compendium/cm/ManagedServiceFactoryTest.java > > > > > > Added: > > > > > > aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/BaseManagedServiceFactory.java > > > URL: > > > > > > http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/BaseManagedServiceFactory.java?rev=1364914&view=auto > > > > > > > > > ============================================================================== > > > --- > > > > > > aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/BaseManagedServiceFactory.java > > > (added) > > > +++ > > > > > > aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/BaseManagedServiceFactory.java > > > Tue Jul 24 06:35:34 2012 > > > @@ -0,0 +1,233 @@ > > > +/** > > > + * 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.aries.blueprint.compendium.cm; > > > + > > > +import java.util.Dictionary; > > > +import java.util.Map; > > > +import java.util.concurrent.ConcurrentHashMap; > > > +import java.util.concurrent.ExecutorService; > > > +import java.util.concurrent.Executors; > > > +import java.util.concurrent.TimeUnit; > > > +import java.util.concurrent.atomic.AtomicBoolean; > > > + > > > +import org.apache.aries.blueprint.utils.JavaUtils; > > > +import org.osgi.framework.BundleContext; > > > +import org.osgi.framework.ServiceRegistration; > > > +import org.osgi.service.cm.ConfigurationException; > > > +import org.osgi.service.cm.ManagedServiceFactory; > > > +import org.slf4j.Logger; > > > +import org.slf4j.LoggerFactory; > > > + > > > +public abstract class BaseManagedServiceFactory<T> implements > > > ManagedServiceFactory { > > > + > > > + public static final long DEFAULT_TIMEOUT_BEFORE_INTERRUPT = 30000; > > > + > > > + public static final int CONFIGURATION_ADMIN_OBJECT_DELETED = 1; > > > + > > > + public static final int BUNDLE_STOPPING = 2; > > > + > > > + public static final int INTERNAL_ERROR = 4; > > > + > > > + protected final Logger LOGGER = > LoggerFactory.getLogger(getClass()); > > > + > > > + private final BundleContext context; > > > + private final String name; > > > + private final long timeoutBeforeInterrupt; > > > + private final AtomicBoolean destroyed; > > > + private final ExecutorService executor; > > > + private final Map<String, Pair<T, ServiceRegistration>> services; > > > + private final Map<ServiceRegistration, T> registrations; > > > + > > > + public BaseManagedServiceFactory(BundleContext context, String > > name) { > > > + this(context, name, DEFAULT_TIMEOUT_BEFORE_INTERRUPT); > > > + } > > > + > > > + public BaseManagedServiceFactory(BundleContext context, String > name, > > > long timeoutBeforeInterrupt) { > > > + this.context = context; > > > + this.name = name; > > > + this.timeoutBeforeInterrupt = timeoutBeforeInterrupt; > > > + this.destroyed = new AtomicBoolean(false); > > > + this.executor = Executors.newSingleThreadExecutor(); > > > + this.services = new ConcurrentHashMap<String, Pair<T, > > > ServiceRegistration>>(); > > > + this.registrations = new > ConcurrentHashMap<ServiceRegistration, > > > T>(); > > > + } > > > + > > > + public String getName() { > > > + return name; > > > + } > > > + > > > + public Map<ServiceRegistration, T> getServices() { > > > + return registrations; > > > + } > > > + > > > + public void updated(final String pid, final Dictionary properties) > > > throws ConfigurationException { > > > + if (destroyed.get()) { > > > + return; > > > + } > > > + checkConfiguration(pid, properties); > > > + executor.submit(new Runnable() { > > > + public void run() { > > > + try { > > > + internalUpdate(pid, properties); > > > + } catch (Throwable t) { > > > + LOGGER.warn("Error destroying service for > > > ManagedServiceFactory " + getName(), t); > > > + } > > > + } > > > + }); > > > + } > > > + > > > + public void deleted(final String pid) { > > > + if (destroyed.get()) { > > > + return; > > > + } > > > + executor.submit(new Runnable() { > > > + public void run() { > > > + try { > > > + internalDelete(pid, > > > CONFIGURATION_ADMIN_OBJECT_DELETED); > > > + } catch (Throwable throwable) { > > > + LOGGER.warn("Error destroying service for > > > ManagedServiceFactory " + getName(), throwable); > > > + } > > > + } > > > + }); > > > + } > > > + > > > + protected void checkConfiguration(String pid, Dictionary > properties) > > > throws ConfigurationException { > > > + // Do nothing > > > + } > > > + > > > + protected abstract T doCreate(Dictionary properties) throws > > Exception; > > > + > > > + protected abstract T doUpdate(T t, Dictionary properties) throws > > > Exception; > > > + > > > + protected abstract void doDestroy(T t, Dictionary properties, int > > > code) throws Exception; > > > + > > > + protected abstract String[] getExposedClasses(T t); > > > + > > > + private void internalUpdate(String pid, Dictionary properties) { > > > + Pair<T, ServiceRegistration> pair = services.get(pid); > > > + if (pair != null) { > > > + try { > > > + T t = doUpdate(pair.getFirst(), properties); > > > + pair.setFirst(t); > > > + pair.getSecond().setProperties(properties); > > > + } catch (Throwable throwable) { > > > + internalDelete(pid, INTERNAL_ERROR); > > > + LOGGER.warn("Error updating service for > > > ManagedServiceFactory " + getName(), throwable); > > > + } > > > + } else { > > > + if (destroyed.get()) { > > > + return; > > > + } > > > + try { > > > + T t = doCreate(properties); > > > + try { > > > + if (destroyed.get()) { > > > + throw new > > > IllegalStateException("ManagedServiceFactory has been destroyed"); > > > + } > > > + ServiceRegistration registration = > > > context.registerService(getExposedClasses(t), t, properties); > > > + services.put(pid, new Pair<T, > > ServiceRegistration>(t, > > > registration)); > > > + registrations.put(registration, t); > > > + postRegister(t, properties, registration); > > > + } catch (Throwable throwable1) { > > > + try { > > > + doDestroy(t, properties, INTERNAL_ERROR); > > > + } catch (Throwable throwable2) { > > > + // Ignore > > > + } > > > + throw throwable1; > > > + } > > > + } catch (Throwable throwable) { > > > + LOGGER.warn("Error creating service for > > > ManagedServiceFactory " + getName(), throwable); > > > + } > > > + } > > > + } > > > + > > > + protected void postRegister(T t, Dictionary properties, > > > ServiceRegistration registration) { > > > + // Place holder > > > + } > > > + > > > + protected void preUnregister(T t, Dictionary properties, > > > ServiceRegistration registration) { > > > + // Place holder > > > + } > > > + > > > + private void internalDelete(String pid, int code) { > > > + Pair<T, ServiceRegistration> pair = services.remove(pid); > > > + if (pair != null) { > > > + registrations.remove(pair.getSecond()); > > > + Dictionary properties = > > > JavaUtils.getProperties(pair.getSecond().getReference()); > > > + try { > > > + preUnregister(pair.getFirst(), properties, > > > pair.getSecond()); > > > + pair.getSecond().unregister(); > > > + } catch (Throwable t) { > > > + LOGGER.info("Error unregistering service", t); > > > + } > > > + try { > > > + doDestroy(pair.getFirst(), properties, code); > > > + } catch (Throwable t) { > > > + LOGGER.info("Error destroying service", t); > > > + } > > > + } > > > + } > > > + > > > + public void destroy() { > > > + if (destroyed.compareAndSet(false, true)) { > > > + executor.shutdown(); > > > + try { > > > + executor.awaitTermination(timeoutBeforeInterrupt, > > > TimeUnit.MILLISECONDS); > > > + } catch (InterruptedException e) { > > > + throw new RuntimeException("Shutdown interrupted"); > > > + } > > > + if (!executor.isTerminated()) { > > > + executor.shutdownNow(); > > > + try { > > > + executor.awaitTermination(Long.MAX_VALUE, > > > TimeUnit.NANOSECONDS); > > > + } catch (InterruptedException e) { > > > + throw new RuntimeException("Shutdown > interrupted"); > > > + } > > > + } > > > + > > > + while (!services.isEmpty()) { > > > + String pid = services.keySet().iterator().next(); > > > + internalDelete(pid, BUNDLE_STOPPING); > > > + } > > > + } > > > + } > > > + > > > + static class Pair<U,V> { > > > + private U first; > > > + private V second; > > > + public Pair(U first, V second) { > > > + this.first = first; > > > + this.second = second; > > > + } > > > + public U getFirst() { > > > + return first; > > > + } > > > + public V getSecond() { > > > + return second; > > > + } > > > + public void setFirst(U first) { > > > + this.first = first; > > > + } > > > + public void setSecond(V second) { > > > + this.second = second; > > > + } > > > + } > > > + > > > +} > > > > > > Modified: > > > > > > aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmManagedServiceFactory.java > > > URL: > > > > > > http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmManagedServiceFactory.java?rev=1364914&r1=1364913&r2=1364914&view=diff > > > > > > > > > ============================================================================== > > > --- > > > > > > aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmManagedServiceFactory.java > > > (original) > > > +++ > > > > > > aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmManagedServiceFactory.java > > > Tue Jul 24 06:35:34 2012 > > > @@ -27,23 +27,18 @@ import java.util.List; > > > import java.util.Map; > > > import java.util.Properties; > > > import java.util.Set; > > > -import java.util.concurrent.ConcurrentHashMap; > > > > > > import org.apache.aries.blueprint.BeanProcessor; > > > -import org.apache.aries.blueprint.services.ExtendedBlueprintContainer; > > > import org.apache.aries.blueprint.ServiceProcessor; > > > +import org.apache.aries.blueprint.services.ExtendedBlueprintContainer; > > > import org.apache.aries.blueprint.utils.JavaUtils; > > > import org.apache.aries.blueprint.utils.ReflectionUtils; > > > import org.apache.aries.blueprint.utils.ServiceListener; > > > import org.apache.aries.util.AriesFrameworkUtil; > > > import org.osgi.framework.Bundle; > > > import org.osgi.framework.Constants; > > > -import org.osgi.framework.ServiceReference; > > > import org.osgi.framework.ServiceRegistration; > > > import org.osgi.service.blueprint.reflect.ServiceMetadata; > > > -import org.osgi.service.cm.Configuration; > > > -import org.osgi.service.cm.ConfigurationAdmin; > > > -import org.osgi.service.cm.ConfigurationException; > > > import org.osgi.service.cm.ManagedServiceFactory; > > > import org.slf4j.Logger; > > > import org.slf4j.LoggerFactory; > > > @@ -54,30 +49,27 @@ import org.slf4j.LoggerFactory; > > > * > > > * @version $Rev$, $Date$ > > > */ > > > -public class CmManagedServiceFactory { > > > - > > > - static final int CONFIGURATION_ADMIN_OBJECT_DELETED = 1; > > > - > > > - static final int BUNDLE_STOPPING = 2; > > > +public class CmManagedServiceFactory extends > > > BaseManagedServiceFactory<Object> { > > > > > > private static final Logger LOGGER = > > > LoggerFactory.getLogger(CmManagedServiceFactory.class); > > > - > > > + > > > private ExtendedBlueprintContainer blueprintContainer; > > > - private ConfigurationAdmin configAdmin; > > > private String id; > > > private String factoryPid; > > > private List<String> interfaces; > > > private int autoExport; > > > private int ranking; > > > - private Map serviceProperties; > > > + private Map<Object,Object> serviceProperties; > > > private String managedComponentName; > > > private String componentDestroyMethod; > > > private List<ServiceListener> listeners; > > > - private final Object lock = new Object(); > > > > > > private ServiceRegistration registration; > > > - private final Map<String, ServiceRegistration> pids = new > > > ConcurrentHashMap<String, ServiceRegistration>(); > > > - private final Map<ServiceRegistration, Object> services = new > > > ConcurrentHashMap<ServiceRegistration, Object>(); > > > + > > > + public CmManagedServiceFactory(ExtendedBlueprintContainer > > > blueprintContainer) { > > > + super(blueprintContainer.getBundleContext(), null); > > > + this.blueprintContainer = blueprintContainer; > > > + } > > > > > > public void init() throws Exception { > > > LOGGER.debug("Initializing CmManagedServiceFactory for > > > factoryPid={}", factoryPid); > > > @@ -86,61 +78,27 @@ public class CmManagedServiceFactory { > > > Bundle bundle = > > blueprintContainer.getBundleContext().getBundle(); > > > props.put(Constants.BUNDLE_SYMBOLICNAME, > > > bundle.getSymbolicName()); > > > props.put(Constants.BUNDLE_VERSION, > > > bundle.getHeaders().get(Constants.BUNDLE_VERSION)); > > > - > > > - synchronized(lock) { > > > - registration = > > > > > > blueprintContainer.getBundleContext().registerService(ManagedServiceFactory.class.getName(), > > > new ConfigurationWatcher(), props); > > > - > > > - String filter = '(' + > ConfigurationAdmin.SERVICE_FACTORYPID > > + > > > '=' + this.factoryPid + ')'; > > > - Configuration[] configs = > > > configAdmin.listConfigurations(filter); > > > - if (configs != null) { > > > - for (Configuration config : configs) { > > > - updated(config.getPid(), config.getProperties()); > > > - } > > > - } > > > - } > > > + > > > + registration = > > > > > > blueprintContainer.getBundleContext().registerService(ManagedServiceFactory.class.getName(), > > > this, props); > > > } > > > > > > public void destroy() { > > > AriesFrameworkUtil.safeUnregisterService(registration); > > > - for (Map.Entry<ServiceRegistration, Object> entry : > > > services.entrySet()) { > > > - destroy(entry.getValue(), entry.getKey(), > BUNDLE_STOPPING); > > > - } > > > - services.clear(); > > > - pids.clear(); > > > + super.destroy(); > > > } > > > > > > - private void destroy(Object component, ServiceRegistration > > > registration, int code) { > > > - if (listeners != null) { > > > - ServiceReference ref = registration.getReference(); > > > - for (ServiceListener listener : listeners) { > > > - Hashtable props = JavaUtils.getProperties(ref); > > > - listener.unregister(component, props); > > > - } > > > - } > > > - destroyComponent(component, code); > > > - AriesFrameworkUtil.safeUnregisterService(registration); > > > - } > > > - > > > public Map<ServiceRegistration, Object> getServiceMap() { > > > - return Collections.unmodifiableMap(services); > > > - } > > > - > > > - public void setBlueprintContainer(ExtendedBlueprintContainer > > > blueprintContainer) { > > > - this.blueprintContainer = blueprintContainer; > > > - } > > > - > > > - public void setConfigAdmin(ConfigurationAdmin configAdmin) { > > > - this.configAdmin = configAdmin; > > > + return Collections.unmodifiableMap(getServices()); > > > } > > > > > > public void setListeners(List<ServiceListener> listeners) { > > > this.listeners = listeners; > > > } > > > - > > > + > > > public void setId(String id) { > > > this.id = id; > > > } > > > - > > > + > > > public void setFactoryPid(String factoryPid) { > > > this.factoryPid = factoryPid; > > > } > > > @@ -160,7 +118,7 @@ public class CmManagedServiceFactory { > > > public void setServiceProperties(Map serviceProperties) { > > > this.serviceProperties = serviceProperties; > > > } > > > - > > > + > > > public void setManagedComponentName(String managedComponentName) { > > > this.managedComponentName = managedComponentName; > > > } > > > @@ -168,82 +126,42 @@ public class CmManagedServiceFactory { > > > public void setComponentDestroyMethod(String > > componentDestroyMethod) { > > > this.componentDestroyMethod = componentDestroyMethod; > > > } > > > - > > > - protected void updated(String pid, Dictionary props) { > > > - LOGGER.debug("Updated configuration {} with props {}", pid, > > props); > > > - > > > - Hashtable regProps = null; > > > - Object component = null; > > > - > > > - // This method might be multithreaded, so synchronize checking > and > > > - // creating the service > > > - final ServiceRegistration existingReg; > > > - synchronized (pids) { > > > - existingReg = pids.get(pid); > > > - if (existingReg == null) { > > > - updateComponentProperties(props); > > > - > > > - component = > > > blueprintContainer.getComponentInstance(managedComponentName); > > > - > > > - // TODO: call listeners, etc... > > > - > > > - regProps = getRegistrationProperties(pid); > > > - CmProperties cm = findServiceProcessor(); > > > - if (cm != null) { > > > - if ("".equals(cm.getPersistentId())) { > > > - JavaUtils.copy(regProps, props); > > > - } > > > - cm.updateProperties(new PropertiesUpdater(pid), > > regProps); > > > - } > > > > > > - Set<String> classes = getClasses(component); > > > - String[] classArray = classes.toArray(new > > > String[classes.size()]); > > > - ServiceRegistration reg = > > > blueprintContainer.getBundleContext().registerService(classArray, > > > component, regProps); > > > - > > > - LOGGER.debug("Service {} registered with interfaces {} and > > > properties {}", new Object[] { component, classes, regProps }); > > > - > > > - services.put(reg, component); > > > - pids.put(pid, reg); > > > - } > > > - } // end of synchronization > > > - > > > - // If we just registered a service, do the slower stuff > outside > > > the synchronized block > > > - if (existingReg == null) > > > - { > > > - if (listeners != null) { > > > - for (ServiceListener listener : listeners) { > > > - listener.register(component, regProps); > > > + private void getRegistrationProperties(Dictionary properties, > > boolean > > > update) { > > > + CmProperties cm = findServiceProcessor(); > > > + if (cm == null) { > > > + while (!properties.isEmpty()) { > > > + properties.remove(properties.keys().nextElement()); > > > + } > > > + } else { > > > + if (!cm.getUpdate()) { > > > + if (update) { > > > + while (!properties.isEmpty()) { > > > + > > > properties.remove(properties.keys().nextElement()); > > > + } > > > + for (Map.Entry entry : > > cm.getProperties().entrySet()) > > > { > > > + properties.put(entry.getKey(), > > entry.getValue()); > > > + } > > > + } else { > > > + cm.updated(properties); > > > } > > > } > > > - } else { > > > - updateComponentProperties(props); > > > - > > > - CmProperties cm = findServiceProcessor(); > > > - if (cm != null && "".equals(cm.getPersistentId())) { > > > - regProps = getRegistrationProperties(pid); > > > - JavaUtils.copy(regProps, props); > > > - cm.updated(regProps); > > > - } > > > } > > > - } > > > - > > > - private Hashtable getRegistrationProperties(String pid) { > > > - Hashtable regProps = new Hashtable(); > > > if (serviceProperties != null) { > > > - regProps.putAll(serviceProperties); > > > + for (Map.Entry entry : serviceProperties.entrySet()) { > > > + properties.put(entry.getKey(), entry.getValue()); > > > + } > > > } > > > - regProps.put(Constants.SERVICE_PID, pid); > > > - regProps.put(Constants.SERVICE_RANKING, ranking); > > > - return regProps; > > > + properties.put(Constants.SERVICE_RANKING, ranking); > > > } > > > - > > > + > > > private void updateComponentProperties(Dictionary props) { > > > CmManagedProperties cm = findBeanProcessor(); > > > if (cm != null) { > > > cm.updated(props); > > > } > > > } > > > - > > > + > > > private CmManagedProperties findBeanProcessor() { > > > for (BeanProcessor beanProcessor : > > > blueprintContainer.getProcessors(BeanProcessor.class)) { > > > if (beanProcessor instanceof CmManagedProperties) { > > > @@ -255,7 +173,7 @@ public class CmManagedServiceFactory { > > > } > > > return null; > > > } > > > - > > > + > > > private CmProperties findServiceProcessor() { > > > for (ServiceProcessor processor : > > > blueprintContainer.getProcessors(ServiceProcessor.class)) { > > > if (processor instanceof CmProperties) { > > > @@ -267,20 +185,9 @@ public class CmManagedServiceFactory { > > > } > > > return null; > > > } > > > - > > > - private void destroyComponent(Object instance, int reason) { > > > - Method method = findDestroyMethod(instance.getClass()); > > > - if (method != null) { > > > - try { > > > - method.invoke(instance, new Object [] { reason }); > > > - } catch (Exception e) { > > > - e.printStackTrace(); > > > - } > > > - } > > > - } > > > - > > > + > > > private Method findDestroyMethod(Class clazz) { > > > - Method method = null; > > > + Method method = null; > > > if (componentDestroyMethod != null && > > > componentDestroyMethod.length() > 0) { > > > List<Method> methods = > > > ReflectionUtils.findCompatibleMethods(clazz, componentDestroyMethod, > new > > > Class [] { int.class }); > > > if (methods != null && !methods.isEmpty()) { > > > @@ -289,17 +196,52 @@ public class CmManagedServiceFactory { > > > } > > > return method; > > > } > > > - > > > - protected void deleted(String pid) { > > > - LOGGER.debug("Deleted configuration {}", pid); > > > - ServiceRegistration reg = pids.remove(pid); > > > - if (reg != null) { > > > - Object component = services.remove(reg); > > > - destroy(component, reg, > CONFIGURATION_ADMIN_OBJECT_DELETED); > > > + > > > + protected Object doCreate(Dictionary properties) throws Exception > { > > > + updateComponentProperties(copy(properties)); > > > + Object component = > > > blueprintContainer.getComponentInstance(managedComponentName); > > > + getRegistrationProperties(properties, false); > > > + return component; > > > + } > > > + > > > + protected Object doUpdate(Object service, Dictionary properties) > > > throws Exception { > > > + updateComponentProperties(copy(properties)); > > > + getRegistrationProperties(properties, true); > > > + return service; > > > + } > > > + > > > + protected void doDestroy(Object service, Dictionary properties, > int > > > code) throws Exception { > > > + Method method = findDestroyMethod(service.getClass()); > > > + if (method != null) { > > > + try { > > > + method.invoke(service, new Object [] { code }); > > > + } catch (Exception e) { > > > + LOGGER.info("Error destroying component", e); > > > + } > > > + } > > > + } > > > + > > > + protected void postRegister(Object service, Dictionary properties, > > > ServiceRegistration registration) { > > > + if (listeners != null && !listeners.isEmpty()) { > > > + Hashtable props = new Hashtable(); > > > + JavaUtils.copy(properties, props); > > > + for (ServiceListener listener : listeners) { > > > + listener.register(service, props); > > > + } > > > + } > > > + } > > > + > > > + protected void preUnregister(Object service, Dictionary > properties, > > > ServiceRegistration registration) { > > > + if (listeners != null && !listeners.isEmpty()) { > > > + Hashtable props = new Hashtable(); > > > + JavaUtils.copy(properties, props); > > > + for (ServiceListener listener : listeners) { > > > + listener.unregister(service, props); > > > + } > > > } > > > } > > > > > > - private Set<String> getClasses(Object service) { > > > + protected String[] getExposedClasses(Object service) { > > > Class serviceClass = service.getClass(); > > > Set<String> classes; > > > switch (autoExport) { > > > @@ -317,47 +259,13 @@ public class CmManagedServiceFactory { > > > classes = new HashSet<String>(interfaces); > > > break; > > > } > > > - return classes; > > > + return classes.toArray(new String[classes.size()]); > > > } > > > - > > > - private class ConfigurationWatcher implements > ManagedServiceFactory > > { > > > - > > > - public String getName() { > > > - return null; > > > - } > > > - > > > - public void updated(String pid, Dictionary props) throws > > > ConfigurationException { > > > - CmManagedServiceFactory.this.updated(pid, props); > > > - } > > > > > > - public void deleted(String pid) { > > > - CmManagedServiceFactory.this.deleted(pid); > > > - } > > > + private Hashtable copy(Dictionary source) { > > > + Hashtable ht = new Hashtable(); > > > + JavaUtils.copy(ht, source); > > > + return ht; > > > } > > > > > > - private class PropertiesUpdater implements > > > ServiceProcessor.ServicePropertiesUpdater { > > > - > > > - private String pid; > > > - > > > - public PropertiesUpdater(String pid) { > > > - this.pid = pid; > > > - } > > > - > > > - public String getId() { > > > - return id; > > > - } > > > - > > > - public void updateProperties(Dictionary properties) { > > > - ServiceRegistration reg = pids.get(pid); > > > - if (reg != null) { > > > - ServiceReference ref = reg.getReference(); > > > - if (ref != null) { > > > - Hashtable table = JavaUtils.getProperties(ref); > > > - JavaUtils.copy(table, properties); > > > - reg.setProperties(table); > > > - } > > > - } > > > - } > > > - } > > > - > > > } > > > > > > Modified: > > > > > > aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmNamespaceHandler.java > > > URL: > > > > > > http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmNamespaceHandler.java?rev=1364914&r1=1364913&r2=1364914&view=diff > > > > > > > > > ============================================================================== > > > --- > > > > > > aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmNamespaceHandler.java > > > (original) > > > +++ > > > > > > aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmNamespaceHandler.java > > > Tue Jul 24 06:35:34 2012 > > > @@ -350,8 +350,7 @@ public class CmNamespaceHandler implemen > > > > factoryMetadata.setRuntimeClass(CmManagedServiceFactory.class); > > > factoryMetadata.setInitMethod("init"); > > > factoryMetadata.setDestroyMethod("destroy"); > > > - factoryMetadata.addProperty("configAdmin", > > > createConfigurationAdminRef(context)); > > > - factoryMetadata.addProperty("blueprintContainer", > > > createRef(context, "blueprintContainer")); > > > + factoryMetadata.addArgument(createRef(context, > > > "blueprintContainer"), null, 0); > > > factoryMetadata.addProperty("factoryPid", createValue(context, > > > element.getAttribute(FACTORY_PID_ATTRIBUTE))); > > > String autoExport = > element.hasAttribute(AUTO_EXPORT_ATTRIBUTE) > > ? > > > element.getAttribute(AUTO_EXPORT_ATTRIBUTE) : AUTO_EXPORT_DEFAULT; > > > if (AUTO_EXPORT_DISABLED.equals(autoExport)) { > > > > > > Modified: > > > > > > aries/trunk/blueprint/blueprint-cm/src/test/java/org/apache/aries/blueprint/compendium/cm/ManagedServiceFactoryTest.java > > > URL: > > > > > > http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-cm/src/test/java/org/apache/aries/blueprint/compendium/cm/ManagedServiceFactoryTest.java?rev=1364914&r1=1364913&r2=1364914&view=diff > > > > > > > > > ============================================================================== > > > --- > > > > > > aries/trunk/blueprint/blueprint-cm/src/test/java/org/apache/aries/blueprint/compendium/cm/ManagedServiceFactoryTest.java > > > (original) > > > +++ > > > > > > aries/trunk/blueprint/blueprint-cm/src/test/java/org/apache/aries/blueprint/compendium/cm/ManagedServiceFactoryTest.java > > > Tue Jul 24 06:35:34 2012 > > > @@ -56,6 +56,7 @@ public class ManagedServiceFactoryTest e > > > assertNull(sr.getProperty("b")); > > > > > > props = new Hashtable<String,String>(); > > > + props.put("a", "5"); > > > props.put("b", "foo"); > > > cf.update(props); > > > Thread.sleep(500); > > > @@ -89,6 +90,7 @@ public class ManagedServiceFactoryTest e > > > assertNull(sr.getProperty("b")); > > > > > > props = new Hashtable<String,String>(); > > > + props.put("a", "5"); > > > props.put("b", "foo"); > > > cf.update(props); > > > > > > @@ -122,6 +124,7 @@ public class ManagedServiceFactoryTest e > > > assertNull(sr.getProperty("b")); > > > > > > props = new Hashtable<String,String>(); > > > + props.put("a", "5"); > > > props.put("b", "foo"); > > > cf.update(props); > > > > > > > > > > > > > > > > > > -- > ------------------------ > Guillaume Nodet > ------------------------ > Blog: http://gnodet.blogspot.com/ > ------------------------ > FuseSource, Integration everywhere > http://fusesource.com >
