some major refactoring.
authorErik Brakkee <erik@brakkee.org>
Fri, 4 Apr 2008 22:06:16 +0000 (22:06 +0000)
committerErik Brakkee <erik@brakkee.org>
Fri, 4 Apr 2008 22:06:16 +0000 (22:06 +0000)
ServiceREgistry eliminated as well as Service and DefaultService.
There is now a many-to-one relation from required to provided service
which leads to a more natural design.

18 files changed:
system/general/src/main/java/org/wamblee/system/AbstractComponent.java
system/general/src/main/java/org/wamblee/system/Component.java
system/general/src/main/java/org/wamblee/system/Container.java
system/general/src/main/java/org/wamblee/system/DefaultProvidedInterfaceDescriptor.java
system/general/src/main/java/org/wamblee/system/DefaultRequiredInterfaceDescriptor.java
system/general/src/main/java/org/wamblee/system/DefaultService.java [deleted file]
system/general/src/main/java/org/wamblee/system/DefaultServiceRegistry.java [deleted file]
system/general/src/main/java/org/wamblee/system/ProvidedInterface.java
system/general/src/main/java/org/wamblee/system/RequiredInterface.java
system/general/src/main/java/org/wamblee/system/Service.java [deleted file]
system/general/src/main/java/org/wamblee/system/ServiceRegistry.java [deleted file]
system/general/src/main/java/org/wamblee/system/SystemAssembler.java
system/general/src/test/java/org/wamblee/system/Application.java
system/general/src/test/java/org/wamblee/system/Environment.java
system/general/src/test/java/org/wamblee/system/SystemAssemblerTest.java
system/spring/src/main/java/org/wamblee/system/spring/RequiredServiceBean.java
system/spring/src/main/java/org/wamblee/system/spring/SpringComponent.java
system/spring/src/test/java/org/wamblee/system/spring/SpringComponentTest.java

index a78b46f1152720a10fd94b62da686a2a42776eb7..074e3ab0fe408a3e111f569b7a77d1df76bf0c23 100644 (file)
@@ -2,14 +2,12 @@ package org.wamblee.system;
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
+import java.util.Set;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.wamblee.system.Component.Status;
 
 /**
  * Abstract subsystem class making it easy to implement new subsystems.
@@ -19,17 +17,14 @@ public abstract class AbstractComponent implements Component {
        private static final Log LOG = LogFactory.getLog(AbstractComponent.class);
 
        private Status _status; 
-       private String _name;
-       private ServiceRegistry _registry; 
+       private String _name; 
        private List<ProvidedInterface> _provided;
        private List<RequiredInterface> _required;
-       private Map<ProvidedInterface, Service> _running;
+       private Set<ProvidedInterface> _running;
        
        /**
         * Constructs the subsystem.
-        * 
-        * @param aRegistry
-        *            Registry of services.
+        *
         * @param aName
         *            Name of the system.
         * @param aProvided
@@ -37,16 +32,15 @@ public abstract class AbstractComponent implements Component {
         * @param aRequired
         *            Required services.
         */
