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