now distinguishing between provided and required service and added
[utils] / system / general / src / main / java / org / wamblee / system / AbstractSubSystem.java
1 package org.wamblee.system;
2
3 import java.util.ArrayList;
4 import java.util.Arrays;
5 import java.util.Collection;
6 import java.util.HashMap;
7 import java.util.List;
8 import java.util.Map;
9
10 import org.apache.commons.logging.Log;
11 import org.apache.commons.logging.LogFactory;
12
13 /**
14  * Abstract subsystem class making it easy to implement new subsystems.
15  */
16 public abstract class AbstractSubSystem implements SubSystem {
17
18         private static final Log LOG = LogFactory.getLog(AbstractSubSystem.class);
19
20         private String _name;
21         private ServiceRegistry _registry; 
22         private List<ServiceDescriptor> _provided;
23         private List<ServiceDescriptor> _required;
24         private Map<ServiceDescriptor, Service> _running;
25         
26         /**
27          * Constructs the subsystem.
28          * 
29          * @param aRegistry
30          *            Registry of services.
31          * @param aName
32          *            Name of the system.
33          * @param aProvided
34          *            Provided services.
35          * @param aRequired
36          *            Required services.
37          */
38         protected AbstractSubSystem(String aName, ServiceRegistry aRegistry, ServiceDescriptor[] aProvided,
39                         ServiceDescriptor[] aRequired) {
40                 _name = aName;
41                 _registry = aRegistry; 
42                 _provided = new ArrayList<ServiceDescriptor>();
43                 _provided.addAll(Arrays.asList(aProvided));
44                 _required = new ArrayList<ServiceDescriptor>();
45                 _required.addAll(Arrays.asList(aRequired));
46                 _running = new HashMap<ServiceDescriptor, Service>();
47         }
48
49         @Override
50         public final String getName() {
51                 return _name;
52         }
53         
54         public ServiceRegistry getRegistry() {
55                 return _registry;
56         }
57
58         @Override
59         public final ProvidedServiceDescriptor[] getProvidedServices() {
60                 return _provided.toArray(new ProvidedServiceDescriptor[0]);
61         }
62
63         @Override
64         public final RequiredServiceDescriptor[] getRequiredServices() {
65                 return _required.toArray(new RequiredServiceDescriptor[0]);
66         }
67
68         @Override
69         public final Service[] start(String aContext,
70                         Service[] aRequiredServices) {
71                 LOG.info("Initializing '" + aContext + "." + _name + "' with "
72                                 + Arrays.asList(aRequiredServices));
73                 doStart(aContext + "." + getName(), aRequiredServices);
74                 return _running.values().toArray(new Service[0]);
75         }
76
77         /**
78          * Must be implemented for initializing the subsystem. The implementation
79          * must call {@link #addService(Service)} for each service that is started.
80          *  
81          * @param aRequiredServices
82          *            Services that are already running from other subsystems that
83          *            may be used.
84          */
85         protected abstract void doStart(String aContext,
86                         Service[] aRequiredServices);
87
88         /**
89          * Implementations must call this method to indicate that a new service has
90          * been started.
91          * 
92          * @param aService
93          *            Service.
94          */
95         protected final void addService(String aContext,
96                         ProvidedServiceDescriptor aDescriptor, Object aService) {
97                 LOG.info(aContext + ": service '" + aService + "' started.");
98                 Service svc = getRegistry().register(aDescriptor, aService);
99                 _running.put(svc.getDescriptor(), svc);
100         }
101
102         @Override
103         public Service[] getRunningServices() {
104                 return _running.values().toArray(new Service[0]);
105         }
106         
107         @Override
108         public void stop() {
109                 doStop();       
110                 for (Service svc: _running.values()) { 
111                         getRegistry().remove(svc);
112                 }
113         }
114         
115         protected abstract void doStop(); 
116
117         @Override
118         public String toString() {
119                 return _name;
120         }
121
122 }