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