You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by cl...@apache.org on 2010/05/04 17:22:37 UTC

svn commit: r940905 [1/2] - in /felix/trunk/ipojo: annotations/src/main/java/org/apache/felix/ipojo/annotations/ core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ core/src/main/java/org/apache/felix/ipojo/util/ core/src/main/resources...

Author: clement
Date: Tue May  4 15:22:36 2010
New Revision: 940905

URL: http://svn.apache.org/viewvc?rev=940905&view=rev
Log:
Fix FELIX-2323 : Unbind method are no more called during the invalidation process if this process is not triggered by a service departure
Fix FELIX-2279 : Support post-registration and post-unregistration callbacks (injection of the service reference). Add the processing of @PostRegistration and @PostUnregistration.

Reformat the online-manipulator tests.

Added:
    felix/trunk/ipojo/annotations/src/main/java/org/apache/felix/ipojo/annotations/PostRegistration.java
    felix/trunk/ipojo/annotations/src/main/java/org/apache/felix/ipojo/annotations/PostUnregistration.java
    felix/trunk/ipojo/tests/core/service-providing/src/main/java/org/apache/felix/ipojo/test/scenarios/component/callbacks/
    felix/trunk/ipojo/tests/core/service-providing/src/main/java/org/apache/felix/ipojo/test/scenarios/component/callbacks/CallbacksCheckService.java
    felix/trunk/ipojo/tests/core/service-providing/src/main/java/org/apache/felix/ipojo/test/scenarios/ps/CallbacksTest.java
    felix/trunk/ipojo/tests/online-manipulator/src/test/java/org/apache/felix/ipojo/
    felix/trunk/ipojo/tests/online-manipulator/src/test/java/org/apache/felix/ipojo/online/
    felix/trunk/ipojo/tests/online-manipulator/src/test/java/org/apache/felix/ipojo/online/manipulator/
    felix/trunk/ipojo/tests/online-manipulator/src/test/java/org/apache/felix/ipojo/online/manipulator/test/
    felix/trunk/ipojo/tests/online-manipulator/src/test/java/org/apache/felix/ipojo/online/manipulator/test/OSGiHelper.java
      - copied, changed from r939352, felix/trunk/ipojo/tests/online-manipulator/src/test/java/org/apache/felix/org/apache/felix/ipojo/online/manipulator/test/OSGiHelper.java
    felix/trunk/ipojo/tests/online-manipulator/src/test/java/org/apache/felix/ipojo/online/manipulator/test/OnlineManipulatorTest.java
      - copied, changed from r939968, felix/trunk/ipojo/tests/online-manipulator/src/test/java/org/apache/felix/org/apache/felix/ipojo/online/manipulator/test/OnlineManipulatorTest.java
    felix/trunk/ipojo/tests/online-manipulator/src/test/java/org/apache/felix/ipojo/online/manipulator/test/impl/
      - copied from r939352, felix/trunk/ipojo/tests/online-manipulator/src/test/java/org/apache/felix/org/apache/felix/ipojo/online/manipulator/test/impl/
    felix/trunk/ipojo/tests/online-manipulator/src/test/java/org/apache/felix/ipojo/online/manipulator/test/service/
      - copied from r939352, felix/trunk/ipojo/tests/online-manipulator/src/test/java/org/apache/felix/org/apache/felix/ipojo/online/manipulator/test/service/
Removed:
    felix/trunk/ipojo/tests/online-manipulator/src/test/java/consumer.xml
    felix/trunk/ipojo/tests/online-manipulator/src/test/java/org/apache/felix/org/apache/felix/ipojo/online/manipulator/test/OSGiHelper.java
    felix/trunk/ipojo/tests/online-manipulator/src/test/java/org/apache/felix/org/apache/felix/ipojo/online/manipulator/test/OnlineManipulatorTest.java
    felix/trunk/ipojo/tests/online-manipulator/src/test/java/org/apache/felix/org/apache/felix/ipojo/online/manipulator/test/impl/
    felix/trunk/ipojo/tests/online-manipulator/src/test/java/org/apache/felix/org/apache/felix/ipojo/online/manipulator/test/service/
    felix/trunk/ipojo/tests/online-manipulator/src/test/java/provider.xml
Modified:
    felix/trunk/ipojo/annotations/src/main/java/org/apache/felix/ipojo/annotations/Modified.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/DependencyModel.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Tracker.java
    felix/trunk/ipojo/core/src/main/resources/core.xsd
    felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MethodCollector.java
    felix/trunk/ipojo/manipulator/src/main/resources/core.xsd
    felix/trunk/ipojo/plugin/src/main/resources/archetype-resources/pom.xml
    felix/trunk/ipojo/tests/core/service-providing/pom.xml
    felix/trunk/ipojo/tests/core/service-providing/src/main/java/org/apache/felix/ipojo/test/scenarios/ps/ProvidedServiceTestSuite.java
    felix/trunk/ipojo/tests/core/service-providing/src/main/resources/metadata.xml
    felix/trunk/ipojo/tests/online-manipulator/src/test/java/org/apache/felix/ipojo/online/manipulator/test/impl/Consumer.java
    felix/trunk/ipojo/tests/online-manipulator/src/test/java/org/apache/felix/ipojo/online/manipulator/test/impl/MyProvider.java
    felix/trunk/ipojo/tests/online-manipulator/src/test/java/org/apache/felix/ipojo/online/manipulator/test/service/Hello.java
    felix/trunk/ipojo/tests/online-manipulator/src/test/resources/consumer.xml
    felix/trunk/ipojo/tests/online-manipulator/src/test/resources/provider.xml

Modified: felix/trunk/ipojo/annotations/src/main/java/org/apache/felix/ipojo/annotations/Modified.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/annotations/src/main/java/org/apache/felix/ipojo/annotations/Modified.java?rev=940905&r1=940904&r2=940905&view=diff
==============================================================================
--- felix/trunk/ipojo/annotations/src/main/java/org/apache/felix/ipojo/annotations/Modified.java (original)
+++ felix/trunk/ipojo/annotations/src/main/java/org/apache/felix/ipojo/annotations/Modified.java Tue May  4 15:22:36 2010
@@ -1,4 +1,4 @@
-/* 
+/*
  * 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
@@ -23,56 +23,56 @@ import java.lang.annotation.Target;
 import java.util.Comparator;
 
 /**
- * This annotation declares an modify method.
+ * This annotation declares a modify method.
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 @Target(ElementType.METHOD)
 public @interface Modified {
-    
+
     /**
      * Set the dependency filter.
      * Default : no filter
      */
     String filter() default "";
-    
+
     /**
      * Set if the dependency is an aggregate dependency.
      * Default : false
      */
     boolean aggregate() default false;
-    
-    
+
+
     /**
      * Set if the dependency is optional.
      * Default : false
      */
     boolean optional() default false;
-    
+
     /**
      * Set the required specification.
      * Default : empty (try to discover).
      */
     String specification() default "";
-    
+
     /**
      * Set the dependency id.
      * Default : empty.
      */
     String id() default "";
-    
+
     /**
      * Set the binding policy.
      * Acceptable policy are dynamic, static and dynamic-priority.
      * Default: dynamic.
      */
     String policy() default "dynamic";
-    
+
     /**
      * Set the comparator.
      * The indicated class must implement {@link Comparator}
      */
     Class comparator() default Comparator.class;
-    
+
     /**
      * Set the from attribute.
      */

Added: felix/trunk/ipojo/annotations/src/main/java/org/apache/felix/ipojo/annotations/PostRegistration.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/annotations/src/main/java/org/apache/felix/ipojo/annotations/PostRegistration.java?rev=940905&view=auto
==============================================================================
--- felix/trunk/ipojo/annotations/src/main/java/org/apache/felix/ipojo/annotations/PostRegistration.java (added)
+++ felix/trunk/ipojo/annotations/src/main/java/org/apache/felix/ipojo/annotations/PostRegistration.java Tue May  4 15:22:36 2010
@@ -0,0 +1,14 @@
+package org.apache.felix.ipojo.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+
+/**
+ * This annotation declares a post-service-registration method.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@Target(ElementType.METHOD)
+public @interface PostRegistration {
+
+}

Added: felix/trunk/ipojo/annotations/src/main/java/org/apache/felix/ipojo/annotations/PostUnregistration.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/annotations/src/main/java/org/apache/felix/ipojo/annotations/PostUnregistration.java?rev=940905&view=auto
==============================================================================
--- felix/trunk/ipojo/annotations/src/main/java/org/apache/felix/ipojo/annotations/PostUnregistration.java (added)
+++ felix/trunk/ipojo/annotations/src/main/java/org/apache/felix/ipojo/annotations/PostUnregistration.java Tue May  4 15:22:36 2010
@@ -0,0 +1,14 @@
+package org.apache.felix.ipojo.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+
+/**
+ * This annotation declares a post-service-unregistration method.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@Target(ElementType.METHOD)
+public @interface PostUnregistration {
+
+}

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java?rev=940905&r1=940904&r2=940905&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java Tue May  4 15:22:36 2010
@@ -1,4 +1,4 @@
-/* 
+/*
  * 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
@@ -35,6 +35,7 @@ import org.apache.felix.ipojo.ComponentI
 import org.apache.felix.ipojo.ConfigurationException;
 import org.apache.felix.ipojo.IPOJOServiceFactory;
 import org.apache.felix.ipojo.InstanceManager;
+import org.apache.felix.ipojo.util.Callback;
 import org.apache.felix.ipojo.util.Property;
 import org.apache.felix.ipojo.util.SecurityHelper;
 import org.osgi.framework.Bundle;
@@ -107,18 +108,28 @@ public class ProvidedService implements 
      * Service Object creation policy.
      */
     private CreationStrategy m_strategy;
-    
+
     /**
      * Were the properties updated during the processing.
      */
     private volatile boolean m_wasUpdated;
