KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > portal > server > kernel > Kernel


1 /*****************************************
2  * *
3  * JBoss Portal: The OpenSource Portal *
4  * *
5  * Distributable under LGPL license. *
6  * See terms of license at gnu.org. *
7  * *
8  *****************************************/

9 package org.jboss.portal.server.kernel;
10
11 import java.util.Arrays JavaDoc;
12 import java.util.Collections JavaDoc;
13 import java.util.HashMap JavaDoc;
14 import java.util.HashSet JavaDoc;
15 import java.util.Iterator JavaDoc;
16 import java.util.Map JavaDoc;
17 import java.util.Set JavaDoc;
18
19 import org.apache.log4j.Logger;
20 import org.jboss.portal.server.kernel.state.State;
21
22 /**
23  * The kernel.
24  *
25  * @author <a HREF="mailto:julien@jboss.org">Julien Viet</a>
26  * @version $Revision: 1.3 $
27  */

28 public class Kernel
29 {
30
31    // ServiceID to Entry
32
private final Map JavaDoc registry;
33
34    // Event listeners
35
private Set JavaDoc listeners;
36
37    // Create
38
private final LifeCycleMethod createMethod;
39
40    // Start
41
private final LifeCycleMethod startMethod;
42
43    // Stop
44
private final LifeCycleMethod stopMethod;
45
46    // Destroy
47
private final LifeCycleMethod destroyMethod;
48
49    // Logger
50
private final Logger log;
51
52    public Kernel()
53    {
54       registry = new HashMap JavaDoc();
55       listeners = new HashSet JavaDoc();
56       createMethod = new CreateMethod(this);
57       startMethod = new StartMethod(this);
58       stopMethod = new StopMethod(this);
59       destroyMethod = new DestroyMethod(this);
60       log = Logger.getLogger(getClass());
61    }
62
63    public void addListener(KernelEventListener listener)
64    {
65       synchronized(listeners)
66       {
67          if (!listeners.contains(listener))
68          {
69             Set JavaDoc tmp = new HashSet JavaDoc(listeners);
70             tmp.add(listener);
71             listeners = tmp;
72          }
73       }
74    }
75
76    public void removeListener(KernelEventListener listener)
77    {
78       synchronized(listeners)
79       {
80          if (!listeners.contains(listener))
81          {
82             Set JavaDoc tmp = new HashSet JavaDoc(listeners);
83             tmp.remove(listener);
84             listeners = tmp;
85          }
86       }
87    }
88
89    void fireEvent(KernelEvent event)
90    {
91       // We use an iterator so we will keep always the same listeners instance object.
92
for (Iterator JavaDoc i = listeners.iterator(); i.hasNext();)
93       {
94          try
95          {
96             KernelEventListener listener = (KernelEventListener)i.next();
97             listener.handleEvent(event);
98          }
99          catch (Throwable JavaDoc ignored)
100          {
101          }
102       }
103    }
104
105    public synchronized State getState(ServiceID id)
106    {
107       Entry entry = getEntry(id);
108       if (entry != null)
109       {
110          return entry.getState();
111       }
112       else
113       {
114          return null;
115       }
116    }
117
118    public synchronized Service getService(ServiceID id)
119    {
120       Entry entry = getEntry(id);
121       if (entry == null)
122       {
123          return null;
124       }
125       Implementation implementation = entry.implementation;
126       if (implementation == null)
127       {
128          return null;
129       }
130       return implementation.getService();
131    }
132
133    public synchronized void register(ServiceID id, Service service) throws IllegalArgumentException JavaDoc, ServiceAlreadyRegisteredException, ServiceRegistrationException
134    {
135       register(id, service, Collections.EMPTY_SET);
136    }
137
138    public synchronized void register(ServiceID id, Service service, ServiceID[] depends) throws IllegalArgumentException JavaDoc, ServiceAlreadyRegisteredException, ServiceRegistrationException
139    {
140       register(id, service, new HashSet JavaDoc(Arrays.asList(depends)));
141    }
142
143    /**
144     *
145     */

146    public synchronized void register(ServiceID id, Service service, Set JavaDoc depends) throws IllegalArgumentException JavaDoc, ServiceAlreadyRegisteredException, ServiceRegistrationException
147    {
148       // Argument check
149
if (id == null)
150       {
151          throw new IllegalArgumentException JavaDoc("id must not be null");
152       }
153       if (service == null)
154       {
155          throw new IllegalArgumentException JavaDoc("service must not be null");
156       }
157       if (depends == null)
158       {
159          throw new IllegalArgumentException JavaDoc("depends must not be null");
160       }
161
162       // Get if it is here
163
Entry entry = (Entry)registry.get(id);
164
165       // It's been here before check it's unregistered state
166
if (entry != null)
167       {
168          try
169          {
170             entry.machine.register(true);
171          }
172          catch (TransitionNotPossibleException e)
173          {
174             throw new ServiceAlreadyRegisteredException(id);
175          }
176       }
177       else
178       {
179          entry = new Entry(this, id);
180       }
181
182       try
183       {
184          // API callback
185
if (service instanceof Registration)
186          {
187             ((Registration)service).registered(entry);
188          }
189
190          // Create missing entry and dependencies
191
for (Iterator JavaDoc i = depends.iterator(); i.hasNext();)
192          {
193             ServiceID dependOnID = (ServiceID)i.next();
194             Entry dependOnEntry = (Entry)registry.get(dependOnID);
195             if (dependOnEntry == null)
196             {
197                dependOnEntry = new Entry(this, dependOnID);
198                registry.put(dependOnID, dependOnEntry);
199             }
200             dependOnEntry.dependsOnMe.add(id);
201             entry.depends.add(dependOnID);
202          }
203
204          // Create implementation
205
entry.implementation = new Implementation(entry, service);
206
207          // Transition
208
entry.machine.register(false);
209
210          // Put in registry, it may be already there, but it does not matter
211
registry.put(id, entry);
212       }
213       catch (Throwable JavaDoc t)
214       {
215          // Unexpected exception
216
throw new ServiceRegistrationException(t);
217       }
218
219       // For all of those I depend on
220
for (Iterator JavaDoc i = entry.depends.iterator();i.hasNext();)
221       {
222          Entry IDependOnEntry = (Entry)registry.get((ServiceID)i.next());
223          if (IDependOnEntry.getState() != State.UNREGISTERED && IDependOnEntry.implementation.service instanceof Registration)
224          {
225             // todo : catch runtime ex
226
((Registration)IDependOnEntry.implementation.service).addDependsOnMe(entry.implementation);
227             ((Registration)entry.implementation.service).addIDependOn(IDependOnEntry.implementation);
228          }
229       }
230
231       // For all those that depend on me
232
for (Iterator JavaDoc i = entry.dependsOnMe.iterator();i.hasNext();)
233       {
234          Entry dependsOnMeEntry = (Entry)registry.get((ServiceID)i.next());
235          Implementation dependsOnMeImplementation = dependsOnMeEntry.implementation;
236          if (dependsOnMeEntry.getState() != State.UNREGISTERED && dependsOnMeImplementation.service instanceof Registration)
237          {
238             // todo : catch runtime ex
239
((Registration)dependsOnMeImplementation.service).addIDependOn(entry.implementation);
240             ((Registration)entry.implementation.service).addDependsOnMe(dependsOnMeImplementation);
241          }
242       }
243
244       // Fire registration event
245
RegistrationEvent event = new RegistrationEvent(this, RegistrationEvent.REGISTERED, entry.implementation);
246       fireEvent(event);
247    }
248
249    /**
250     * 1 fire event
251     * 2 break relationship
252     * 3
253     */

254    public synchronized void unregister(ServiceID id) throws IllegalArgumentException JavaDoc, UnknownServiceException, ServiceUnregistrationException, TransitionNotPossibleException
255    {
256       // Get a valid wrapper
257
Entry entry = getValidWrapper(id);
258
259       // Test we can unregister
260
entry.machine.unregister(true);
261
262       // Fire unregistration event
263
RegistrationEvent event = new RegistrationEvent(this, RegistrationEvent.UNREGISTERED, entry.implementation);
264       fireEvent(event);
265
266       // For all of those I depend on
267
for (Iterator JavaDoc i = entry.depends.iterator();i.hasNext();)
268       {
269          Entry IDependOnEntry = (Entry)registry.get((ServiceID)i.next());
270          if (IDependOnEntry.getState() != State.UNREGISTERED && IDependOnEntry.implementation.service instanceof Registration)
271          {
272             // todo : catch runtime ex
273
((Registration)entry.implementation.service).removeIDependOn(IDependOnEntry.implementation);
274             ((Registration)IDependOnEntry.implementation.service).removeDependsOnMe(entry.implementation);
275          }
276       }
277
278       // For all those that depend on me
279
for (Iterator JavaDoc i = entry.dependsOnMe.iterator();i.hasNext();)
280       {
281          Entry dependsOnMeEntry = (Entry)registry.get((ServiceID)i.next());
282          Implementation dependsOnMeImplementation = dependsOnMeEntry.implementation;
283          if (dependsOnMeEntry.getState() != State.UNREGISTERED && dependsOnMeImplementation.service instanceof Registration)
284          {
285             // todo : catch runtime ex
286
((Registration)dependsOnMeImplementation.service).removeIDependOn(entry.implementation);
287             ((Registration)entry.implementation.service).removeDependsOnMe(dependsOnMeImplementation);
288          }
289       }
290
291       // Remove dependencies and unused entries
292
for (Iterator JavaDoc i = entry.depends.iterator();i.hasNext();)
293       {
294          ServiceID dependOnID = (ServiceID)i.next();
295          i.remove();
296          Entry dependOnEntry = (Entry)registry.get(dependOnID);
297          dependOnEntry.dependsOnMe.remove(id);
298          if (dependOnEntry.dependsOnMe.isEmpty() && dependOnEntry.getState() == State.UNREGISTERED)
299          {
300             registry.remove(dependOnID);
301          }
302       }
303
304       // Change state
305
entry.machine.unregister(false);
306
307       // Save reference
308
Implementation implementation = entry.implementation;
309
310       // Check for references, if no references then remove from the registry
311
if (entry.dependsOnMe.isEmpty())
312       {
313          // We are not references anymore remove from registry
314
registry.remove(id);
315       }
316       else
317       {
318          // We are referenced keep the entry
319
entry.implementation = null;
320       }
321
322       try
323       {
324          // API callback
325
if (implementation.service instanceof Registration)
326          {
327             ((Registration)implementation.service).unregister();
328          }
329       }
330       catch (Throwable JavaDoc t)
331       {
332          throw new ServiceUnregistrationException(t);
333       }
334    }
335
336    public synchronized State create(ServiceID id) throws UnknownServiceException, ServiceFailureException
337    {
338       try
339       {
340          Entry entry = getValidWrapper(id);
341          if (entry.getState() == State.UNREGISTERED)
342          {
343             return State.UNREGISTERED;
344          }
345          else if (entry.getState() == State.REGISTERED || entry.getState() == State.FAILED)
346          {
347             return createMethod.invoke(entry);
348          }
349          else if (entry.getState() == State.STOPPED)
350          {
351             return State.STOPPED;
352          }
353          else
354          {
355             return State.STARTED;
356          }
357       }
358       catch (TransitionNotPossibleException e)
359       {
360          throw new IllegalStateException JavaDoc("This should not be possible");
361       }
362    }
363
364    public synchronized State start(ServiceID id) throws UnknownServiceException, ServiceFailureException
365    {
366       try
367       {
368          Entry entry = getValidWrapper(id);
369          if (entry.getState() == State.UNREGISTERED)
370          {
371             return State.UNREGISTERED;
372          }
373          else if (entry.getState() == State.REGISTERED || entry.getState() == State.FAILED)
374          {
375             State state = createMethod.invoke(entry);
376             if (state != State.STOPPED)
377             {
378                return state;
379             }
380             else
381             {
382                return startMethod.invoke(entry);
383             }
384          }
385          else if (entry.getState() == State.STOPPED)
386          {
387             return startMethod.invoke(entry);
388          }
389          else
390          {
391             return State.STARTED;
392          }
393       }
394       catch (TransitionNotPossibleException e)
395       {
396          throw new IllegalStateException JavaDoc("This should not be possible");
397       }
398    }
399
400    public synchronized State stop(ServiceID id) throws UnknownServiceException, ServiceFailureException
401    {
402       try
403       {
404          Entry entry = getValidWrapper(id);
405          if (entry.getState() == State.UNREGISTERED)
406          {
407             return State.UNREGISTERED;
408          }
409          else if (entry.getState() == State.REGISTERED)
410          {
411             return State.REGISTERED;
412          }
413          else if (entry.getState() == State.STOPPED)
414          {
415             return State.STOPPED;
416          }
417          else if (entry.getState() == State.FAILED)
418          {
419             return State.FAILED;
420          }
421          else
422          {
423             return stopMethod.invoke(entry);
424          }
425       }
426       catch (TransitionNotPossibleException e)
427       {
428          throw new IllegalStateException JavaDoc("This should not be possible");
429       }
430    }
431
432    public synchronized State destroy(ServiceID id) throws UnknownServiceException, ServiceFailureException
433    {
434       try
435       {
436          Entry entry = getValidWrapper(id);
437          if (entry.getState() == State.UNREGISTERED)
438          {
439             return State.UNREGISTERED;
440          }
441          else if (entry.getState() == State.REGISTERED)
442          {
443             return State.REGISTERED;
444          }
445          else if (entry.getState() == State.STOPPED)
446          {
447             return destroyMethod.invoke(entry);
448          }
449          else if (entry.getState() == State.FAILED)
450          {
451             return State.FAILED;
452          }
453          else
454          {
455             State state = stopMethod.invoke(entry);
456             if (state != State.STOPPED)
457             {
458                return state;
459             }
460             else
461             {
462                return destroyMethod.invoke(entry);
463             }
464          }
465       }
466       catch (TransitionNotPossibleException e)
467       {
468          throw new IllegalStateException JavaDoc("This should not be possible");
469       }
470    }
471
472    /**
473     * Returns a valid wrapper for this ID.
474     */

475    private Entry getValidWrapper(ServiceID id) throws IllegalArgumentException JavaDoc, UnknownServiceException
476    {
477       // Check against null arg
478
if (id == null)
479       {
480          throw new IllegalArgumentException JavaDoc("id must not be null");
481       }
482
483       // Get the wrapper
484
Entry entry = (Entry)registry.get(id);
485
486       // Ensure we have a wrapper
487
if (entry == null)
488       {
489          throw new UnknownServiceException("Unknown service " + id);
490       }
491
492       return entry;
493    }
494
495    Entry getEntry(ServiceID id)
496    {
497       return (Entry)registry.get(id);
498    }
499 }
500
Popular Tags