-       protected AbstractComponent(String aName, ServiceRegistry aRegistry, ProvidedInterface[] aProvided,
+       protected AbstractComponent(String aName, ProvidedInterface[] aProvided,
                        RequiredInterface[] aRequired) {
                _status = Status.NOT_STARTED;
                _name = aName;
-               _registry = aRegistry; 
                _provided = new ArrayList<ProvidedInterface>();
                _provided.addAll(Arrays.asList(aProvided));
                _required = new ArrayList<RequiredInterface>();
                _required.addAll(Arrays.asList(aRequired));
-               _running = new HashMap<ProvidedInterface, Service>();
+               _running = new HashSet<ProvidedInterface>();
        }
        
        @Override
@@ -58,10 +52,6 @@ public abstract class AbstractComponent implements Component {
        public final String getName() {
                return _name;
        }
-       
-       public ServiceRegistry getRegistry() {
-               return _registry;
-       }
 
        @Override
        public final ProvidedInterface[] getProvidedServices() {
@@ -74,25 +64,17 @@ public abstract class AbstractComponent implements Component {
        }
 
        @Override
-       public final Service[] start(String aContext,
-                       Service[] aRequiredServices) {
-               LOG.info("Initializing '" + aContext + "." + _name + "' with "
-                               + Arrays.asList(aRequiredServices));
-               doStart(aContext + "." + getName(), aRequiredServices);
+       public final void start(String aContext) {
+               LOG.info("Initializing '" + aContext + "." + _name + "'");
+               doStart(aContext + "." + getName());
                _status = Status.RUNNING;
-               return _running.values().toArray(new Service[0]);
        }
 
        /**
         * Must be implemented for initializing the subsystem. The implementation
         * must call {@link #addService(Service)} for each service that is started.
-        *  
-        * @param aRequiredServices
-        *            Services that are already running from other subsystems that
-        *            may be used.
         */
-       protected abstract void doStart(String aContext,
-                       Service[] aRequiredServices);
+       protected abstract void doStart(String aContext);
 
        /**
         * Implementations must call this method to indicate that a new service has
@@ -104,21 +86,18 @@ public abstract class AbstractComponent implements Component {
        protected final void addService(String aContext,
                        ProvidedInterface aDescriptor, Object aService) {
                LOG.info(aContext + ": service '" + aService + "' started.");
-               Service svc = getRegistry().register(aDescriptor, aService);
-               _running.put(svc.getDescriptor(), svc);
+               _running.add(aDescriptor);
+               aDescriptor.publish(aService);
        }
 
        @Override
-       public Service[] getRunningServices() {
-               return _running.values().toArray(new Service[0]);
+       public ProvidedInterface[] getRunningServices() {
+               return _running.toArray(new ProvidedInterface[0]);
        }
        
        @Override
        public void stop() {
                doStop();       
-               for (Service svc: _running.values()) { 
-                       getRegistry().remove(svc);
-               }
                _status = Status.STOPPED;
        }
        
index e72dd7f0b37978da6452701d0f32f282fe894ccd..4083c5bd6fc9e28f2e4b04e096e659d06b5d0d9b 100644 (file)
@@ -40,12 +40,9 @@ public interface Component {
        /**
         * Initialises the subsytem by starting all the services that
         * it described as provided. 
-        * @param aContext Unique name for the subsystem. 
-        * @param aRequiredServices Running services from other 
-        * subsystems that are required by this subsystem. 
-        * @return Services that are running in the subsystem. 
+        * @param aContext Unique name for the subsystem.  
         */
-       Service[] start(String aContext, Service[] aRequiredServices);
+       void start(String aContext);
        
        /**
         * Stops a subsystem. 
@@ -59,5 +56,5 @@ public interface Component {
         * {@link #initialize(String, Service[])} has been called. 
         * @return
         */
-       Service[] getRunningServices();
+       ProvidedInterface[] getRunningServices();
 }
index a23a7373aba0b9635ec9ad4e7c9b5d802d753281..d9dc29be471126bdfeba4f818c4b2e859e5d6ff4 100644 (file)
@@ -28,11 +28,11 @@ public class Container extends AbstractComponent {
         * @param aProvided Provided services of the system. 
         * @param aRequired Required services by the system. 
         */
-       public Container(String aName, ServiceRegistry aRegistry, Component[] aSystems,
+       public Container(String aName, Component[] aSystems,
                        ProvidedInterface[] aProvided, RequiredInterface[] aRequired) {
-               super(aName, aRegistry, aProvided, aRequired);
+               super(aName, aProvided, aRequired);
                _systems = aSystems;
-               validate();
+               validate(aRequired);
        }
 
        /**
@@ -41,7 +41,7 @@ public class Container extends AbstractComponent {
         * no services in the provided list that cannot be provided. 
         * Also logs a warning in case of superfluous requirements.  
         */
-       private void validate() {
+       private void validate(RequiredInterface[] aRequired) {
                List<ProvidedInterface> provided = new ArrayList<ProvidedInterface>();
                for (Component system : _systems) {
                        provided.addAll(Arrays.asList(system.getProvidedServices()));
@@ -69,12 +69,17 @@ public class Container extends AbstractComponent {
 
                List<RequiredInterface> reallyRequired = new ArrayList<RequiredInterface>(
                                required);
+               // Compute all required interfaces that are not provided
                for (ProvidedInterface service : provided) {
-                       reallyRequired.remove(service); 
-               }
-               for (RequiredInterface service: getRequiredServices()) { 
-                       reallyRequired.remove(service); 
+                       List<RequiredInterface> fulfilled = 
+                               Arrays.asList(SystemAssembler.filterRequiredServices(service, 
+                                       reallyRequired));
+                       reallyRequired.removeAll(fulfilled); 
                }
+               // Now the remaining interfaces should be covered by the required
+               // list. 
+               reallyRequired.removeAll(Arrays.asList(aRequired));
+               
                String missingRequired = "";
                for (RequiredInterface service: reallyRequired) {
                        missingRequired += service + "\n";
@@ -85,14 +90,23 @@ public class Container extends AbstractComponent {
        }
 
        @Override
-       protected void doStart(String aContext, Service[] aRequiredServices) {
-               List<ProvidedInterface> descriptors = new ArrayList<ProvidedInterface>();
-               for (Service service : aRequiredServices) {
-                       descriptors.add(service.getDescriptor());
+       protected void doStart(String aContext) {
+               List<ProvidedInterface> provided = new ArrayList<ProvidedInterface>();
+               
+               // all interfaces from the required list of this container are
+               // provided to the components inside it.
+               RequiredInterface[] required = getRequiredServices();
+               for (RequiredInterface intf: required) { 
+                   ProvidedInterface provider = intf.getProvider(); 
+                   if ( provider == null ) { 
+                       throw new SystemAssemblyException(aContext + ": required interface '" + intf +"' is not provided");
+                   }
+                       provided.add(intf.getProvider());
                }
-               SystemAssembler assembler = new SystemAssembler(aContext + "." + getName(), _systems,
-                               descriptors.toArray(new ProvidedInterface[0]));
-               assembler.start(getRegistry(), aRequiredServices);
+               
+               SystemAssembler assembler = new SystemAssembler( _systems, 
+                               provided.toArray(new ProvidedInterface[0]));
+               assembler.start();
        }
        
        @Override
index 2b51c60afc39cbfce5cb43d504714f1d4f2f82a3..3b38be7a199dbf6ce8b961e3cbd317d19225196a 100644 (file)
@@ -10,7 +10,8 @@ import java.util.Arrays;
 public class DefaultProvidedInterfaceDescriptor implements ProvidedInterface {
        
        private String _name; 
-       private Class[] _interfaces; 
+       private Class[] _interfaces;
+       private Object _implementation; 
        
        /**
         * Constructs the descriptor. 
@@ -36,6 +37,16 @@ public class DefaultProvidedInterfaceDescriptor implements ProvidedInterface {
                return _interfaces;
        }
        
+       @Override
+       public void publish(Object aImplementation) {
+               _implementation = aImplementation;      
+       }
+       
+       @Override
+       public Object getImplementation() {
+               return _implementation; 
+       }
+       
        @Override
        public boolean equals(Object obj) {
                if ( !(obj instanceof DefaultProvidedInterfaceDescriptor)) { 
index 9e434c08d49c276a6d599f84cfbd162aa5036d04..580b390b4402dbc7fb45b0972ed9bdeb8db248fe 100644 (file)
@@ -1,20 +1,31 @@
 package org.wamblee.system;
 
-public class DefaultRequiredInterfaceDescriptor extends DefaultProvidedInterfaceDescriptor
-               implements RequiredInterface {
+import java.util.Arrays;
 
+public class DefaultRequiredInterfaceDescriptor implements RequiredInterface {
+
+       private String _name;
+       private Class[] _required;
+       private ProvidedInterface _provider; 
+       
        public DefaultRequiredInterfaceDescriptor(String aName, Class aInterface) {
-               super(aName, aInterface);
+               this(aName, new Class[] { aInterface }); 
        }
 
        public DefaultRequiredInterfaceDescriptor(String aName, Class[] aInterfaces) {
-               super(aName, aInterfaces);
+               _name = aName; 
+               _required = aInterfaces; 
        }
 
+       @Override
+       public String getName() {
+               return _name;
+       }
+       
        @Override
        public boolean implementedBy(ProvidedInterface aDescriptor) {
                Class[] provided = aDescriptor.getInterfaceTypes();
-               for (Class required : getInterfaceTypes()) {
+               for (Class required : _required) {
                        if ( !serviceProvided(required, provided)) { 
                                return false; 
                        }
@@ -40,5 +51,53 @@ public class DefaultRequiredInterfaceDescriptor extends DefaultProvidedInterface
                }
                return false; 
        }
+       
+       @Override
+       public ProvidedInterface getProvider() {
+               return _provider; 
+       }
+       
+       @Override
+       public void setProvider(ProvidedInterface aProvider) {
+               _provider = aProvider;  
+       }
+
+       @Override
+       public <T> T getImplementation(Class<T> aClass) {
+               return (T)_provider.getImplementation();
+       }
+       
+       @Override
+       public boolean equals(Object obj) {
+               if ( !(obj instanceof DefaultRequiredInterfaceDescriptor)) { 
+                       return false; 
+               }
+               DefaultRequiredInterfaceDescriptor descr = (DefaultRequiredInterfaceDescriptor)obj;
+               if ( _required.length != descr._required.length ) { 
+                       return false; 
+               }
+               String[] interfaces1 = new String[_required.length];
+               String[] interfaces2 = new String[_required.length];
+               for (int i = 0; i < _required.length; i++) {  
+                       interfaces1[i] = _required[i].getName();
+                       interfaces2[i] = descr._required[i].getName();
+               }
+               Arrays.sort(interfaces1);
+               Arrays.sort(interfaces2);
+               return Arrays.equals(interfaces1, interfaces2);
+       }
 
+       @Override
+       public int hashCode() {
+               return _required.hashCode(); 
+       }
+       
+       @Override
+       public String toString() {
+               StringBuffer buf = new StringBuffer();
+               for (Class intf: _required) { 
+                       buf.append("." + intf.getName());
+               }
+               return buf.toString();
+       }
 }
diff --git a/system/general/src/main/java/org/wamblee/system/DefaultService.java b/system/general/src/main/java/org/wamblee/system/DefaultService.java
deleted file mode 100644 (file)
index a8a2692..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-package org.wamblee.system;
-
-/**
- * Default service implementation.
- *
- * @author Erik Brakkee
- */
-public class DefaultService implements Service {
-
-       private String _id;
-       private ProvidedInterface _descriptor;
-       private Object _service;
-
-       /**
-        * Constructs the service.
-        * 
-        * @param aDescriptor
-        *            Descriptor to use.
-        * @param aService
-        *            Service.
-        */
-       public DefaultService(String aId, ProvidedInterface aDescriptor,
-                       Object aService) {
-               _id = aId;
-               _descriptor = aDescriptor;
-               _service = aService;
-       }
-
-       @Override
-       public String getId() {
-               return _id;
-       }
-
-       @Override
-       public ProvidedInterface getDescriptor() {
-               return _descriptor;
-       }
-
-       @Override
-       public <T> T reference(Class<T> aClass) {
-               return (T) _service;
-       }
-
-       @Override
-       public String toString() {
-               return "(" + _descriptor + ", " + _service + ")";
-       }
-}
diff --git a/system/general/src/main/java/org/wamblee/system/DefaultServiceRegistry.java b/system/general/src/main/java/org/wamblee/system/DefaultServiceRegistry.java
deleted file mode 100644 (file)
index 27d576e..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-package org.wamblee.system;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
-
-public class DefaultServiceRegistry implements ServiceRegistry {
-
-       private int _count;
-       private Map<String, Service> _services;
-
-       public DefaultServiceRegistry() {
-               _count = 0;
-               _services = new HashMap<String, Service>();
-       }
-
-       @Override
-       public synchronized Service register(ProvidedInterface aDescriptor,
-                       Object aService) {
-               _count++;
-               String id = "" + _count;
-               Service svc = new DefaultService(id, aDescriptor, aService);
-               _services.put(id, svc);
-               return svc;
-       }
-       
-       @Override
-       public void remove(Service aService) {
-               Service svc = _services.remove(aService.getId());
-               if ( svc == null ) { 
-                       throw new IllegalArgumentException("Service '" + aService.getId() + "' does not exist");
-               }
-       }
-
-       @Override
-       public synchronized Service find(String aId) {
-               return _services.get(aId);
-       }
-
-       @Override
-       public Service[] listAllServices() {
-               return new ArrayList<Service>(_services.values())
-                               .toArray(new Service[0]);
-       }
-}
index 11b566460b068e3f8ed0d9aff597b85103458a02..20976d8a722c7e84060561dcecf4e5e7e98c3dbd 100644 (file)
@@ -20,4 +20,16 @@ public interface ProvidedInterface {
         * @return Service type. 
         */
        Class[] getInterfaceTypes();
+       
+       /**
+        * Publish an implementation of the interface. 
+        * @param aImplementation
+        */
+       void publish(Object aImplementation); 
+       
+       /**
+        * Gets the implementation. 
+        * @return Implementation or null if not started. 
+        */
+       Object getImplementation(); 
 }
index fd6074031e2b16f8374536a6bcd233889d312b36..f012df51b8cbe60c684f243458505998f3946229 100644 (file)
@@ -13,4 +13,24 @@ public interface RequiredInterface {
         * @return
         */
        boolean implementedBy(ProvidedInterface aInterface);
+       
+       /**
+        * Sets the provider of this interface. 
+        * @param aProvider Provider. 
+        */
+       void setProvider(ProvidedInterface aProvider);
+       
+       /**
+        * Getst the provider interface. 
+        * @return Provider or null if not set. 
+        */
+       ProvidedInterface getProvider(); 
+       
+       /**
+        * Gets the implementation of the required interface. 
+        * @param <T>
+        * @param aClass Interface type. 
+        * @return Interface implementation or null if not known yet. 
+        */
+       <T> T getImplementation(Class<T> aClass); 
 }
diff --git a/system/general/src/main/java/org/wamblee/system/Service.java b/system/general/src/main/java/org/wamblee/system/Service.java
deleted file mode 100644 (file)
index 8624c0c..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-package org.wamblee.system;
-
-/**
- * Represents a running service.
- *
- * @author Erik Brakkee
- */
-public interface Service {
-       
-       /**
-        * Gets the ide of the service in the registry. 
-        * @return Service id. 
-        */
-       String getId(); 
-       
-       /**
-        * Gets the descriptor of the service. 
-        * @return Descriptor. 
-        */
-       ProvidedInterface getDescriptor(); 
-       
-       /**
-        * Returns a reference to the running service. 
-        * @return Service. 
-        */
-       <T> T reference(Class<T> aClass);
-}
diff --git a/system/general/src/main/java/org/wamblee/system/ServiceRegistry.java b/system/general/src/main/java/org/wamblee/system/ServiceRegistry.java
deleted file mode 100644 (file)
index 7fe3506..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-package org.wamblee.system;
-
-public interface ServiceRegistry {
-
-       Service register(ProvidedInterface aDescriptor, Object aService);
-       
-       void remove(Service aService); 
-       
-       Service find(String aId); 
-       
-       Service[] listAllServices(); 
-}
index 5cdb3890cc5a3b810345f0dc114b424d143af7e6..50e0e3ab41ecf925524dc7019dd2ddb3771c3975 100644 (file)
@@ -4,8 +4,10 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -23,6 +25,7 @@ public class SystemAssembler {
        private static final String ROOT_CONTEXT_NAME = "root";
        private String _context;
        private Component[] _systems;
+       private ProvidedInterface[] _required; 
 
        public static RequiredInterface[] filterRequiredServices(
                        ProvidedInterface aProvided,
@@ -77,18 +80,19 @@ public class SystemAssembler {
                        ProvidedInterface[] aAvailableServices) {
                _context = aContext;
                _systems = aSystems;
-               validate(aAvailableServices);
+               _required = aAvailableServices; 
+               validate();
        }
 
        /**
         * Determines if the systems are ordered appropriately so that all
         * dependencies are met.
         */
-       private void validate(ProvidedInterface[] aDescriptors)
+       private void validate()
                        throws SystemAssemblyException {
 
                List<ProvidedInterface> allProvided = new ArrayList<ProvidedInterface>();
-               for (ProvidedInterface descriptor : aDescriptors) {
+               for (ProvidedInterface descriptor : _required) {
                        allProvided.add(descriptor);
                }
                for (Component system : _systems) {
@@ -128,39 +132,36 @@ public class SystemAssembler {
        /**
         * Starts the subsystems.
         * 
-        * @param aRegistry
-        *            Service registry to which created services must be registered.
         * @param aRequiredServices
         *            Services that are available from other systems that have been
         *            started before.
         */
-       public void start(ServiceRegistry aRegistry, Service[] aRequiredServices) {
+       public void start() {
                LOG.info("Starting '" + _context + "'");
-               Map<ProvidedInterface, Service> allProvided = new HashMap<ProvidedInterface, Service>();
-
-               for (Service service : aRequiredServices) {
-                       allProvided.put(service.getDescriptor(), service);
-               }
+               Set<ProvidedInterface> allProvided = new HashSet<ProvidedInterface>();
+               allProvided.addAll(Arrays.asList(_required));
+               
                for (Component system : _systems) {
                        
                        // Compose a list of the required services required for the subsystem.
                        
                        RequiredInterface[] descriptors = system
                                        .getRequiredServices();
-                       List<Service> services = new ArrayList<Service>();
-                       for (RequiredInterface descriptor : descriptors) {
+                       List<ProvidedInterface> services = new ArrayList<ProvidedInterface>();
+                       for (RequiredInterface required : descriptors) {
                                ProvidedInterface[] provided = filterProvidedServices(
-                                               descriptor, allProvided.keySet());
-                               services.add(allProvided.get(provided[0]));
+                                               required, allProvided);
+                               assert provided.length == 1;    
+                               services.add(provided[0]);
+                               required.setProvider(provided[0]);
                        }
                        
                        // Start the service. 
-                       Service[] provided = system.start(_context, services
-                                       .toArray(new Service[0]));
+                       system.start(_context);
                        
-                       // Add started services to the map of started services.
-                       for (Service service : provided) {
-                               allProvided.put(service.getDescriptor(), service);
+                       // Add started services to the set of started services.
+                       for (ProvidedInterface service : system.getProvidedServices()) {
+                               allProvided.add(service);
                        }
 
                }
index 3825c98962614eaae400c3c68ea1db230b981638..b84ca5e247410ea6d0ec7c690edc539b87683c9b 100644 (file)
@@ -3,18 +3,20 @@ package org.wamblee.system;
 import javax.sql.DataSource;
 
 public class Application extends AbstractComponent {
-       private static final RequiredInterface[] REQUIRED = 
+       private static RequiredInterface[] required() {
+               return
                new RequiredInterface[] { 
                        new DefaultRequiredInterfaceDescriptor("datasource", DataSource.class), 
                        new DefaultRequiredInterfaceDescriptor("integer", Integer.class)
        };
+       }
        
-       public Application(ServiceRegistry aRegistry) {
-               super("application", aRegistry, new ProvidedInterface[0], REQUIRED); 
+       public Application() {
+               super("application", new ProvidedInterface[0], required()); 
        }
 
        @Override
-       protected void doStart(String aContext, Service[] aRequiredServices) {
+       protected void doStart(String aContext) {
                // Empty, no services provided externally. 
        }
        
index e2bd2b8053731fc0b603d1e297a9116f69fa9b61..27537e0a850b9b297dd9058b3f5ca30e519ac3a1 100644 (file)
@@ -5,20 +5,21 @@ import javax.sql.DataSource;
 
 public class Environment extends AbstractComponent {
        
-       private static final ProvidedInterface[] PROVIDED = 
-               new ProvidedInterface[] { 
+       private static final ProvidedInterface[] provided() { 
+               return new ProvidedInterface[] { 
                        new DefaultProvidedInterfaceDescriptor("datasource", DataSource.class), 
                        new DefaultProvidedInterfaceDescriptor("integer", Integer.class)
        };
+       }
        
-       public Environment(ServiceRegistry aRegistry) { 
-               super("environment", aRegistry, PROVIDED, new RequiredInterface[0]);
+       public Environment() { 
+               super("environment", provided(), new RequiredInterface[0]);
        }
        
        @Override
-       protected void doStart(String aContext, Service[] aRequiredServices) {
-           addService(aContext, PROVIDED[0], new Integer(1));
-           addService(aContext, PROVIDED[1], new Integer(2));
+       protected void doStart(String aContext) {
+           addService(aContext, getProvidedServices()[0], new Integer(1));
+           addService(aContext, getProvidedServices()[1], new Integer(2));
        }
        
        @Override
index c372bf045b13c236f7923c25f6afd4525ee02dae..9412caee08a58029eb5fb9d825ab56099e6f6051 100644 (file)
@@ -11,12 +11,9 @@ import junit.framework.TestCase;
 
 public class SystemAssemblerTest extends TestCase {
 
-       private ServiceRegistry _registry;
-
        @Override
        protected void setUp() throws Exception {
                super.setUp();
-               _registry = new DefaultServiceRegistry();
        }
 
        private static class MyMultiple implements Serializable, Runnable {
@@ -27,10 +24,10 @@ public class SystemAssemblerTest extends TestCase {
        }
 
        public void testFilterProvided() {
-               RequiredInterface req1 = new DefaultRequiredInterfaceDescriptor(
-                               "name", Runnable.class);
-               RequiredInterface req2 = new DefaultRequiredInterfaceDescriptor(
-                               "name", Serializable.class);
+               RequiredInterface req1 = new DefaultRequiredInterfaceDescriptor("name",
+                               Runnable.class);
+               RequiredInterface req2 = new DefaultRequiredInterfaceDescriptor("name",
+                               Serializable.class);
                ProvidedInterface prov1 = new DefaultProvidedInterfaceDescriptor(
                                "name", Runnable.class);
                ProvidedInterface prov2 = new DefaultProvidedInterfaceDescriptor(
@@ -42,54 +39,46 @@ public class SystemAssemblerTest extends TestCase {
                                SystemAssembler.filterRequiredServices(prov1, Arrays
                                                .asList(new RequiredInterface[] { req1 })));
                AssertionUtils.assertEquals(new RequiredInterface[] { req1 },
-                               SystemAssembler.filterRequiredServices(prov1,
-                                               Arrays.asList(new RequiredInterface[] { req1,
-                                                               req2 })));
-               AssertionUtils.assertEquals(new RequiredInterface[] { req1,
-                               req2 }, SystemAssembler.filterRequiredServices(prov3, Arrays
-                               .asList(new RequiredInterface[] { req1, req2 })));
-
-               AssertionUtils.assertEquals(
-                               new ProvidedInterface[] { prov1 },
+                               SystemAssembler.filterRequiredServices(prov1, Arrays
+                                               .asList(new RequiredInterface[] { req1, req2 })));
+               AssertionUtils.assertEquals(new RequiredInterface[] { req1, req2 },
+                               SystemAssembler.filterRequiredServices(prov3, Arrays
+                                               .asList(new RequiredInterface[] { req1, req2 })));
+
+               AssertionUtils.assertEquals(new ProvidedInterface[] { prov1 },
                                SystemAssembler.filterProvidedServices(req1, Arrays
                                                .asList(new ProvidedInterface[] { prov1 })));
-               AssertionUtils.assertEquals(
-                               new ProvidedInterface[] { prov1 }, SystemAssembler
-                                               .filterProvidedServices(req1, Arrays
-                                                               .asList(new ProvidedInterface[] {
-                                                                               prov1, prov2 })));
-               AssertionUtils.assertEquals(new ProvidedInterface[] { prov1,
-                               prov3 }, SystemAssembler.filterProvidedServices(req1, Arrays
-                               .asList(new ProvidedInterface[] { prov1, prov3 })));
+               AssertionUtils.assertEquals(new ProvidedInterface[] { prov1 },
+                               SystemAssembler.filterProvidedServices(req1, Arrays
+                                               .asList(new ProvidedInterface[] { prov1, prov2 })));
+               AssertionUtils.assertEquals(new ProvidedInterface[] { prov1, prov3 },
+                               SystemAssembler.filterProvidedServices(req1, Arrays
+                                               .asList(new ProvidedInterface[] { prov1, prov3 })));
        }
 
        public void testEnvironmentApplication() {
-               Component environment = new Environment(_registry);
-               Component application = new Application(_registry);
+               Component environment = new Environment();
+               Component application = new Application();
                SystemAssembler assembler = new SystemAssembler(new Component[] {
                                environment, application }, new ProvidedInterface[0]);
-               assembler.start(_registry, new Service[0]);
-               Service[] envServices = environment.getRunningServices();
+               assembler.start();
+               ProvidedInterface[] envServices = environment.getRunningServices();
                assertEquals(2, envServices.length);
-               Service[] appServices = environment.getRunningServices();
+               ProvidedInterface[] appServices = environment.getRunningServices();
                assertEquals(2, appServices.length);
-               assertEquals(2, _registry.listAllServices().length);
 
+               // TODO test stopping!!!!!!
                environment.stop();
-               assertEquals(0, _registry.listAllServices().length);
-
                application.stop();
-               assertEquals(0, _registry.listAllServices().length);
        }
 
        public void testApplicationEnvironment() {
                try {
-                       Component environment = new Environment(_registry);
-                       Component application = new Application(_registry);
+                       Component environment = new Environment();
+                       Component application = new Application();
                        SystemAssembler assembler = new SystemAssembler(new Component[] {
-                                       application, environment },
-                                       new ProvidedInterface[0]);
-                       assembler.start(_registry, new Service[0]);
+                                       application, environment }, new ProvidedInterface[0]);
+                       assembler.start();
                } catch (SystemAssemblyException e) {
                        // e.printStackTrace();
                        return;
@@ -98,15 +87,15 @@ public class SystemAssemblerTest extends TestCase {
        }
 
        public void testComposite() {
-               Component environment = new Environment(_registry);
-               Component application = new Application(_registry);
+               Component environment = new Environment();
+               Component application = new Application();
                assertEquals(Status.NOT_STARTED, environment.getStatus());
                assertEquals(Status.NOT_STARTED, application.getStatus());
-               Container system = new Container("all", _registry, new Component[] {
-                               environment, application }, new ProvidedInterface[0],
+               Container system = new Container("all", new Component[] { environment,
+                               application }, new ProvidedInterface[0],
                                new RequiredInterface[0]);
                assertEquals(Status.NOT_STARTED, system.getStatus());
-               system.start("root", new Service[0]);
+               system.start("root");
                RequiredInterface[] required = system.getRequiredServices();
                assertEquals(0, required.length);
                ProvidedInterface[] provided = system.getProvidedServices();
@@ -123,11 +112,10 @@ public class SystemAssemblerTest extends TestCase {
 
        public void testCompositeWithWrongProvidedInfo() {
                try {
-                       Component environment = new Environment(_registry);
-                       Component application = new Application(_registry);
+                       Component environment = new Environment();
+                       Component application = new Application();
                        Container system = new Container(
                                        "all",
-                                       _registry,
                                        new Component[] { environment, application },
                                        new ProvidedInterface[] { new DefaultProvidedInterfaceDescriptor(
                                                        "string", String.class) },
@@ -138,17 +126,35 @@ public class SystemAssemblerTest extends TestCase {
                fail();
        }
 
+       public void testCompositeRequiredInterfaceNotProvided() {
+               try {
+                       Component environment = new Environment();
+                       Component application = new Application();
+                       Container system = new Container(
+                                       "all",
+                                       new Component[] { environment, application },
+                                       new ProvidedInterface[0],
+                                       new RequiredInterface[] { new DefaultRequiredInterfaceDescriptor(
+                                                       "string", String.class) });
+                       system.start("root");
+               } catch (SystemAssemblyException e) {
+                       return;
+               }
+               fail();
+       }
+
        public void testCompositeWithSuperfluousRequiredInfo() {
-               Component environment = new Environment(_registry);
-               Component application = new Application(_registry);
+               Component environment = new Environment();
+               Component application = new Application();
                Container system = new Container(
                                "all",
-                               _registry,
                                new Component[] { environment, application },
                                new ProvidedInterface[0],
                                new RequiredInterface[] { new DefaultRequiredInterfaceDescriptor(
                                                "string", String.class) });
-               system.start("root", new Service[0]);
+               system.getRequiredServices()[0].setProvider(
+                               new DefaultProvidedInterfaceDescriptor("hallo", String.class));
+               system.start("root");
                RequiredInterface[] required = system.getRequiredServices();
                assertEquals(1, required.length);
                ProvidedInterface[] provided = system.getProvidedServices();
@@ -157,13 +163,12 @@ public class SystemAssemblerTest extends TestCase {
 
        public void testCompositeWithExternalDependencesNotProvided() {
                try {
-                       Component environment = new Environment(_registry);
-                       Component application = new Application(_registry);
-                       Container system = new Container("all", _registry,
-                                       new Component[] { application },
-                                       new ProvidedInterface[0], application
-                                                       .getRequiredServices());
-                       system.start("root", new Service[0]);
+                       Component environment = new Environment();
+                       Component application = new Application();
+                       Container system = new Container("all",
+                                       new Component[] { application }, new ProvidedInterface[0],
+                                       application.getRequiredServices());
+                       system.start("root");
                } catch (SystemAssemblyException e) {
                        return;
                }
@@ -173,14 +178,16 @@ public class SystemAssemblerTest extends TestCase {
 
        public void testCompositeWithExternalDependencesProvided() {
 
-               Component environment = new Environment(_registry);
-               Component application = new Application(_registry);
-               Container system = new Container("all", _registry,
-                               new Component[] { application },
-                               new ProvidedInterface[0], application
-                                               .getRequiredServices());
-               Service[] envServices = environment.start("env", new Service[0]);
-               system.start("root", envServices);
+               Component environment = new Environment();
+               Component application = new Application();
+               Container system = new Container("all",
+                               new Component[] { application }, new ProvidedInterface[0],
+                               application.getRequiredServices());
+               environment.start("env");
+               system.getRequiredServices()[0].setProvider(environment.getProvidedServices()[0]);
+               system.getRequiredServices()[1].setProvider(environment.getProvidedServices()[1]);
+               
+               system.start("root");
                RequiredInterface[] required = system.getRequiredServices();
                assertEquals(2, required.length);
                ProvidedInterface[] provided = system.getProvidedServices();
@@ -190,13 +197,13 @@ public class SystemAssemblerTest extends TestCase {
 
        public void testAmbiguousInterfaces() {
                try {
-                       Component environment1 = new Environment(_registry);
-                       Component environment2 = new Environment(_registry);
-                       Component application = new Application(_registry);
+                       Component environment1 = new Environment();
+                       Component environment2 = new Environment();
+                       Component application = new Application();
                        SystemAssembler assembler = new SystemAssembler(new Component[] {
                                        environment1, environment2, application },
                                        new ProvidedInterface[0]);
-                       assembler.start(_registry, new Service[0]);
+                       assembler.start();
 
                } catch (SystemAssemblyException e) {
                        return;
@@ -206,12 +213,11 @@ public class SystemAssemblerTest extends TestCase {
 
        public void testIncompleteRequirements() {
                try {
-                       Component application = new Application(_registry);
-                       Container system = new Container("all", _registry,
-                                       new Component[] { application },
-                                       new ProvidedInterface[0],
+                       Component application = new Application();
+                       Container system = new Container("all",
+                                       new Component[] { application }, new ProvidedInterface[0],
                                        new RequiredInterface[0]);
-                       system.start("root", new Service[0]);
+                       system.start("root");
                } catch (SystemAssemblyException e) {
                        return;
                }
index eaf55336c185f74afc0d72de41a0da54cc3afdfb..50e7e967998ef4e3b098b9516cad92b3980ab593 100644 (file)
@@ -1,6 +1,9 @@
 package org.wamblee.system.spring;
 
 import org.springframework.beans.factory.FactoryBean;
+import org.wamblee.system.ProvidedInterface;
+import org.wamblee.system.RequiredInterface;
+import org.wamblee.system.SystemAssemblyException;
 
 /**
  * Bean which adds a service required by the spring component to 
@@ -10,19 +13,26 @@ import org.springframework.beans.factory.FactoryBean;
  */
 class RequiredServiceBean implements FactoryBean {
        
-       private String _id;
+       private RequiredInterface _required; 
        
        /**
         * Constructs the bean. 
         * @param aId Id of the bean in the service registry.  
         */
        public RequiredServiceBean(String aId) { 
-               _id = aId; 
+               RequiredInterface[] required = SpringComponent.THIS.get().getRequiredServices();
+               for ( RequiredInterface intf: required) { 
+                       if ( intf.getName().equals(aId)) { 
+                               _required = intf; 
+                               return;
+                       }
+               }
+               throw new SystemAssemblyException("Cannot resolve provided component '" + aId + "'");
        }
 
        @Override
        public Object getObject() throws Exception {
-               return SpringComponent.REGISTRY.get().find(_id).reference(Object.class);
+               return _required.getImplementation(Object.class);
        }
 
        @Override
index b9a2648c7ca706838795538637e0c0d584aa3271..0b0921e6dcd6abbb410ee56effb32e6c4f916b03 100644 (file)
@@ -14,25 +14,20 @@ import org.wamblee.system.AbstractComponent;
 import org.wamblee.system.ProvidedInterface;
 import org.wamblee.system.RequiredInterface;
 import org.wamblee.system.Service;
-import org.wamblee.system.ServiceRegistry;
 import org.wamblee.system.SystemAssembler;
 import org.wamblee.system.SystemAssemblyException;
 
 /**
- * Represents a system configured based on spring.
- * The spring config files that are configured should not contain any PropertyPlaceholderConfigurer 
- * objects. 
- *
+ * Represents a system configured based on spring. The spring config files that
+ * are configured should not contain any PropertyPlaceholderConfigurer objects.
+ * 
  * @author Erik Brakkee
  */
 public class SpringComponent extends AbstractComponent {
 
-       /**
-        * Singleton access to the service registry. Required while starting up.
-        */
-       static ThreadLocal<ServiceRegistry> REGISTRY = new ThreadLocal<ServiceRegistry>();
+       static final ThreadLocal<SpringComponent> THIS = new ThreadLocal<SpringComponent>();
 
-       private Properties _properties; 
+       private Properties _properties;
        private String[] _configFiles;
        private Map<String, ProvidedInterface> _provided;
        private Map<RequiredInterface, String> _required;
@@ -62,57 +57,59 @@ public class SpringComponent extends AbstractComponent {
         *            names that the spring config files use for each required
         *            service.
         */
-       public SpringComponent(String aName, ServiceRegistry aRegistry, String[] aConfigFiles,
+       public SpringComponent(String aName, String[] aConfigFiles,
                        Map<String, ProvidedInterface> aProvided,
                        Map<RequiredInterface, String> aRequired) {
-               super(aName, aRegistry, aProvided.values().toArray(new ProvidedInterface[0]),
+               super(aName, aProvided.values().toArray(new ProvidedInterface[0]),
                                aRequired.keySet().toArray(new RequiredInterface[0]));
-               _properties = new Properties(); 
+               _properties = new Properties();
                _configFiles = aConfigFiles;
                _provided = aProvided;
                _required = aRequired;
        }
-       
+
        /**
-        * Must be called to make a property available in the application context. 
-        * @param aKey Property key. 
-        * @param aValue Property value. 
+        * Must be called to make a property available in the application context.
+        * 
+        * @param aKey
+        *            Property key.
+        * @param aValue
+        *            Property value.
         */
-       public void setProperty(String aKey, String aValue) { 
+       public void setProperty(String aKey, String aValue) {
                _properties.put(aKey, aValue);
        }
-       
-       public void addProperties(Properties aProperties) { 
-               for (Object key: aProperties.keySet()) { 
-                       setProperty((String)key, aProperties.getProperty((String)key));
+
+       public void addProperties(Properties aProperties) {
+               for (Object key : aProperties.keySet()) {
+                       setProperty((String) key, aProperties.getProperty((String) key));
                }
        }
 
        @Override
-       protected void doStart(String aContext, 
-                       Service[] aRequiredServices) {
-               ServiceRegistry oldRegistry = REGISTRY.get();
-               try {   
-                       REGISTRY.set(getRegistry());
-                       try {
-                               _parentContext = new GenericApplicationContext();
-
-                               registerRequiredServices(aRequiredServices);
-                               
-                               _parentContext.refresh();
-
-                               parseConfigFiles();
-                               
-                               _context.addBeanFactoryPostProcessor(new PropertySetter(_properties));
-                               _context.refresh(); 
-
-                               exposeProvidedServices(aContext);
-                       } catch (Exception e) {
-                               throw new SystemAssemblyException(
-                                               "Failed to assemble spring system", e);
-                       }
+       protected void doStart(String aContext) {
+
+               SpringComponent old = THIS.get();
+               THIS.set(this);
+               try {
+                       _parentContext = new GenericApplicationContext();
+
+                       registerRequiredServices();
+
+                       _parentContext.refresh();
+
+                       parseConfigFiles();
+
+                       _context
+                                       .addBeanFactoryPostProcessor(new PropertySetter(_properties));
+                       _context.refresh();
+
+                       exposeProvidedServices(aContext);
+               } catch (Exception e) {
+                       throw new SystemAssemblyException(
+                                       "Failed to assemble spring system", e);
                } finally {
-                       REGISTRY.set(oldRegistry);
+                       THIS.set(old);
                }
        }
 
@@ -136,27 +133,21 @@ public class SpringComponent extends AbstractComponent {
                                _parentContext);
        }
 
-       private void registerRequiredServices(Service[] aRequiredServices) {
+       private void registerRequiredServices() {
                // Register required services in a parent context
-
-               for (Service svc: aRequiredServices) { 
-                       String id = svc.getId();
-                       ProvidedInterface descriptor = svc.getDescriptor();
-                       RequiredInterface[] requiredServices = SystemAssembler.filterRequiredServices(descriptor,
-                                       _required.keySet()); 
-                       for (RequiredInterface required: requiredServices) { 
-                               String beanName = _required.get(required);
-                               ConstructorArgumentValues cargs = new ConstructorArgumentValues();
-                               cargs.addGenericArgumentValue(id); 
-                               BeanDefinition definition = new RootBeanDefinition(RequiredServiceBean.class, cargs,
-                                               new MutablePropertyValues());
-                               _parentContext.registerBeanDefinition(beanName, definition);
-                       }
+               for (RequiredInterface required: getRequiredServices()) { 
+                       String beanName = _required.get(required);
+                       ConstructorArgumentValues cargs = new ConstructorArgumentValues();
+                       cargs.addGenericArgumentValue(required.getName());
+                       BeanDefinition definition = new RootBeanDefinition(
+                                       RequiredServiceBean.class, cargs,
+                                       new MutablePropertyValues());
+                       _parentContext.registerBeanDefinition(beanName, definition);
                }
        }
 
        @Override
        protected void doStop() {
-           _context.close();
+               _context.close();
        }
 }
index b0f7f8abd82734244288475825599f7c98523a90..0b4ffb08a9f83eb497f3cf4a73ded1bcb4de1906 100644 (file)
@@ -10,11 +10,10 @@ import junit.framework.TestCase;
 import org.wamblee.io.ClassPathResource;
 import org.wamblee.system.DefaultProvidedInterfaceDescriptor;
 import org.wamblee.system.DefaultRequiredInterfaceDescriptor;
-import org.wamblee.system.DefaultServiceRegistry;
+import org.wamblee.system.DefaultService;
 import org.wamblee.system.ProvidedInterface;
 import org.wamblee.system.RequiredInterface;
 import org.wamblee.system.Service;
-import org.wamblee.system.ServiceRegistry;
 import org.wamblee.system.SystemAssemblyException;
 
 public class SpringComponentTest extends TestCase {
@@ -24,21 +23,18 @@ public class SpringComponentTest extends TestCase {
        private static final String HELLO_SERVICE_SPRING_WITH_PROPERTIES_XML = "test.org.wamblee.system.springWithProperties.xml";
     private static final String PROPERTY_FILE = "test.org.wamblee.system.spring.properties";
 
-       private ServiceRegistry _registry;
-
        @Override
        protected void setUp() throws Exception {
                super.setUp();
-               _registry = new DefaultServiceRegistry();
        }
 
        public void testBlackboxSystem() {
-               SpringComponent system = new SpringComponent("system", _registry,
+               SpringComponent system = new SpringComponent("system",
                                new String[] { HELLO_SERVICE_SPRING_XML },
                                new HashMap<String, ProvidedInterface>(),
                                new HashMap<RequiredInterface, String>());
-               system.start("Hello", new Service[0]);
-               Service[] services = system.getRunningServices();
+               system.start("Hello");
+               ProvidedInterface[] services = system.getRunningServices();
                assertEquals(0, services.length);
                
                system.stop();
@@ -49,14 +45,14 @@ public class SpringComponentTest extends TestCase {
                provided.put("helloService", new DefaultProvidedInterfaceDescriptor(
                                "hello", HelloService.class));
 
-               SpringComponent system = new SpringComponent("system", _registry,
+               SpringComponent system = new SpringComponent("system", 
                                new String[] { HELLO_SERVICE_SPRING_XML }, provided,
                                new HashMap<RequiredInterface, String>());
-               system.start("Hello", new Service[0]);
-               Service[] services = system.getRunningServices();
+               system.start("Hello");
+               ProvidedInterface[] services = system.getRunningServices();
                assertEquals(1, services.length);
-               assertTrue(services[0].reference(HelloService.class) instanceof HelloService);
-               assertEquals("Hello world!", services[0].reference(HelloService.class)
+               assertTrue(services[0].getImplementation() instanceof HelloService);
+               assertEquals("Hello world!", ((HelloService)services[0].getImplementation())
                                .say());
                system.stop();
        }
@@ -65,7 +61,7 @@ public class SpringComponentTest extends TestCase {
                Map<String, ProvidedInterface> provided = new HashMap<String, ProvidedInterface>();
                provided.put("helloService", new DefaultProvidedInterfaceDescriptor(
                                "hello", HelloService.class));
-               SpringComponent system = new SpringComponent("system", _registry,
+               SpringComponent system = new SpringComponent("system", 
                                new String[] { HELLO_SERVICE_SPRING_WITH_PROPERTIES_XML },
                                provided,
                                new HashMap<RequiredInterface, String>());
@@ -73,18 +69,19 @@ public class SpringComponentTest extends TestCase {
                props.load(new ClassPathResource(PROPERTY_FILE).getInputStream());
                system.addProperties(props);
                
-               system.start("Hello", new Service[0]);
-               Service[] services = system.getRunningServices();
-               assertEquals("Property Value", services[0].reference(HelloService.class).say());
+               system.start("Hello");
+               ProvidedInterface[] services = system.getRunningServices();
+               assertEquals("Property Value", 
+                               ((HelloService)services[0].getImplementation()).say());
        }
 
        public void testWithMissingRequirement() {
                try {
-                       SpringComponent system = new SpringComponent("system", _registry,
+                       SpringComponent system = new SpringComponent("system",
                                        new String[] { HELLO_SERVICE_SPRING_WITH_REQS_XML },
                                        new HashMap<String, ProvidedInterface>(),
                                        new HashMap<RequiredInterface, String>());
-                       system.start("Bla", new Service[0]);
+                       system.start("Bla");
                } catch (SystemAssemblyException e) {
                        //e.printStackTrace();
                        return;
@@ -96,13 +93,16 @@ public class SpringComponentTest extends TestCase {
                Map<RequiredInterface, String> required = new HashMap<RequiredInterface, String>();
                required.put(new DefaultRequiredInterfaceDescriptor("hello", HelloService.class),
                                "helloService");
-               SpringComponent system = new SpringComponent("system", _registry,
+               SpringComponent system = new SpringComponent("system",
                                new String[] { HELLO_SERVICE_SPRING_WITH_REQS_XML },
                                new HashMap<String, ProvidedInterface>(), required);
                
                HelloService helloObject = new HelloService("ladida"); 
-               Service helloService = _registry.register(new DefaultProvidedInterfaceDescriptor("hello", HelloService.class), helloObject);
-               system.start("Bla", new Service[] { helloService } );
+               ProvidedInterface helloService = new DefaultProvidedInterfaceDescriptor("hello", HelloService.class);
+               helloService.publish(helloObject);
+               system.getRequiredServices()[0].setProvider(helloService);
+               
+               system.start("Bla");
                system.stop();
        }
        
@@ -114,18 +114,22 @@ public class SpringComponentTest extends TestCase {
                provided.put("blaService", new DefaultProvidedInterfaceDescriptor("bla",
                                BlaService.class));
 
-               SpringComponent system = new SpringComponent("system", _registry,
+               SpringComponent system = new SpringComponent("system",
                                new String[] { HELLO_SERVICE_SPRING_WITH_REQS_XML },
                                provided, required);
                
                HelloService helloObject = new HelloService("ladida"); 
-               Service helloService = _registry.register(new DefaultProvidedInterfaceDescriptor("hello", HelloService.class), helloObject);
-               Service[] services = system.start("Bla", new Service[] { helloService } );
-               assertEquals(1, services.length);
+               ProvidedInterface helloService = 
+                       new DefaultProvidedInterfaceDescriptor("hello", HelloService.class);
+               helloService.publish(helloObject);
+               system.getRequiredServices()[0].setProvider(helloService);
+               system.start("Bla");
+               ProvidedInterface started = system.getProvidedServices()[0];
                
-               assertTrue(services[0].reference(BlaService.class) instanceof BlaService);
-               assertEquals("ladida", services[0].reference(BlaService.class)
-                               .execute());
+           assertNotNull(started.getImplementation());
+           assertTrue(started.getImplementation() instanceof BlaService);
+               assertEquals("ladida", 
+                               ((BlaService)started.getImplementation()).execute());
                system.stop();
        }