-    
+
     /**
      * Service Controller.
      */
     private ServiceController m_controller;
 
     /**
+     * Post-Registration callback.
+     */
+    private Callback m_postRegistration;
+
+    /**
+     * Post-Unregistration callback.
+     */
+    private Callback m_postUnregistration;
+
+    /**
      * Creates a provided service object.
      *
      * @param handler the the provided service handler.
@@ -136,7 +147,7 @@ public class ProvidedService implements 
         try {
             addProperty(new Property("instance.name", null, null, handler.getInstanceManager().getInstanceName(), String.class.getName(), handler.getInstanceManager(), handler));
             addProperty(new Property("factory.name", null, null, handler.getInstanceManager().getFactory().getFactoryName(), String.class.getName(), handler.getInstanceManager(), handler));
-         
+
             if (handler.getInstanceManager().getFactory().getVersion() != null) {
                 addProperty(new Property("factory.version", null, null, handler.getInstanceManager().getFactory().getVersion(), String.class.getName(), handler.getInstanceManager(), handler));
             }
@@ -146,7 +157,7 @@ public class ProvidedService implements 
                 addProperty(new Property(Constants.SERVICE_PID, null, null, (String) conf.get(Constants.SERVICE_PID), String.class.getName(), handler.getInstanceManager(), handler));
             }
             if (conf.get(Constants.SERVICE_RANKING) != null) {
-                addProperty(new Property(Constants.SERVICE_RANKING, null, null, (String) conf.get(Constants.SERVICE_RANKING), "int", handler.getInstanceManager(), handler));                
+                addProperty(new Property(Constants.SERVICE_RANKING, null, null, (String) conf.get(Constants.SERVICE_RANKING), "int", handler.getInstanceManager(), handler));
             }
             if (conf.get(Constants.SERVICE_VENDOR) != null) {
                 addProperty(new Property(Constants.SERVICE_VENDOR, null, null, (String) conf.get(Constants.SERVICE_VENDOR), String.class.getName(), handler.getInstanceManager(), handler));
@@ -316,10 +327,10 @@ public class ProvidedService implements 
      * This method also notifies the creation strategy of the publication.
      */
     protected synchronized void registerService() {
-        if (m_handler.getInstanceManager().getState() == ComponentInstance.VALID 
+        if (m_handler.getInstanceManager().getState() == ComponentInstance.VALID
                 && m_serviceRegistration == null  && (m_controller == null || m_controller.getValue())) {
             // Build the service properties list
-            
+
             BundleContext bc = m_handler.getInstanceManager().getContext();
             // Security check
             if (SecurityHelper.hasPermissionToRegisterServices(m_serviceSpecifications, bc)) {
@@ -331,10 +342,21 @@ public class ProvidedService implements 
                     m_serviceRegistration.setProperties(getServiceProperties());
                     m_wasUpdated = false;
                 }
+
+                // Call the post-registration callback in the same thread holding the monitor lock.
+                // This allows to be sure that the callback is called once per registration.
+                // But the callback must take care to not create a deadlock
+                if (m_postRegistration != null) {
+	                try {
+						m_postRegistration.call(new Object[] { m_serviceRegistration.getReference() });
+					} catch (Exception e) {
+						m_handler.error("Cannot invoke the post-registration callback " + m_postRegistration.getMethod(), e);
+					}
+                }
             } else {
                 throw new SecurityException("The bundle " + bc.getBundle().getBundleId() + " does not have the"
                         + " permission to register the services " + Arrays.asList(m_serviceSpecifications));
-            }      
+            }
         }
     }
 
@@ -342,13 +364,29 @@ public class ProvidedService implements 
      * Unregisters the service.
      */
     protected synchronized void unregisterService() {
+    	// Create a copy of the service reference in the case we need
+    	// to inject it to the post-unregistration callback.
+
+    	ServiceReference ref = null;
         if (m_serviceRegistration != null) {
+    		ref = m_serviceRegistration.getReference();
             m_serviceRegistration.unregister();
             m_serviceRegistration = null;
         }
 
         m_strategy.onUnpublication();
 
+        // Call the post-unregistration callback in the same thread holding the monitor lock.
+        // This allows to be sure that the callback is called once per unregistration.
+        // But the callback must take care to not create a deadlock
+        if (m_postUnregistration != null   && ref != null) {
+            try {
+            	m_postUnregistration.call(new Object[] { ref });
+			} catch (Exception e) {
+				m_handler.error("Cannot invoke the post-unregistration callback " + m_postUnregistration.getMethod(), e);
+			}
+        }
+
     }
 
     /**
@@ -463,12 +501,20 @@ public class ProvidedService implements 
     public void setController(String field, boolean value) {
         m_controller = new ServiceController(field, value);
     }
-    
+
     public ServiceController getController() {
         return m_controller;
     }
 
-    /**
+    public void setPostRegistrationCallback(Callback cb) {
+		m_postRegistration = cb;
+	}
+
+    public void setPostUnregistrationCallback(Callback cb) {
+		m_postUnregistration = cb;
+	}
+
+	/**
      * Service Controller.
      */
     class ServiceController {
@@ -480,7 +526,7 @@ public class ProvidedService implements 
          * The field attached to this controller.
          */
         private final String m_field;
-        
+
         /**
          * Creates a ServiceController.
          * @param field the field
@@ -494,7 +540,7 @@ public class ProvidedService implements 
         public String getField() {
             return m_field;
         }
-        
+
         /**
          * Gets the value.
          * @return the value
@@ -521,7 +567,7 @@ public class ProvidedService implements 
                 }
             }
         }
-        
+
     }
 
     /**

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java?rev=940905&r1=940904&r2=940905&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java Tue May  4 15:22:36 2010
@@ -1,4 +1,4 @@
-/* 
+/*
  * 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
@@ -42,9 +42,11 @@ import org.apache.felix.ipojo.parser.Man
 import org.apache.felix.ipojo.parser.ParseException;
 import org.apache.felix.ipojo.parser.ParseUtils;
 import org.apache.felix.ipojo.parser.PojoMetadata;
+import org.apache.felix.ipojo.util.Callback;
 import org.apache.felix.ipojo.util.Logger;
 import org.apache.felix.ipojo.util.Property;
 import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceReference;
 
 /**
  * Composite Provided Service Handler.
@@ -57,7 +59,7 @@ public class ProvidedServiceHandler exte
      * The list of the provided service.
      */
     private ProvidedService[] m_providedServices = new ProvidedService[0];
-    
+
     /**
      * The handler description.
      */
@@ -65,7 +67,7 @@ public class ProvidedServiceHandler exte
 
     /**
      * Add a provided service to the list .
-     * 
+     *
      * @param svc : the provided service to add
      */
     private void addProvidedService(ProvidedService svc) {
@@ -133,13 +135,28 @@ public class ProvidedServiceHandler exte
                         throw new ConfigurationException("The custom creation policy class " + strategy + " cannot be loaded " + e.getMessage());
 
                     }
-                    
+
                 }
             }
-            
+
+
             // Then create the provided service
             ProvidedService svc = new ProvidedService(this, serviceSpecifications, factory, custom, configuration);
 
+            // Post-Registration callback
+            String post = providedServices[i].getAttribute("post-registration");
+            if (post != null) {
+            	Callback cb = new Callback(post, new Class[] {ServiceReference.class}, false, getInstanceManager());
+            	svc.setPostRegistrationCallback(cb);
+            }
+
+            post = providedServices[i].getAttribute("post-unregistration");
+            if (post != null) {
+            	// TODO Can we really send the service reference here ?
+            	Callback cb = new Callback(post, new Class[] {ServiceReference.class}, false, getInstanceManager());
+            	svc.setPostUnregistrationCallback(cb);
+            }
+
             Element[] props = providedServices[i].getElements("Property");
             if (props != null) {
                 //Property[] properties = new Property[props.length];
@@ -153,15 +170,15 @@ public class ProvidedServiceHandler exte
                     Property prop = new Property(name, field, null, value, type, getInstanceManager(), this);
                     properties[j] = prop;
 
-                    // Check if the instance configuration has a value for this property                    
+                    // Check if the instance configuration has a value for this property
                     Object object = configuration.get(prop.getName());
                     if (object != null) {
                         prop.setValue(object);
                     }
-                    
+
                     if (field != null) {
                         getInstanceManager().register(new FieldMetadata(field, type), this);
-                        // Cannot register the property as the interception is necessary 
+                        // Cannot register the property as the interception is necessary
                         // to deal with registration update.
                     }
                 }
@@ -169,22 +186,22 @@ public class ProvidedServiceHandler exte
                 // Attach to properties to the provided service
                 svc.setProperties(properties);
             }
-            
+
             Element[] controllers = providedServices[i].getElements("Controller");
             if (controllers != null) {
                 if (controllers.length > 1) {
                     throw new ConfigurationException("Cannot have several controller per 'provides' element");
                 }
-                
+
                 String field = controllers[0].getAttribute("field");
                 if (field == null) {
                     throw new ConfigurationException("The field attribute of a controller is mandatory");
                 }
-                
+
                 String v = controllers[0].getAttribute("value");
                 boolean value = ! (v != null  && v.equalsIgnoreCase("false"));
                 svc.setController(field, value);
-                
+
                 getInstanceManager().register(new FieldMetadata(field, "boolean"), this);
             }
 
@@ -196,15 +213,15 @@ public class ProvidedServiceHandler exte
                     itfs.append(' ');
                     itfs.append(serviceSpecifications[j]);
                 }
-                throw new ConfigurationException("The provided service" + itfs + " is not valid");                
+                throw new ConfigurationException("The provided service" + itfs + " is not valid");
             }
-            
+
             // Initialize the description.
             m_description = new ProvidedServiceHandlerDescription(this, m_providedServices);
 
         }
     }
-    
+
     /**
      * Collect interfaces implemented by the POJO.
      * @param specs : implemented interfaces.
@@ -231,7 +248,7 @@ public class ProvidedServiceHandler exte
 
         return result;
     }
-    
+
     /**
      * Look for inherited interfaces.
      * @param clazz : interface name to explore (class object)
@@ -246,7 +263,7 @@ public class ProvidedServiceHandler exte
             collectInterfaces(clazzes[i], acc, bundle);
         }
     }
-    
+
     /**
      * Collect interfaces for the given class.
      * This method explores super class to.
@@ -274,10 +291,10 @@ public class ProvidedServiceHandler exte
      * @return true if the provided service is correct
      * @throws ConfigurationException : the checked provided service is not correct.
      */
-    private boolean checkProvidedService(ProvidedService svc) throws ConfigurationException {        
+    private boolean checkProvidedService(ProvidedService svc) throws ConfigurationException {
         for (int i = 0; i < svc.getServiceSpecifications().length; i++) {
             String specName = svc.getServiceSpecifications()[i];
-            
+
             // Check service level dependencies
             try {
                 Class spec = getInstanceManager().getFactory().loadClass(specName);
@@ -370,7 +387,7 @@ public class ProvidedServiceHandler exte
 
     /**
      * Stop the provided service handler.
-     * 
+     *
      * @see org.apache.felix.ipojo.Handler#stop()
      */
     public void stop() {
@@ -379,7 +396,7 @@ public class ProvidedServiceHandler exte
 
     /**
      * Start the provided service handler.
-     * 
+     *
      * @see org.apache.felix.ipojo.Handler#start()
      */
     public void start() {
@@ -439,7 +456,7 @@ public class ProvidedServiceHandler exte
                 Property prop = svc.getProperties()[j];
                 if (fieldName.equals(prop.getField())) {
                     // Manage the No Value case.
-                    return prop.onGet(pojo, fieldName, value); 
+                    return prop.onGet(pojo, fieldName, value);
                 }
             }
             if (svc.getController() != null  && svc.getController().getField().equals(fieldName)) {
@@ -453,7 +470,7 @@ public class ProvidedServiceHandler exte
     /**
      * Register the services if the new state is VALID. Unregister the services
      * if the new state is UNRESOLVED.
-     * 
+     *
      * @param state : the new instance state.
      * @see org.apache.felix.ipojo.Handler#stateChanged(int)
      */
@@ -488,7 +505,7 @@ public class ProvidedServiceHandler exte
 
     /**
      * Remove properties form all provided services.
-     * 
+     *
      * @param dict : dictionary of properties to delete.
      */
     public void removeProperties(Dictionary dict) {
@@ -551,7 +568,7 @@ public class ProvidedServiceHandler exte
             } catch (ClassNotFoundException e) {
                 throw new ConfigurationException("An interface cannot be loaded : " + e.getMessage());
             }
-            
+
             String serviceSpecificationStr = provides[i].getAttribute("specifications");
             if (serviceSpecificationStr == null) {
                 serviceSpecificationStr = provides[i].getAttribute("interface");
@@ -565,14 +582,14 @@ public class ProvidedServiceHandler exte
                 for (int j = 0; j < itfs.size(); j++) {
                     if (! all.contains(itfs.get(j))) {
                         if (parent == null || (parent != null && ! parent.equals((String) itfs.get(j)))) {
-                            desc.getFactory().getLogger().log(Logger.WARNING, "The specification " + itfs.get(j) + " is not implemented by " + metadata.getAttribute("classname") 
+                            desc.getFactory().getLogger().log(Logger.WARNING, "The specification " + itfs.get(j) + " is not implemented by " + metadata.getAttribute("classname")
                                     + " it might be a superclass or the class itself.");
                         }
                     }
                 }
                 all = new HashSet(itfs);
             }
-            
+
             if (all.isEmpty()) {
                 throw new ConfigurationException("Service Providing: Cannot instantiate a provided service : no specifications found (no interfaces implemented by the pojo)");
             }
@@ -580,7 +597,7 @@ public class ProvidedServiceHandler exte
             StringBuffer specs = null;
             Set set = new HashSet(all);
             set.remove(Pojo.class.getName()); // Remove POJO.
-            Iterator iterator = set.iterator(); 
+            Iterator iterator = set.iterator();
             while (iterator.hasNext()) {
                 String spec = (String) iterator.next();
                 desc.addProvidedServiceSpecification(spec);
@@ -592,7 +609,7 @@ public class ProvidedServiceHandler exte
                     specs.append(spec);
                 }
             }
-            
+
             specs.append('}');
             provides[i].addAttribute(new Attribute("specifications", specs.toString())); // Add interface attribute to avoid checking in the configure method
 
@@ -602,7 +619,7 @@ public class ProvidedServiceHandler exte
                 String value = props[j].getAttribute("value");
                 String type = props[j].getAttribute("type");
                 String field = props[j].getAttribute("field");
-                
+
 
                 // Get property name :
                 if (field != null && name == null) {
@@ -621,17 +638,17 @@ public class ProvidedServiceHandler exte
                     type = fieldMeta.getFieldType();
                     props[j].addAttribute(new Attribute("type", type));
                 }
-                
+
                 // Is the property set to immutable
                 boolean immutable = false;
                 String imm = props[j].getAttribute("immutable");
                 if (imm != null && imm.equalsIgnoreCase("true")) {
                     immutable = true;
                 }
-                
+
                 PropertyDescription pd = new PropertyDescription(name, type, value, immutable);
                 desc.addProperty(pd);
-                
+
                 String man = props[j].getAttribute("mandatory");
                 if (man != null && man.equalsIgnoreCase("true")) {
                     pd.setMandatory();

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/DependencyModel.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/DependencyModel.java?rev=940905&r1=940904&r2=940905&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/DependencyModel.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/DependencyModel.java Tue May  4 15:22:36 2010
@@ -431,7 +431,7 @@ public abstract class DependencyModel im
      * @param obj the service object if the service was get
      */
     private void manageDeparture(ServiceReference ref, Object obj) {
-        // Unget the service reference
+    	// Unget the service reference
         ungetService(ref);
 
         // If we already get this service and the binding policy is static, the dependency becomes broken

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Tracker.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Tracker.java?rev=940905&r1=940904&r2=940905&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Tracker.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Tracker.java Tue May  4 15:22:36 2010
@@ -748,8 +748,10 @@ public class Tracker implements TrackerC
                 if (!isTraked) { return; }
                 modified();
             }
-            // Call customizer outside of synchronized region
-            m_customizer.removedService(reference, object);
+            // Call customizer outside of synchronized region and only if we are not closed
+            if (! m_closed) {
+            	m_customizer.removedService(reference, object);
+            }
             // If the customizer throws an unchecked exception, it is safe to let it propagate
         }
 

Modified: felix/trunk/ipojo/core/src/main/resources/core.xsd
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/resources/core.xsd?rev=940905&r1=940904&r2=940905&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/resources/core.xsd (original)
+++ felix/trunk/ipojo/core/src/main/resources/core.xsd Tue May  4 15:22:36 2010
@@ -409,6 +409,18 @@
           specifying the qualified name of the class extending CreationPolicy</xs:documentation>
       </xs:annotation>
     </xs:attribute>
+    <xs:attribute name="post-registration" type="xs:string" use="optional">
+      <xs:annotation>
+        <xs:documentation>Defines a callback called after the service registration. The callback takes a ServiceReference
+        as parameter</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="post-unregistration" type="xs:string" use="optional">
+      <xs:annotation>
+        <xs:documentation>Defines a callback called after the service unregistration. The callback takes a ServiceReference
+        as parameter</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
   </xs:complexType>
   <xs:complexType name="ServiceControllerType">
     <xs:annotation>

Modified: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MethodCollector.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MethodCollector.java?rev=940905&r1=940904&r2=940905&view=diff
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MethodCollector.java (original)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MethodCollector.java Tue May  4 15:22:36 2010
@@ -1,4 +1,4 @@
-/* 
+/*
  * 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
@@ -25,7 +25,7 @@ import org.objectweb.asm.Type;
 import org.objectweb.asm.commons.EmptyVisitor;
 
 /**
- * This class collects method annotations, and give them to the metadata collector. 
+ * This class collects method annotations, and give them to the metadata collector.
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 public class MethodCollector extends EmptyVisitor {
@@ -34,9 +34,9 @@ public class MethodCollector extends Emp
      * Parent collector.
      */
     private MetadataCollector m_collector;
-    
+
     /**
-     * Method name. 
+     * Method name.
      */
     private String m_name;
 
@@ -79,13 +79,19 @@ public class MethodCollector extends Emp
         if (arg0.equals("Lorg/apache/felix/ipojo/annotations/Unbind;")) {
             return processBind("unbind");
         }
-        
+        if (arg0.equals("Lorg/apache/felix/ipojo/annotations/PostRegistration;")) {
+            return processPostRegistration();
+        }
+        if (arg0.equals("Lorg/apache/felix/ipojo/annotations/PostUnregistration;")) {
+            return processPostUnregistration();
+        }
+
         if (CustomAnnotationVisitor.isCustomAnnotation(arg0)) {
             Element elem = CustomAnnotationVisitor.buildElement(arg0);
             elem.addAttribute(new Attribute("method", m_name));
             return new CustomAnnotationVisitor(elem, m_collector, true, false);
         }
-        
+
         return null;
     }
 
@@ -102,9 +108,41 @@ public class MethodCollector extends Emp
         } else {
             parent = (Element) m_collector.getIds().get("properties");
         }
-        
+
         parent.addAttribute(new Attribute("updated", m_name));
-        
+
+        return null;
+    }
+
+    /**
+     * Process @PostRegistration annotation.
+     * @return null.
+     */
+    private AnnotationVisitor processPostRegistration() {
+        Element parent = null;
+        if (m_collector.getIds().containsKey("provides")) {
+            parent = (Element) m_collector.getIds().get("provides");
+            parent.addAttribute(new Attribute("post-registration", m_name));
+        } else {
+            // Ignore annotation...
+        }
+
+        return null;
+    }
+
+    /**
+     * Process @PostRegistration annotation.
+     * @return null.
+     */
+    private AnnotationVisitor processPostUnregistration() {
+        Element parent = null;
+        if (m_collector.getIds().containsKey("provides")) {
+            parent = (Element) m_collector.getIds().get("provides");
+            parent.addAttribute(new Attribute("post-unregistration", m_name));
+        } else {
+            // Ignore annotation...
+        }
+
         return null;
     }
 
@@ -183,7 +221,7 @@ public class MethodCollector extends Emp
         private String m_aggregate;
 
         /**
-         * Required specification. 
+         * Required specification.
          */
         private String m_specification;
 
@@ -196,22 +234,22 @@ public class MethodCollector extends Emp
          * Bind, Modify or Unbind method?
          */
         private String m_type;
-        
+
         /**
          * Binding policy.
          */
         private String m_policy;
-        
+
         /**
          * Comparator.
          */
         private String m_comparator;
-        
+
         /**
          * From attribute.
          */
         private String m_from;
-        
+
         /**
          * Constructor.
          * @param bind : method name.
@@ -262,7 +300,7 @@ public class MethodCollector extends Emp
                 m_from = arg1.toString();
                 return;
             }
-            
+
         }
 
         /**
@@ -326,7 +364,7 @@ public class MethodCollector extends Emp
                         return;
                     }
                 }
-                
+
                 if (m_optional != null) {
                     if (optional == null) {
                         req.addAttribute(new Attribute("optional", m_optional));
@@ -335,7 +373,7 @@ public class MethodCollector extends Emp
                         return;
                     }
                 }
-                
+
                 if (m_aggregate != null) {
                     if (aggregate == null) {
                         req.addAttribute(new Attribute("aggregate", m_aggregate));
@@ -344,7 +382,7 @@ public class MethodCollector extends Emp
                         return;
                     }
                 }
-                
+
                 if (m_filter != null) {
                     if (filter == null) {
                         req.addAttribute(new Attribute("filter", m_filter));
@@ -353,7 +391,7 @@ public class MethodCollector extends Emp
                         return;
                     }
                 }
-                
+
                 if (m_policy != null) {
                     if (policy == null) {
                         req.addAttribute(new Attribute("policy", m_policy));
@@ -362,7 +400,7 @@ public class MethodCollector extends Emp
                         return;
                     }
                 }
-                
+
                 if (m_comparator != null) {
                     if (comparator == null) {
                         req.addAttribute(new Attribute("comparator", m_comparator));
@@ -371,7 +409,7 @@ public class MethodCollector extends Emp
                         return;
                     }
                 }
-                
+
                 if (m_from != null) {
                     if (from == null) {
                         req.addAttribute(new Attribute("from", m_from));
@@ -380,7 +418,7 @@ public class MethodCollector extends Emp
                         return;
                     }
                 }
-                
+
             }
             Element method = new Element("callback", "");
             method.addAttribute(new Attribute("method", m_name));
@@ -398,22 +436,22 @@ public class MethodCollector extends Emp
          * Parent element.
          */
         private Element m_parent;
-        
+
         /**
          * Attached method.
          */
         private String m_method;
-        
+
         /**
-         * Property name. 
+         * Property name.
          */
         private String m_name;
-        
+
         /**
-         * Property value. 
+         * Property value.
          */
         private String m_value;
-        
+
         /**
          * Property mandatory aspect.
          */

Modified: felix/trunk/ipojo/manipulator/src/main/resources/core.xsd
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/resources/core.xsd?rev=940905&r1=940904&r2=940905&view=diff
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/resources/core.xsd (original)
+++ felix/trunk/ipojo/manipulator/src/main/resources/core.xsd Tue May  4 15:22:36 2010
@@ -409,6 +409,18 @@
           specifying the qualified name of the class extending CreationPolicy</xs:documentation>
       </xs:annotation>
     </xs:attribute>
+    <xs:attribute name="post-registration" type="xs:string" use="optional">
+      <xs:annotation>
+        <xs:documentation>Defines a callback called after the service registration. The callback takes a ServiceReference
+        as parameter</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="post-unregistration" type="xs:string" use="optional">
+      <xs:annotation>
+        <xs:documentation>Defines a callback called after the service unregistration. The callback takes a ServiceReference
+        as parameter</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
   </xs:complexType>
   <xs:complexType name="ServiceControllerType">
     <xs:annotation>

Modified: felix/trunk/ipojo/plugin/src/main/resources/archetype-resources/pom.xml
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/plugin/src/main/resources/archetype-resources/pom.xml?rev=940905&r1=940904&r2=940905&view=diff
==============================================================================
--- felix/trunk/ipojo/plugin/src/main/resources/archetype-resources/pom.xml (original)
+++ felix/trunk/ipojo/plugin/src/main/resources/archetype-resources/pom.xml Tue May  4 15:22:36 2010
@@ -1,38 +1,39 @@
-<project>
-  <modelVersion>4.0.0</modelVersion>
-  <packaging>bundle</packaging>
-  <groupId>${groupId}</groupId>
-  <artifactId>${artifactId}</artifactId>
-  <version>${version}</version>
-  <name>$YOUR_PROJECT_NAME</name>
-  
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.felix</groupId>
-        <artifactId>maven-bundle-plugin</artifactId>
-        <version>1.4.3</version>
-        <extensions>true</extensions>
-        <configuration>
-          <instructions>
-            <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
-            <Private-Package>YOUR_PRIVATE_PACKAGES</Private-Package>
-            <Import-Package>*</Import-Package> <!-- YOUR_IMPORTED_PACKAGES -->
-            <Export-Package>*</Export-Package> <!-- YOUR_EXPORTED_PACKAGES -->
-          </instructions>
-        </configuration>
-      </plugin>
-      <plugin>
-	      <groupId>org.apache.felix</groupId>
-	      <artifactId>maven-ipojo-plugin</artifactId>
-		  <executions>
-          	<execution>
-            	<goals>
-	              <goal>ipojo-bundle</goal>
-               </goals>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<packaging>bundle</packaging>
+	<groupId>${groupId}</groupId>
+	<artifactId>${artifactId}</artifactId>
+	<version>${version}</version>
+	<name>$YOUR_PROJECT_NAME</name>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.felix</groupId>
+				<artifactId>maven-bundle-plugin</artifactId>
+				<version>1.4.3</version>
+				<extensions>true</extensions>
+				<configuration>
+					<instructions>
+						<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
+						<Private-Package>YOUR_PRIVATE_PACKAGES</Private-Package>
+						<Import-Package>*</Import-Package> <!-- YOUR_IMPORTED_PACKAGES -->
+						<Export-Package>*</Export-Package> <!-- YOUR_EXPORTED_PACKAGES -->
+					</instructions>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.felix</groupId>
+				<artifactId>maven-ipojo-plugin</artifactId>
+				<executions>
+					<execution>
+						<goals>
+							<goal>ipojo-bundle</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+		</plugins>
+	</build>
 </project>

Modified: felix/trunk/ipojo/tests/core/service-providing/pom.xml
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/tests/core/service-providing/pom.xml?rev=940905&r1=940904&r2=940905&view=diff
==============================================================================
--- felix/trunk/ipojo/tests/core/service-providing/pom.xml (original)
+++ felix/trunk/ipojo/tests/core/service-providing/pom.xml Tue May  4 15:22:36 2010
@@ -93,9 +93,17 @@
             </goals>
             <configuration>
               <ignoreAnnotations>true</ignoreAnnotations>
+              <ignoreEmbeddedSchemas>true</ignoreEmbeddedSchemas>
             </configuration>
           </execution>
         </executions>
+        <dependencies>
+        	<dependency>
+        		<groupId>org.apache.felix</groupId>
+        		<artifactId>org.apache.felix.ipojo.manipulator</artifactId>
+        		<version>1.7.0-SNAPSHOT</version>
+        	</dependency>
+        </dependencies>
       </plugin>
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>

Added: felix/trunk/ipojo/tests/core/service-providing/src/main/java/org/apache/felix/ipojo/test/scenarios/component/callbacks/CallbacksCheckService.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/tests/core/service-providing/src/main/java/org/apache/felix/ipojo/test/scenarios/component/callbacks/CallbacksCheckService.java?rev=940905&view=auto
==============================================================================
--- felix/trunk/ipojo/tests/core/service-providing/src/main/java/org/apache/felix/ipojo/test/scenarios/component/callbacks/CallbacksCheckService.java (added)
+++ felix/trunk/ipojo/tests/core/service-providing/src/main/java/org/apache/felix/ipojo/test/scenarios/component/callbacks/CallbacksCheckService.java Tue May  4 15:22:36 2010
@@ -0,0 +1,92 @@
+package org.apache.felix.ipojo.test.scenarios.component.callbacks;
+
+import java.util.Properties;
+
+import org.apache.felix.ipojo.test.scenarios.ps.service.CheckService;
+import org.apache.felix.ipojo.test.scenarios.ps.service.FooService;
+import org.osgi.framework.ServiceReference;
+
+public class CallbacksCheckService implements FooService, CheckService {
+
+	// 4 Counters
+	int registered = 0;
+	int unregistered = 0;
+	int registered2 = 0;
+	int unregistered2 = 0;
+
+	// 4 Methods
+	public void registered(ServiceReference ref) {
+		if (ref == null) {
+			throw new IllegalArgumentException("ref null");
+		}
+		registered++;
+	}
+
+	public void unregistered(ServiceReference ref) {
+		if (ref == null) {
+			throw new IllegalArgumentException("ref null");
+		}
+		unregistered++;
+	}
+
+	public void registered2(ServiceReference ref) {
+		if (ref == null) {
+			throw new IllegalArgumentException("ref null");
+		}
+		registered2++;
+	}
+
+	public void unregistered2(ServiceReference ref) {
+		if (ref == null) {
+			throw new IllegalArgumentException("ref null");
+		}
+		unregistered2++;
+	}
+
+    public boolean foo() {
+        return true;
+    }
+
+    public Properties fooProps() {
+        Properties props = new Properties();
+        props.put("registered", new Integer(registered));
+        props.put("registered2", new Integer(registered2));
+        props.put("unregistered", new Integer(unregistered));
+        props.put("unregistered2", new Integer(unregistered2));
+        return props;
+    }
+
+    public boolean getBoolean() {
+        return false;
+    }
+
+    public double getDouble() {
+        return 0;
+    }
+
+    public int getInt() {
+        return 0;
+    }
+
+    public long getLong() {
+        return 0;
+    }
+
+    public Boolean getObject() {
+        return null;
+    }
+
+    public boolean check() {
+       return true;
+    }
+
+    public Properties getProps() {
+        Properties props = new Properties();
+        props.put("registered", new Integer(registered));
+        props.put("registered2", new Integer(registered2));
+        props.put("unregistered", new Integer(unregistered));
+        props.put("unregistered2", new Integer(unregistered2));
+        return props;
+    }
+
+}

Added: felix/trunk/ipojo/tests/core/service-providing/src/main/java/org/apache/felix/ipojo/test/scenarios/ps/CallbacksTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/tests/core/service-providing/src/main/java/org/apache/felix/ipojo/test/scenarios/ps/CallbacksTest.java?rev=940905&view=auto
==============================================================================
--- felix/trunk/ipojo/tests/core/service-providing/src/main/java/org/apache/felix/ipojo/test/scenarios/ps/CallbacksTest.java (added)
+++ felix/trunk/ipojo/tests/core/service-providing/src/main/java/org/apache/felix/ipojo/test/scenarios/ps/CallbacksTest.java Tue May  4 15:22:36 2010
@@ -0,0 +1,177 @@
+/*
+ * 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.ipojo.test.scenarios.ps;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;
+import org.apache.felix.ipojo.junit4osgi.helpers.IPOJOHelper;
+import org.apache.felix.ipojo.test.scenarios.ps.service.CheckService;
+import org.apache.felix.ipojo.test.scenarios.ps.service.FooService;
+
+public class CallbacksTest extends OSGiTestCase {
+
+    IPOJOHelper helper;
+
+    public void setUp() {
+        helper = new IPOJOHelper(this);
+    }
+
+
+    public void tearDown() {
+        helper.dispose();
+    }
+
+    public void testWithPostRegistrationOnly() {
+    	ComponentInstance ci = helper.createComponentInstance("PS-Callbacks-reg-only");
+        // Controller set to true.
+        waitForService(FooService.class.getName(), null, 5000);
+        waitForService(CheckService.class.getName(), null, 5000);
+
+        CheckService check = (CheckService) getServiceObject(CheckService.class.getName(), null);
+        assertNotNull(check);
+
+        Integer reg = (Integer) check.getProps().get("registered");
+        Integer unreg = (Integer) check.getProps().get("unregistered");
+        assertNotNull(reg);
+        assertNotNull(unreg);
+        assertEquals(new Integer(1), reg);
+        assertEquals(new Integer(0), unreg);
+
+        ci.stop();
+
+        reg = (Integer) check.getProps().get("registered");
+        unreg = (Integer) check.getProps().get("unregistered");
+        assertNotNull(reg);
+        assertNotNull(unreg);
+        assertEquals(new Integer(1), reg);
+        assertEquals(new Integer(0), unreg);
+    }
+
+    public void testWithBoth() {
+    	ComponentInstance ci = helper.createComponentInstance("PS-Callbacks-both");
+        // Controller set to true.
+        waitForService(FooService.class.getName(), null, 5000);
+        waitForService(CheckService.class.getName(), null, 5000);
+
+        CheckService check = (CheckService) getServiceObject(CheckService.class.getName(), null);
+        assertNotNull(check);
+
+        Integer reg = (Integer) check.getProps().get("registered");
+        Integer unreg = (Integer) check.getProps().get("unregistered");
+        assertNotNull(reg);
+        assertNotNull(unreg);
+        assertEquals(new Integer(1), reg);
+        assertEquals(new Integer(0), unreg);
+
+        ci.stop();
+
+        reg = (Integer) check.getProps().get("registered");
+        unreg = (Integer) check.getProps().get("unregistered");
+        assertNotNull(reg);
+        assertNotNull(unreg);
+        assertEquals(new Integer(1), reg);
+        assertEquals(new Integer(1), unreg);
+    }
+
+    public void testWithPostUnregistrationOnly() {
+    	ComponentInstance ci = helper.createComponentInstance("PS-Callbacks-unreg-only");
+        // Controller set to true.
+        waitForService(FooService.class.getName(), null, 5000);
+        waitForService(CheckService.class.getName(), null, 5000);
+
+        CheckService check = (CheckService) getServiceObject(CheckService.class.getName(), null);
+        assertNotNull(check);
+
+        Integer reg = (Integer) check.getProps().get("registered");
+        Integer unreg = (Integer) check.getProps().get("unregistered");
+        assertNotNull(reg);
+        assertNotNull(unreg);
+        assertEquals(new Integer(0), reg);
+        assertEquals(new Integer(0), unreg);
+
+        ci.stop();
+
+        reg = (Integer) check.getProps().get("registered");
+        unreg = (Integer) check.getProps().get("unregistered");
+        assertNotNull(reg);
+        assertNotNull(unreg);
+        assertEquals(new Integer(0), reg);
+        assertEquals(new Integer(1), unreg);
+    }
+
+    public void testWithTwoPairsOfCallbacks() {
+    	ComponentInstance ci = helper.createComponentInstance("PS-Callbacks-both-2");
+        // Controller set to true.
+        waitForService(FooService.class.getName(), null, 5000);
+        waitForService(CheckService.class.getName(), null, 5000);
+
+        CheckService check = (CheckService) getServiceObject(CheckService.class.getName(), null);
+        assertNotNull(check);
+
+        Integer reg = (Integer) check.getProps().get("registered");
+        Integer unreg = (Integer) check.getProps().get("unregistered");
+        Integer reg2 = (Integer) check.getProps().get("registered2");
+        Integer unreg2 = (Integer) check.getProps().get("unregistered2");
+        assertNotNull(reg);
+        assertNotNull(unreg);
+        assertNotNull(reg2);
+        assertNotNull(unreg2);
+        assertEquals(new Integer(1), reg);
+        assertEquals(new Integer(0), unreg);
+        assertEquals(new Integer(1), reg2);
+        assertEquals(new Integer(0), unreg2);
+
+        ci.stop();
+
+        reg = (Integer) check.getProps().get("registered");
+        unreg = (Integer) check.getProps().get("unregistered");
+        reg2 = (Integer) check.getProps().get("registered2");
+        unreg2 = (Integer) check.getProps().get("unregistered2");
+        assertNotNull(reg2);
+        assertNotNull(unreg2);
+        assertEquals(new Integer(1), reg);
+        assertEquals(new Integer(1), unreg);
+        assertEquals(new Integer(1), reg2);
+        assertEquals(new Integer(1), unreg2);
+    }
+
+    public void testWithOnePairForTwoService() {
+    	ComponentInstance ci = helper.createComponentInstance("PS-Callbacks-both-1");
+        // Controller set to true.
+        waitForService(FooService.class.getName(), null, 5000);
+        waitForService(CheckService.class.getName(), null, 5000);
+
+        CheckService check = (CheckService) getServiceObject(CheckService.class.getName(), null);
+        assertNotNull(check);
+
+        Integer reg = (Integer) check.getProps().get("registered");
+        Integer unreg = (Integer) check.getProps().get("unregistered");
+        assertNotNull(reg);
+        assertNotNull(unreg);
+        assertEquals(new Integer(2), reg);
+        assertEquals(new Integer(0), unreg);
+
+        ci.stop();
+
+        reg = (Integer) check.getProps().get("registered");
+        unreg = (Integer) check.getProps().get("unregistered");
+        assertEquals(new Integer(2), reg);
+        assertEquals(new Integer(2), unreg);
+    }
+}

Modified: felix/trunk/ipojo/tests/core/service-providing/src/main/java/org/apache/felix/ipojo/test/scenarios/ps/ProvidedServiceTestSuite.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/tests/core/service-providing/src/main/java/org/apache/felix/ipojo/test/scenarios/ps/ProvidedServiceTestSuite.java?rev=940905&r1=940904&r2=940905&view=diff
==============================================================================
--- felix/trunk/ipojo/tests/core/service-providing/src/main/java/org/apache/felix/ipojo/test/scenarios/ps/ProvidedServiceTestSuite.java (original)
+++ felix/trunk/ipojo/tests/core/service-providing/src/main/java/org/apache/felix/ipojo/test/scenarios/ps/ProvidedServiceTestSuite.java Tue May  4 15:22:36 2010
@@ -41,6 +41,7 @@ public class ProvidedServiceTestSuite ex
         ots.addTestSuite(NullCheck.class);
         ots.addTestSuite(ServiceControllerTest.class);
         ots.addTestSuite(PropertiesInAnonymousClassTest.class);
+        ots.addTestSuite(CallbacksTest.class);
         return ots;
     }
 

Modified: felix/trunk/ipojo/tests/core/service-providing/src/main/resources/metadata.xml
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/tests/core/service-providing/src/main/resources/metadata.xml?rev=940905&r1=940904&r2=940905&view=diff
==============================================================================
--- felix/trunk/ipojo/tests/core/service-providing/src/main/resources/metadata.xml (original)
+++ felix/trunk/ipojo/tests/core/service-providing/src/main/resources/metadata.xml Tue May  4 15:22:36 2010
@@ -1,227 +1,263 @@
 <ipojo
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:schemaLocation="org.apache.felix.ipojo http://felix.apache.org/ipojo/schemas/SNAPSHOT/core.xsd"
-    xmlns="org.apache.felix.ipojo"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="org.apache.felix.ipojo http://felix.apache.org/ipojo/schemas/SNAPSHOT/core.xsd"
+ xmlns="org.apache.felix.ipojo"
 >
-  <!-- Simple provider  -->
-  <component
-    classname="org.apache.felix.ipojo.test.scenarios.component.FooProviderType1"
-    name="PS-FooProviderType-1" architecture="true">
-    <provides />
-  </component>
-
-  <component
-    classname="org.apache.felix.ipojo.test.scenarios.component.FooProviderType1"
-    name="PS-FooProviderType-itf" architecture="true">
-    <provides
-      specifications="org.apache.felix.ipojo.test.scenarios.ps.service.FooService" />
-  </component>
-
-  <component
-    classname="org.apache.felix.ipojo.test.scenarios.component.FooProviderType1"
-    name="PS-FooProviderType-3" architecture="true">
-    <provides>
-      <property name="foo" field="m_foo" />
-      <property name="bar" field="m_bar" />
-      <property name="baz" type="java.lang.String" />
-    </provides>
-    <properties propagation="true">
-      <property name="foo" field="m_foo" />
-      <property name="bar" field="m_bar" />
-    </properties>
-  </component>
-
-  <!-- Providers providing 2 services -->
-  <component
-    classname="org.apache.felix.ipojo.test.scenarios.component.FooBarProviderType1"
-    name="PS-FooBarProviderType-1" architecture="true">
-    <provides />
-  </component>
-  <component
-    classname="org.apache.felix.ipojo.test.scenarios.component.FooBarProviderType1"
-    name="PS-FooBarProviderType-2" architecture="true">
-    <provides
-      specifications="{org.apache.felix.ipojo.test.scenarios.ps.service.FooService, org.apache.felix.ipojo.test.scenarios.ps.service.BarService }" />
-  </component>
-  <component
-    classname="org.apache.felix.ipojo.test.scenarios.component.FooBarProviderType1"
-    name="PS-FooBarProviderType-3" architecture="true">
-    <provides
-      specifications="{org.apache.felix.ipojo.test.scenarios.ps.service.FooService}">
-      <property name="baz" type="java.lang.String" value="foo" />
-    </provides>
-    <provides
-      specifications="{org.apache.felix.ipojo.test.scenarios.ps.service.BarService}">
-      <property name="baz" type="java.lang.String" value="bar" />
-    </provides>
-  </component>
-
-
-  <!-- Provider with dynamic property -->
-  <component
-    classname="org.apache.felix.ipojo.test.scenarios.component.FooProviderTypeDyn"
-    name="PS-FooProviderType-Dyn" architecture="true">
-    <provides>
-      <property name="int" field="intProp" value="2" />
-      <property name="boolean" field="boolProp" value="false" />
-      <property name="string" field="strProp" value="foo" />
-      <property name="strAProp" field="strAProp"
-        value="{foo, bar}" />
-      <property name="intAProp" field="intAProp" value="{1,2,3}" />
-    </provides>
-  </component>
-
-  <component
-    classname="org.apache.felix.ipojo.test.scenarios.component.FooProviderType1"
-    name="PS-FooProviderType-2" architecture="true">
-    <provides>
-      <property name="int" type="int" value="2" />
-      <property name="long" type="long" value="40" />
-      <property name="string" type="java.lang.String" value="foo" />
-      <property name="strAProp" type="java.lang.String[]"
-        value="{foo, bar}" />
-      <property name="intAProp" type="int[]" value="{1,2,3}" />
-    </provides>
-  </component>
-
-  <component
-    classname="org.apache.felix.ipojo.test.scenarios.component.FooProviderTypeDyn2"
-    name="PS-FooProviderType-Dyn2" architecture="true">
-    <provides>
-      <property name="int" field="intProp" value="4" />
-      <property name="boolean" field="boolProp" />
-      <property name="string" field="strProp" />
-      <property name="strAProp" field="strAProp" />
-      <property name="intAProp" field="intAProp"
-        value="{1, 2,3 }" />
-    </provides>
-  </component>
-
-  <!--  Inherited Provides -->
-  <component
-    classname="org.apache.felix.ipojo.test.scenarios.component.inherited.ProcessImplementation1"
-    name="PS-PI1" architecture="true">
-    <provides />
-  </component>
-
-  <component
-    classname="org.apache.felix.ipojo.test.scenarios.component.inherited.ProcessImplementation1"
-    name="PS-PI1-1" architecture="true">
-    <provides
-      specifications="org.apache.felix.ipojo.test.scenarios.ps.service.ParentParentInterface" />
-  </component>
-
-  <component
-    classname="org.apache.felix.ipojo.test.scenarios.component.inherited.ProcessImplementation1"
-    name="PS-PI1-2" architecture="true">
-    <provides
-      specifications="{org.apache.felix.ipojo.test.scenarios.ps.service.ParentParentInterface, org.apache.felix.ipojo.test.scenarios.ps.service.ParentInterface2}" />
-  </component>
-
-  <component
-    classname="org.apache.felix.ipojo.test.scenarios.component.inherited.ProcessImplementation2"
-    name="PS-PI2" architecture="true">
-    <provides />
-  </component>
-
-  <component
-    classname="org.apache.felix.ipojo.test.scenarios.component.inherited.ProcessImplementation2"
-    name="PS-PI2-1" architecture="true">
-    <provides
-      specifications="org.apache.felix.ipojo.test.scenarios.ps.service.ParentParentInterface" />
-  </component>
-
-  <component
-    classname="org.apache.felix.ipojo.test.scenarios.component.inherited.ProcessImplementation3"
-    name="PS-PI3" architecture="true">
-    <provides />
-  </component>
-
-  <!-- Concrete and abstract class -->
-  <component
-    classname="org.apache.felix.ipojo.test.scenarios.component.inherited.ProcessParentImplementation"
-    name="PS-PI4" architecture="true">
-    <provides specifications="org.apache.felix.ipojo.test.scenarios.component.inherited.ProcessParentImplementation"/>
-  </component>
-  <component
-    classname="org.apache.felix.ipojo.test.scenarios.component.inherited.ProcessImplementation2"
-    name="PS-PI5" architecture="true">
-    <provides specifications="org.apache.felix.ipojo.test.scenarios.component.inherited.ProcessParentImplementation"/>
-  </component>
-  <component
-    classname="org.apache.felix.ipojo.test.scenarios.component.inherited.ProcessImplementation4"
-    name="PS-PI6" architecture="true">
-    <provides specifications="org.apache.felix.ipojo.test.scenarios.component.inherited.ProcessParentImplementation"/>
-  </component>
-  <component
-    classname="org.apache.felix.ipojo.test.scenarios.component.inherited.ProcessImplementation3"
-    name="PS-PI7" architecture="true">
-    <provides specifications="[org.apache.felix.ipojo.test.scenarios.component.inherited.ProcessParentImplementation,
-          org.apache.felix.ipojo.test.scenarios.ps.service.FooService]"/>
-  </component>
-
-  <!--  Null Check -->
-  <component classname="org.apache.felix.ipojo.test.scenarios.component.NullCheckServiceProvider" immediate="true"
-    name="PS-Null">
-    <provides>
-      <property field="prop1"/>
-      <property field="prop2"/>
-    </provides>
-  </component>
-
-  <!--  Service Controller -->
-  <component classname="org.apache.felix.ipojo.test.scenarios.component.controller.ControllerCheckService"
-    name="PS-Controller-1-default">
-    <provides specifications="org.apache.felix.ipojo.test.scenarios.ps.service.FooService">
-      <controller field="controller"/>
-    </provides>
-    <provides specifications="org.apache.felix.ipojo.test.scenarios.ps.service.CheckService">
-    </provides>
-  </component>
+    <!-- Simple provider  -->
+    <component
+     classname="org.apache.felix.ipojo.test.scenarios.component.FooProviderType1"
+     name="PS-FooProviderType-1" architecture="true">
+        <provides/>
+    </component>
+
+    <component
+     classname="org.apache.felix.ipojo.test.scenarios.component.FooProviderType1"
+     name="PS-FooProviderType-itf" architecture="true">
+        <provides
+         specifications="org.apache.felix.ipojo.test.scenarios.ps.service.FooService"/>
+    </component>
+
+    <component
+     classname="org.apache.felix.ipojo.test.scenarios.component.FooProviderType1"
+     name="PS-FooProviderType-3" architecture="true">
+        <provides>
+            <property name="foo" field="m_foo"/>
+            <property name="bar" field="m_bar"/>
+            <property name="baz" type="java.lang.String"/>
+        </provides>
+        <properties propagation="true">
+            <property name="foo" field="m_foo"/>
+            <property name="bar" field="m_bar"/>
+        </properties>
+    </component>
+
+    <!-- Providers providing 2 services -->
+    <component
+     classname="org.apache.felix.ipojo.test.scenarios.component.FooBarProviderType1"
+     name="PS-FooBarProviderType-1" architecture="true">
+        <provides/>
+    </component>
+    <component
+     classname="org.apache.felix.ipojo.test.scenarios.component.FooBarProviderType1"
+     name="PS-FooBarProviderType-2" architecture="true">
+        <provides
+         specifications="{org.apache.felix.ipojo.test.scenarios.ps.service.FooService, org.apache.felix.ipojo.test.scenarios.ps.service.BarService }"/>
+    </component>
+    <component
+     classname="org.apache.felix.ipojo.test.scenarios.component.FooBarProviderType1"
+     name="PS-FooBarProviderType-3" architecture="true">
+        <provides
+         specifications="{org.apache.felix.ipojo.test.scenarios.ps.service.FooService}">
+            <property name="baz" type="java.lang.String" value="foo"/>
+        </provides>
+        <provides
+         specifications="{org.apache.felix.ipojo.test.scenarios.ps.service.BarService}">
+            <property name="baz" type="java.lang.String" value="bar"/>
+        </provides>
+    </component>
+
+
+    <!-- Provider with dynamic property -->
+    <component
+     classname="org.apache.felix.ipojo.test.scenarios.component.FooProviderTypeDyn"
+     name="PS-FooProviderType-Dyn" architecture="true">
+        <provides>
+            <property name="int" field="intProp" value="2"/>
+            <property name="boolean" field="boolProp" value="false"/>
+            <property name="string" field="strProp" value="foo"/>
+            <property name="strAProp" field="strAProp"
+             value="{foo, bar}"/>
+            <property name="intAProp" field="intAProp" value="{1,2,3}"/>
+        </provides>
+    </component>
+
+    <component
+     classname="org.apache.felix.ipojo.test.scenarios.component.FooProviderType1"
+     name="PS-FooProviderType-2" architecture="true">
+        <provides>
+            <property name="int" type="int" value="2"/>
+            <property name="long" type="long" value="40"/>
+            <property name="string" type="java.lang.String" value="foo"/>
+            <property name="strAProp" type="java.lang.String[]"
+             value="{foo, bar}"/>
+            <property name="intAProp" type="int[]" value="{1,2,3}"/>
+        </provides>
+    </component>
+
+    <component
+     classname="org.apache.felix.ipojo.test.scenarios.component.FooProviderTypeDyn2"
+     name="PS-FooProviderType-Dyn2" architecture="true">
+        <provides>
+            <property name="int" field="intProp" value="4"/>
+            <property name="boolean" field="boolProp"/>
+            <property name="string" field="strProp"/>
+            <property name="strAProp" field="strAProp"/>
+            <property name="intAProp" field="intAProp"
+             value="{1, 2,3 }"/>
+        </provides>
+    </component>
+
+    <!--  Inherited Provides -->
+    <component
+     classname="org.apache.felix.ipojo.test.scenarios.component.inherited.ProcessImplementation1"
+     name="PS-PI1" architecture="true">
+        <provides/>
+    </component>
+
+    <component
+     classname="org.apache.felix.ipojo.test.scenarios.component.inherited.ProcessImplementation1"
+     name="PS-PI1-1" architecture="true">
+        <provides
+         specifications="org.apache.felix.ipojo.test.scenarios.ps.service.ParentParentInterface"/>
+    </component>
+
+    <component
+     classname="org.apache.felix.ipojo.test.scenarios.component.inherited.ProcessImplementation1"
+     name="PS-PI1-2" architecture="true">
+        <provides
+         specifications="{org.apache.felix.ipojo.test.scenarios.ps.service.ParentParentInterface, org.apache.felix.ipojo.test.scenarios.ps.service.ParentInterface2}"/>
+    </component>
+
+    <component
+     classname="org.apache.felix.ipojo.test.scenarios.component.inherited.ProcessImplementation2"
+     name="PS-PI2" architecture="true">
+        <provides/>
+    </component>
+
+    <component
+     classname="org.apache.felix.ipojo.test.scenarios.component.inherited.ProcessImplementation2"
+     name="PS-PI2-1" architecture="true">
+        <provides
+         specifications="org.apache.felix.ipojo.test.scenarios.ps.service.ParentParentInterface"/>
+    </component>
+
+    <component
+     classname="org.apache.felix.ipojo.test.scenarios.component.inherited.ProcessImplementation3"
+     name="PS-PI3" architecture="true">
+        <provides/>
+    </component>
+
+    <!-- Concrete and abstract class -->
+    <component
+     classname="org.apache.felix.ipojo.test.scenarios.component.inherited.ProcessParentImplementation"
+     name="PS-PI4" architecture="true">
+        <provides specifications="org.apache.felix.ipojo.test.scenarios.component.inherited.ProcessParentImplementation"/>
+    </component>
+    <component
+     classname="org.apache.felix.ipojo.test.scenarios.component.inherited.ProcessImplementation2"
+     name="PS-PI5" architecture="true">
+        <provides specifications="org.apache.felix.ipojo.test.scenarios.component.inherited.ProcessParentImplementation"/>
+    </component>
+    <component
+     classname="org.apache.felix.ipojo.test.scenarios.component.inherited.ProcessImplementation4"
+     name="PS-PI6" architecture="true">
+        <provides specifications="org.apache.felix.ipojo.test.scenarios.component.inherited.ProcessParentImplementation"/>
+    </component>
+    <component
+     classname="org.apache.felix.ipojo.test.scenarios.component.inherited.ProcessImplementation3"
+     name="PS-PI7" architecture="true">
+        <provides specifications="[org.apache.felix.ipojo.test.scenarios.component.inherited.ProcessParentImplementation, org.apache.felix.ipojo.test.scenarios.ps.service.FooService]"/>
+    </component>
+
+    <!--  Null Check -->
+    <component classname="org.apache.felix.ipojo.test.scenarios.component.NullCheckServiceProvider" immediate="true"
+     name="PS-Null">
+        <provides>
+            <property field="prop1"/>
+            <property field="prop2"/>
+        </provides>
+    </component>
+
+    <!--  Service Controller -->
+    <component classname="org.apache.felix.ipojo.test.scenarios.component.controller.ControllerCheckService"
+     name="PS-Controller-1-default">
+        <provides specifications="org.apache.felix.ipojo.test.scenarios.ps.service.FooService">
+            <controller field="controller"/>
+        </provides>
+        <provides specifications="org.apache.felix.ipojo.test.scenarios.ps.service.CheckService">
+        </provides>
+    </component>
     <component classname="org.apache.felix.ipojo.test.scenarios.component.controller.ControllerCheckService"
-    name="PS-Controller-1-false">
-    <provides specifications="org.apache.felix.ipojo.test.scenarios.ps.service.FooService">
-      <property name="test2" type="string" value="test2"/>
-      <controller field="controller" value="false"/>
-      <property name="test" type="string" value="test"/>
-    </provides>
-    <provides specifications="org.apache.felix.ipojo.test.scenarios.ps.service.CheckService">
-    </provides>
-  </component>
-  <component classname="org.apache.felix.ipojo.test.scenarios.component.controller.DoubleControllerCheckService"
-    name="PS-Controller-2-truetrue">
-    <provides specifications="org.apache.felix.ipojo.test.scenarios.ps.service.FooService">
-      <property name="test2" type="string" value="test2"/>
-      <controller field="controllerFoo" value="true"/>
-      <property name="test" type="string" value="test"/>
-    </provides>
-    <provides specifications="org.apache.felix.ipojo.test.scenarios.ps.service.CheckService">
-        <controller field="controllerCS" value="true"/>
-    </provides>
-  </component>
-  <component classname="org.apache.felix.ipojo.test.scenarios.component.controller.DoubleControllerCheckService"
-    name="PS-Controller-2-truefalse">
-    <provides specifications="org.apache.felix.ipojo.test.scenarios.ps.service.FooService">
-      <property name="test2" type="string" value="test2"/>
-      <controller field="controllerFoo" value="false"/>
-      <property name="test" type="string" value="test"/>
-    </provides>
-    <provides specifications="org.apache.felix.ipojo.test.scenarios.ps.service.CheckService">
-        <controller field="controllerCS" value="true"/>
-    </provides>
-  </component>
-
-  <!-- Anonymous classes -->
-  <component
-    classname="org.apache.felix.ipojo.test.scenarios.component.FooProviderWithAnonymousClass"
-    name="PS-FooProviderTypeAnonymous-Dyn" architecture="true">
-    <provides>
-      <property name="int" field="intProp" value="2" />
-      <property name="boolean" field="boolProp" value="false" />
-      <property name="string" field="strProp" value="foo" />
-      <property name="strAProp" field="strAProp"
-        value="{foo, bar}" />
-      <property name="intAProp" field="intAProp" value="{1,2,3}" />
-    </provides>
-  </component>
+     name="PS-Controller-1-false">
+        <provides specifications="org.apache.felix.ipojo.test.scenarios.ps.service.FooService">
+            <property name="test2" type="string" value="test2"/>
+            <controller field="controller" value="false"/>
+            <property name="test" type="string" value="test"/>
+        </provides>
+        <provides specifications="org.apache.felix.ipojo.test.scenarios.ps.service.CheckService">
+        </provides>
+    </component>
+    <component classname="org.apache.felix.ipojo.test.scenarios.component.controller.DoubleControllerCheckService"
+     name="PS-Controller-2-truetrue">
+        <provides specifications="org.apache.felix.ipojo.test.scenarios.ps.service.FooService">
+            <property name="test2" type="string" value="test2"/>
+            <controller field="controllerFoo" value="true"/>
+            <property name="test" type="string" value="test"/>
+        </provides>
+        <provides specifications="org.apache.felix.ipojo.test.scenarios.ps.service.CheckService">
+            <controller field="controllerCS" value="true"/>
+        </provides>
+    </component>
+    <component classname="org.apache.felix.ipojo.test.scenarios.component.controller.DoubleControllerCheckService"
+     name="PS-Controller-2-truefalse">
+        <provides specifications="org.apache.felix.ipojo.test.scenarios.ps.service.FooService">
+            <property name="test2" type="string" value="test2"/>
+            <controller field="controllerFoo" value="false"/>
+            <property name="test" type="string" value="test"/>
+        </provides>
+        <provides specifications="org.apache.felix.ipojo.test.scenarios.ps.service.CheckService">
+            <controller field="controllerCS" value="true"/>
+        </provides>
+    </component>
+
+    <!-- Anonymous classes -->
+    <component
+     classname="org.apache.felix.ipojo.test.scenarios.component.FooProviderWithAnonymousClass"
+     name="PS-FooProviderTypeAnonymous-Dyn" architecture="true">
+        <provides>
+            <property name="int" field="intProp" value="2"/>
+            <property name="boolean" field="boolProp" value="false"/>
+            <property name="string" field="strProp" value="foo"/>
+            <property name="strAProp" field="strAProp"
+             value="{foo, bar}"/>
+            <property name="intAProp" field="intAProp" value="{1,2,3}"/>
+        </provides>
+    </component>
+
+    <!-- Registration callbacks -->
+    <component
+     classname="org.apache.felix.ipojo.test.scenarios.component.callbacks.CallbacksCheckService"
+     name="PS-Callbacks-reg-only">
+        <provides post-registration="registered"/>
+    </component>
+    <component
+     classname="org.apache.felix.ipojo.test.scenarios.component.callbacks.CallbacksCheckService"
+     name="PS-Callbacks-both">
+        <provides post-registration="registered" post-unregistration="unregistered"/>
+    </component>
+	<component
+     classname="org.apache.felix.ipojo.test.scenarios.component.callbacks.CallbacksCheckService"
+     name="PS-Callbacks-unreg-only">
+        <provides post-unregistration="unregistered"/>
+    </component>
+	<component
+     classname="org.apache.felix.ipojo.test.scenarios.component.callbacks.CallbacksCheckService"
+     name="PS-Callbacks-both-2">
+        <provides
+			specifications="org.apache.felix.ipojo.test.scenarios.ps.service.FooService"
+			post-unregistration="unregistered" post-registration="registered"/>
+		<provides
+			specifications="org.apache.felix.ipojo.test.scenarios.ps.service.CheckService"
+			post-unregistration="unregistered2" post-registration="registered2"/>
+    </component>
+	<component
+     classname="org.apache.felix.ipojo.test.scenarios.component.callbacks.CallbacksCheckService"
+     name="PS-Callbacks-both-1">
+        <provides
+			specifications="org.apache.felix.ipojo.test.scenarios.ps.service.FooService"
+			post-unregistration="unregistered" post-registration="registered"/>
+		<provides
+			specifications="org.apache.felix.ipojo.test.scenarios.ps.service.CheckService"
+			post-unregistration="unregistered" post-registration="registered"/>
+    </component>
 </ipojo>

Copied: felix/trunk/ipojo/tests/online-manipulator/src/test/java/org/apache/felix/ipojo/online/manipulator/test/OSGiHelper.java (from r939352, felix/trunk/ipojo/tests/online-manipulator/src/test/java/org/apache/felix/org/apache/felix/ipojo/online/manipulator/test/OSGiHelper.java)
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/tests/online-manipulator/src/test/java/org/apache/felix/ipojo/online/manipulator/test/OSGiHelper.java?p2=felix/trunk/ipojo/tests/online-manipulator/src/test/java/org/apache/felix/ipojo/online/manipulator/test/OSGiHelper.java&p1=felix/trunk/ipojo/tests/online-manipulator/src/test/java/org/apache/felix/org/apache/felix/ipojo/online/manipulator/test/OSGiHelper.java&r1=939352&r2=940905&rev=940905&view=diff
==============================================================================
--- felix/trunk/ipojo/tests/online-manipulator/src/test/java/org/apache/felix/org/apache/felix/ipojo/online/manipulator/test/OSGiHelper.java (original)
+++ felix/trunk/ipojo/tests/online-manipulator/src/test/java/org/apache/felix/ipojo/online/manipulator/test/OSGiHelper.java Tue May  4 15:22:36 2010
@@ -1,4 +1,4 @@
-package org.apache.felix.org.apache.felix.ipojo.online.manipulator.test;
+package org.apache.felix.ipojo.online.manipulator.test;
 
 import static org.junit.Assert.fail;
 

Copied: felix/trunk/ipojo/tests/online-manipulator/src/test/java/org/apache/felix/ipojo/online/manipulator/test/OnlineManipulatorTest.java (from r939968, felix/trunk/ipojo/tests/online-manipulator/src/test/java/org/apache/felix/org/apache/felix/ipojo/online/manipulator/test/OnlineManipulatorTest.java)
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/tests/online-manipulator/src/test/java/org/apache/felix/ipojo/online/manipulator/test/OnlineManipulatorTest.java?p2=felix/trunk/ipojo/tests/online-manipulator/src/test/java/org/apache/felix/ipojo/online/manipulator/test/OnlineManipulatorTest.java&p1=felix/trunk/ipojo/tests/online-manipulator/src/test/java/org/apache/felix/org/apache/felix/ipojo/online/manipulator/test/OnlineManipulatorTest.java&r1=939968&r2=940905&rev=940905&view=diff
==============================================================================
--- felix/trunk/ipojo/tests/online-manipulator/src/test/java/org/apache/felix/org/apache/felix/ipojo/online/manipulator/test/OnlineManipulatorTest.java (original)
+++ felix/trunk/ipojo/tests/online-manipulator/src/test/java/org/apache/felix/ipojo/online/manipulator/test/OnlineManipulatorTest.java Tue May  4 15:22:36 2010
@@ -1,4 +1,4 @@
-package org.apache.felix.org.apache.felix.ipojo.online.manipulator.test;
+package org.apache.felix.ipojo.online.manipulator.test;
 
 
 import static org.ops4j.pax.exam.CoreOptions.equinox;
@@ -19,9 +19,9 @@ import java.io.InputStream;
 import org.apache.felix.ipojo.ComponentInstance;
 import org.apache.felix.ipojo.architecture.Architecture;
 import org.apache.felix.ipojo.architecture.InstanceDescription;
-import org.apache.felix.org.apache.felix.ipojo.online.manipulator.test.impl.Consumer;
-import org.apache.felix.org.apache.felix.ipojo.online.manipulator.test.impl.MyProvider;
-import org.apache.felix.org.apache.felix.ipojo.online.manipulator.test.service.Hello;
+import org.apache.felix.ipojo.online.manipulator.test.impl.Consumer;
+import org.apache.felix.ipojo.online.manipulator.test.impl.MyProvider;
+import org.apache.felix.ipojo.online.manipulator.test.service.Hello;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
@@ -96,7 +96,7 @@ public class OnlineManipulatorTest {
                             newBundle()
                                 .add( Hello.class )
                                .set(Constants.BUNDLE_SYMBOLICNAME,"ServiceInterface")
-                               .set(Constants.EXPORT_PACKAGE, "org.apache.felix.org.apache.felix.ipojo.online.manipulator.test.service")
+                               .set(Constants.EXPORT_PACKAGE, "org.apache.felix.ipojo.online.manipulator.test.service")
                                .build()
                         ),
            systemProperty( "providerWithMetadata" ).value( providerWithMetadata ),
@@ -110,7 +110,7 @@ public class OnlineManipulatorTest {
                      public InputStream customizeTestProbe( InputStream testProbe )
                      {
                          return TinyBundles.modifyBundle(testProbe).set(Constants.IMPORT_PACKAGE,
-                        		 "org.apache.felix.org.apache.felix.ipojo.online.manipulator.test.service")
+                        		 "org.apache.felix.ipojo.online.manipulator.test.service")
                         		 .build();
                      }
 
@@ -155,8 +155,6 @@ public class OnlineManipulatorTest {
 
         assertBundle("Provider");
 
-        Assert.assertNotNull(context.getAllServiceReferences(Hello.class.getName(), null));
-
         helper.waitForService(Hello.class.getName(), null, 5000);
         assertValidity();
         Assert.assertNotNull(context.getServiceReference(Hello.class.getName()));
@@ -240,7 +238,7 @@ public class OnlineManipulatorTest {
         .add("metadata.xml", OnlineManipulatorTest.class.getClassLoader().getResource("provider.xml"))
         .add(MyProvider.class)
         .set(Constants.BUNDLE_SYMBOLICNAME,"Provider")
-        .set(Constants.IMPORT_PACKAGE, "org.apache.felix.org.apache.felix.ipojo.online.manipulator.test.service")
+        .set(Constants.IMPORT_PACKAGE, "org.apache.felix.ipojo.online.manipulator.test.service")
         .build();
 
         File out = getTemporaryFile("providerWithMetadata");
@@ -258,7 +256,7 @@ public class OnlineManipulatorTest {
         .add("META-INF/metadata.xml", OnlineManipulatorTest.class.getClassLoader().getResource("provider.xml"))
         .add(MyProvider.class)
         .set(Constants.BUNDLE_SYMBOLICNAME,"Provider")
-        .set(Constants.IMPORT_PACKAGE, "org.apache.felix.org.apache.felix.ipojo.online.manipulator.test.service")
+        .set(Constants.IMPORT_PACKAGE, "org.apache.felix.ipojo.online.manipulator.test.service")
         .build();
 
         File out = getTemporaryFile("providerWithMetadataInMetaInf");
@@ -276,7 +274,7 @@ public class OnlineManipulatorTest {
         //.addResource("metadata.xml", this.getClass().getClassLoader().getResource("provider.xml"))
         .add(MyProvider.class)
         .set(Constants.BUNDLE_SYMBOLICNAME,"Provider")
-        .set(Constants.IMPORT_PACKAGE, "org.apache.felix.org.apache.felix.ipojo.online.manipulator.test.service")
+        .set(Constants.IMPORT_PACKAGE, "org.apache.felix.ipojo.online.manipulator.test.service")
         .build();
 
     	File out = getTemporaryFile("providerWithoutMetadata");
@@ -297,7 +295,7 @@ public class OnlineManipulatorTest {
             .add("metadata.xml", OnlineManipulatorTest.class.getClassLoader().getResource("consumer.xml"))
             .add(Consumer.class)
             .set(Constants.BUNDLE_SYMBOLICNAME, "Consumer")
-            .set(Constants.IMPORT_PACKAGE, "org.apache.felix.org.apache.felix.ipojo.online.manipulator.test.service")
+            .set(Constants.IMPORT_PACKAGE, "org.apache.felix.ipojo.online.manipulator.test.service")
             .build();
 
         File out = getTemporaryFile("consumerWithMetadata");
@@ -315,7 +313,7 @@ public class OnlineManipulatorTest {
         InputStream is = newBundle()
         .add(Consumer.class)
         .set(Constants.BUNDLE_SYMBOLICNAME, "Consumer")
-        .set(Constants.IMPORT_PACKAGE, "org.apache.felix.org.apache.felix.ipojo.online.manipulator.test.service")
+        .set(Constants.IMPORT_PACKAGE, "org.apache.felix.ipojo.online.manipulator.test.service")
         .build();
 
         File out = getTemporaryFile("consumerWithoutMetadata");

Modified: felix/trunk/ipojo/tests/online-manipulator/src/test/java/org/apache/felix/ipojo/online/manipulator/test/impl/Consumer.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/tests/online-manipulator/src/test/java/org/apache/felix/ipojo/online/manipulator/test/impl/Consumer.java?rev=940905&r1=939352&r2=940905&view=diff
==============================================================================
--- felix/trunk/ipojo/tests/online-manipulator/src/test/java/org/apache/felix/ipojo/online/manipulator/test/impl/Consumer.java (original)
+++ felix/trunk/ipojo/tests/online-manipulator/src/test/java/org/apache/felix/ipojo/online/manipulator/test/impl/Consumer.java Tue May  4 15:22:36 2010
@@ -1,8 +1,8 @@
-package org.apache.felix.org.apache.felix.ipojo.online.manipulator.test.impl;
+package org.apache.felix.ipojo.online.manipulator.test.impl;
 
 import org.apache.felix.ipojo.annotations.Component;
 import org.apache.felix.ipojo.annotations.Requires;
-import org.apache.felix.org.apache.felix.ipojo.online.manipulator.test.service.Hello;
+import org.apache.felix.ipojo.online.manipulator.test.service.Hello;
 
 @Component
 public class Consumer {